1

I have created a Parent List that has a multiple selection checkbox for "Media Type". If a user chooses multiple media types, I want user to add a quantity to each media type selected. I am using SharePoint 2010. I am a novice so I am somewhat limited to SPD, InfoPath and using "simple" code of the brilliant SP developers from internet searches. Assistance is appreciated.

1
  • 1
    I think the key here is probably using Infopath to set some rules and then generate muliple text fields for each checkbox.
    – Matt
    Jan 11, 2013 at 18:48

2 Answers 2

1

The problem is that SharePoint lists work in single rows and don't allow multiple complex sub records for individual items. It's a huge limitation that still exists in 2013 and I can't see anything in the road map that suggests this basic need will be introduced in the next version.

I would advise against InfoPath because it's been deprecated. I would similarly advise against modifying the list form views themselves as this can lead to any number of strange quirks.

You have several client-side options, all of which will require a custom form and use of the JSOM (JavaScript Object Model). You can achieve this using a single list but two would allow you to add a worflow to the Master list that included the media orders created in the second list.

Single list approach (making several assumptions):

  1. In your list include columns for Customer Name (Peron or Group, or Single Line of Text if not in AD), Order Date (Date and Time), Media (Choice->Checkbox) and Quantity (Number).
  2. Create a new view and Group by Customer Name, order by Created.
  3. Create a new page in the same site and name it Orders or whatever is appropriate.
  4. Add a Script Editor web part to the page and either embed or link to (preferred) your code.

Your code would include a form with Customer Name and Order Date, and a table with a row for each Media Types (and Quantity) underneath. Each row in this table will represent a new item (row) in your list.

Use the ClientContext library to lookup the list. Generate the table above by querying the list's Media field and creating a new row for each value. The Quantity field is just a plain input field.

Use jQuery to iterate over the table rows and create an object array for each row that contains a Quantity. You'd also want to validate these fields to ensure a valid numeric value.

Then just create a new list item for each row returned.

Clearly it's outside the scope of this reply to include fully-functional code without actually building the solution. But the example below should hopefully give you a head start.

<!-- Add reference to jQuery-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>

<script type="text/javascript">

// Variables


$(document).ready(function () {
    // Initialise the function after sp.js and ClientContext is ready.
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', GetContextListAndField);
});

// Get context, list and required fields
function GetContextListAndField() {

    var ctx;
    var list;
    var field;

    // Get current context
    ctx = SP.ClientContext.get_current();
    // Get the list
    list = ctx.get_web().get_lists().getByInternalNameOrTitle("Orders")
    ctx.load(list);
    // Get the choice field
    field = list.get_fields().getByInternalNameOrTitle("Media");
    field = ctx.castTo(field, SP.FieldChoice);
    ctx.load(field);

    // Execute query
    ctx.executeQueryAsync(
        Function.createDelegate(this, this.BuildForm),
        Function.createDelegate(this, this.onFailure)
    );

}

function BuildForm(sender, args) {

    var form = $('#myForm');

    var clientName = '<p>Full Name: <input type="text" id="name" /></p>';
    var orderDate = '<p>Order Date: <input type="text" id="date" /></p>';
    var table = $('#myTable');
    var submit = '<p><button id="Submit" type="button">Send Order</button></p>';

    $('#myForm').append(clientName);
    $('#myForm').append(orderDate);

    // Build table only if it doesn't already exist
    if (!table.length) {

        var tableHTML = '<table id="myTable"><tr><th>Media</th><th>Quantity</th></tr></table>';

        // Get arry of possible choices
        var choices = field.get_choices();

        // Populate table
        $.each(choices, function (text) {
            $('#myTable').append('<tr class="mediaRow"><td class="mediaType">' + text + '</td><td class="mediaVal"><input /></td></tr>');
        });

        // Append table to form
        $('#myForm').append(tableHTML)
    }

    $('#myForm').append(submit);

    $('#submit').click(function() {
        createListItems(list);
    });
}

function createListItems(list) {

    var client = $('#myForm #name');
    var date = $('#myForm #date');

    var row = $('tr.mediaRow');
    var count = 0;

    row.each(function() {
        var type = $(this).children('.mediaType').text();
        var quantity = $(this).children('.mediaVal input').text();
        if (quantity !== "") {
            var itemCreateInfo = new SP.ListItemCreationInformation();
            var listItem = list.addItem(itemCreateInfo);
            listItem.set_item(client, date, type, quantity);
            listItem.update();
            count++;
        }
    });

    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded() {

    alert(count + 'items have been added to your order.');
}

function onQueryFailed(sender, args) {

    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}


function onFailure(sender, e) {
    alert('Failed:' + e.get_message() + '\n' + e.get_stackTrace());
}


</script>

<!-- Form placeholder -->
<div id="myForm"></div>
0

Out-of-the-box having such behavior is not offered by any component. You could however opt for:

  1. Change the Edit form into an InfoPath and rely on few Action rules and Formatting rules you could decide to toggle visibility on the "Media-Type" to store data, see here to get started http://allcomputers.us/windows_server/infopath-with-sharepoint-2010---use-the-edit-form-on-the-list-page.aspx and here to Show/Hide fields based on conditions http://office.microsoft.com/en-us/infopath-help/hide-or-disable-a-control-based-on-values-in-a-form-HP001096364.aspx
  2. Customize the EDIT Form to include some JavaScript code to show/hide (see here http://sharepointsherpa.com/2008/08/26/sharepoint-2007-hiding-fields-on-newformaspx-and-editformaspx-the-easy-way/)

In both cases, you should probably create additional columns for each quantity you need to store per record.

2
  • I believe I understand what you are saying. However, I don't see a way with the above suggestions to fulfil my customers needs. Thank you for your quick response.
    – Doo4fun
    Jan 11, 2013 at 21:23
  • you would need to store data in a custom list, which allows edit forms either custom or InfoPath based - the "window" to your data. the shape of the form is up to you to design (more complex would require Web-Part). Either of the 2 options allows for custom interaction (hide/show various form elements - text boxes, etc.). Jan 12, 2013 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.