0

In my SharePoint Hosted app... I have a table with 3 rows (also user can add a new dynamic row) with some input fields.

Currently with my code, system is only reading first row of table and creating a list item out of that.

What I am trying to achieve is: 1. System will read each row of table 2. Each row will create separate line item in SharePoint list.

Below is my code. Kindly suggest

$("#Save").click(function SaveButton(event) {
    var oListItem = "";
    for (var i = 1; i <= $("tbody > tr").length; i++) {
        $("tbody > tr:nth-child(" + i + ")").children();
        var claimId = $("input[class=serialNo]").val();
        expenseType = $("select[name=expenseType]").val();
        var amount = $("input[name=amount]").val();
        var expenseDate = $("input[name=expensedate]").val();
        var description = $("textarea[name=description]").val();
        var submissionDate = $('#subDate').val();
        var Attachment = $("#attchmnt").val();
        claimId = expenseType.slice(0, 4) + employeeID.val();
        if (!((amount && expenseDate && description) === "")) {
            var oList = context.get_web().get_lists().getByTitle('ExpensesTransaction');

            var itemCreateInfo = new SP.ListItemCreationInformation();
            oListItem = oList.addItem(itemCreateInfo);

            oListItem.set_item('Title', expenseType);
            oListItem.set_item('ClaimID', claimId);
            oListItem.set_item('EmployeeName', employeeName.val());
            oListItem.set_item('EmployeeID', employeeID.val());
            oListItem.set_item('EmployeeDepartment', department.val());
            oListItem.set_item('ManagerName', manager.val());
            oListItem.set_item('Amount', amount);
            oListItem.set_item('SubmissionDate', submissionDate);
            oListItem.set_item('ExpenseDate', expenseDate);
            oListItem.set_item('ExpenseDescription', description);
            oListItem.set_item('Attachment', Attachment);
            oListItem.set_item('ClaimStatus', "Pending At Manager");
            oListItem.set_item('ItemID', "item");
            oListItem.update();

            context.load(oListItem);
            context.executeQueryAsync(function onQuerySucceeded() {
                alert('Items Added Successfully ')
            }, function onQueryFailed(sender, args) {
                alert('Request failed. ' + args.get_message())
            });

            event.preventDefault();
        }
        else {
            alert("Please Fill all required Fields!!");
        }
    }
});

Below is my HTML

<table class='table-fill' id="claims">
                    <tr>
                        <th>S. No.</th>
                        <th>Expense type</th>
                        <th>Amount<i style="color: red; font-weight: 600">* 
</i></th>
                        <th>Description<i style="color: red; font-weight: 
600">*</i></th>
                        <th>Expense Date<i style="color: red; font-weight: 
600">*</i></th>
                        <th>Attachment</th>
                    </tr>
                    <tbody>
                        <tr id="tr1">
                            <td id="claimID" class="serialNo">1</td>
                            <td>
                                <select id="expType" name="expenseType">
                                    <option>--Select--</option>
                                </select></td>
                            <td>
                                <input type="text" id="amnt" name="amount" 
/></td>
                            <td>
                                <textarea rows="1" cols="40" id="desc" 
name="description"></textarea></td>
                            <td style="width: 232px;">
                                <input type="date" id="expDate" 
name="expensedate" />
                            </td>

                            <td style="width: 232px;">
                                <input type="file" id="attch" 
name="attachment" /></td>
                        </tr>

                        <tr id="tr2">
                            <td id="claimID 2">2</td>
                            <td>
                                <select id="expType2" name="expenseType">
                                    <option>--Select--</option>
                                </select></td>
                            <td>
                                <input type="text" id="amnt2" name="amount" 
/></td>
                            <td>
                                <textarea rows="1" cols="40" id="desc2" 
name="description"></textarea></td>
                            <td style="width: 232px;">
                                <input type="date" id="expDate2" 
name="expensedate"/>
                            </td>

                            <td style="width: 232px;">
                                <input type="file" id="attch 2" 
name="attachment"/></td>
                        </tr>

                        <tr id="tr3">
                            <td id="claimID 3">3</td>
                            <td>
                                <select id="expType3" name="expenseType">
                                    <option>--Select--</option>
                                </select></td>
                            <td>
                                <input type="text" id="amnt3" 
 name="amount"/></td>
                            <td>
                                <textarea rows="1" cols="40" id="desc3" 
 name="description"></textarea></td>
                            <td style="width: 232px;">
                                <input type="date" id="expDate3" name="expensedate"/>
                            </td>
                            <td style="width: 232px;">
                                <input type="file" id="attch3" name="attachment"/></td>
                        </tr>
                    </tbody>
                </table>
0

As i see, you have two major error in your code:

$("tbody > tr:nth-child(" + i + ")").children();

This is not an assignment, so you dont actually get the n-th tr childrens value later. For that you need to something like this:

var row = $("tbody > tr:nth-child(" + i + ")").children();
var amount = row.find("input[name=amount]").val();

The second one is this line:

if (!((amount && expenseDate && description) === "")) 
{ /*...*/ }

It's pretty confusing and not correct (this condition is always true). You can write this instead:

if (amount && expenseDate && description) 
{ /*...*/ }

Here is the full code with some modifications. Note, that i do not tested it at all. JS:

$('#Save').on('click', onSaveClickHandler);
function onSaveClickHandler(evt) {
    evt.preventDefault();
    var rows = $("#claims").find('tr');
    var successCount = 0;
    var submissionDate = $('#subDate').val();
    for (var i = 0; i < rows.length; i++) {
        //var claimId = rows.find('#claimID' + i).val();
        var expenseType = rows.find('#expType_' + i).val();
        var amount = rows.find('#amnt_' + i).val();
        var expenseDate = rows.find('#expDate_' + i).val();
        var description = rows.find('#desc_' + i).val();
        var attachment = rows.find('#attch_' + i).val();
        claimId = expenseType.slice(0, 4) + employeeID.val();

        if (amount && expenseDate && description) {
            var oList = context.get_web().get_lists().getByTitle('ExpensesTransaction');
            var itemCreateInfo = new SP.ListItemCreationInformation();
            oListItem = oList.addItem(itemCreateInfo);
            oListItem.set_item('Title', expenseType);
            oListItem.set_item('ClaimID', claimId);
            oListItem.set_item('EmployeeName', employeeName.val());
            oListItem.set_item('EmployeeID', employeeID.val());
            oListItem.set_item('EmployeeDepartment', department.val());
            oListItem.set_item('ManagerName', manager.val());
            oListItem.set_item('Amount', amount);
            oListItem.set_item('SubmissionDate', submissionDate);
            oListItem.set_item('ExpenseDate', expenseDate);
            oListItem.set_item('ExpenseDescription', description);
            oListItem.set_item('Attachment', attachment);
            oListItem.set_item('ClaimStatus', "Pending At Manager");
            oListItem.set_item('ItemID', "item");
            oListItem.update();

            context.load(oListItem);
            context.executeQueryAsync(function onQuerySucceeded() {
                successCount++;
                if (successCount == rows.length) {
                    alert('All Items Added Successfully ');
                }
            }, function onQueryFailed(sender, args) {
                alert('Request failed. ' + args.get_message());
            });
        }
        else {
            alert("Please Fill all required Fields!!");
        }
    }
}

HTML:

<table class='table-fill' id="claims">
    <tr>
        <th>S. No.</th>
        <th>Expense type</th>
        <th>Amount
            <i style="color: red; font-weight: 600">*</i>
        </th>
        <th>Description
            <i style="color: red; font-weight: 600">*</i>
        </th>
        <th>Expense Date
            <i style="color: red; font-weight:600">*</i>
        </th>
        <th>Attachment</th>
    </tr>
    <tbody>
        <tr id="tr_0">
            <td id="claimID_0" class="serialNo">1</td>
            <td>
                <select id="expType_0" name="expenseType">
                    <option>--Select--</option>
                </select>
            </td>
            <td>
                <input type="text" id="amnt_0" />
            </td>
            <td>
                <textarea rows="1" cols="40" id="desc"></textarea>
            </td>
            <td style="width: 232px;">
                <input type="date" id="expDate_0" />
            </td>

            <td style="width: 232px;">
                <input type="file" id="attch_0" />
            </td>
        </tr>

        <tr id="tr_1">
            <td id="claimID_1">2</td>
            <td>
                <select id="expType_1" name="expenseType">
                    <option>--Select--</option>
                </select>
            </td>
            <td>
                <input type="text" id="amnt_1" />
            </td>
            <td>
                <textarea rows="1" cols="40" id="desc_1"></textarea>
            </td>
            <td style="width: 232px;">
                <input type="date" id="expDate_1" />
            </td>

            <td style="width: 232px;">
                <input type="file" id="attch_1" />
            </td>
        </tr>

        <tr id="tr_2">
            <td id="claimID 3">3</td>
            <td>
                <select id="expType_2" name="expenseType">
                    <option>--Select--</option>
                </select>
            </td>
            <td>
                <input type="text" id="amnt_2" />
            </td>
            <td>
                <textarea rows="1" cols="40" id="desc_2"></textarea>
            </td>
            <td style="width: 232px;">
                <input type="date" id="expDate_2" />
            </td>
            <td style="width: 232px;">
                <input type="file" id="attch_2" />
            </td>
        </tr>
    </tbody>
</table>
  • Thanks for replying @csonthejjas ... an exception is throwing saying "current is not defined" at var expenseType = current.find('#expType_... – Tezz Chaudhary Jun 19 '18 at 16:45
  • Okss it is working fine,I have added var current = $("#claims").find('tr'); and then working fine...Thanks alott @csonthejjas – Tezz Chaudhary Jun 19 '18 at 17:29
  • Oo, shoot. Sorry, deleted that row, because i realized it was not really necceceryinside the loop, but didnt added it outside. Answer edited to make it work. – csonthejjas Jun 19 '18 at 21:19
  • one more thing i just noticed, that the else branch only show error after the saving already started. So idealy you need to the data validation before the for loop. You can write another function for that, and do something like this: if(isDataValid()){ for (var i = 0; i < rows.length; i++) {/*save logic*/} else { alert("Please Fill all required Fields!!");} – csonthejjas Jun 19 '18 at 21:29
  • one more thing @csonthejjas, as you can see a user can fill up 3 claims, if he has to fill only one claim & then saves his request, then also error prompts! i have something like this for (var i = 0; i < itemCount; i++) { if (document.getElementById(row[i].cells[2].children[0].id).disabled) { return; } else {**save Logic **} else{alert("Please Fill all required Fields!!");} – Tezz Chaudhary Jun 27 '18 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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