Skip to content Skip to sidebar Skip to footer

How Do I Capture Only Those Columns In Multiple Rows In Which User Has Changed Values?

Are there are any approaches in ASP.NET or JavaScript where i run update stored procedure on only those rows in which specific columns have been updated by user? For example: if th

Solution 1:

There is a very convoluted way to achieve this. If anyone knows of a cleaner way, please post it.

You need to do the following:

Add to your Model: - a Boolean property (column) that will be hidden and used as a change Identifier

Set up your table in your view like this (my example is in Razor):

@{
int j = 1;
for (var i = 0; i < Model.itemList.Count; i++)
{
     <tr>
          <td>
               @Html.TextBoxFor(model => model.itemList[i].columnOne, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
          </td>
          <td>
               @Html.TextBoxFor(model => model.itemList[i].columnTwo, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
          </td>
          <td>
               @Html.TextBoxFor(model => model.itemList[i].columnThree, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
          </td>
          <td>
               @Html.TextBoxFor(model => model.itemList[i].columnFour, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
          </td>
          <td>
               @Html.TextBoxFor(model => model.itemList[i].columnFive, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
          </td>
          <td>
               @Html.HiddenFor(model => model.itemList[i].IsChanged)
          </td>
     </tr>
     j++;
}

Your JavaScript function will edit the hidden element as soon as someone changes a field for a row:

functionrerunOldChange(rowIndex, changeIndex) {
    var table = document.getElementById("changeTable");
    var j = rowIndex;
    var i = changeIndex;

    var currentRow = table.rows[j];
    var cellSix = currentRow.cells[5];

    var thisRowIsChanged = "<input type = 'hidden' id = 'itemList_" + i + "__IsChanged' name = 'itemList[" + i + "].IsChanged' value = 'true' />"

    cellSix.innerHTML = thisRowIsChanged;
}

What it is doing is changing the value of the boolean as soon as someone presses a key on that field. So when you pass the list to your controller in order to post, you can do so only for rows that have a boolean value of True.

Solution 2:

I'll tack on some updates and simplification to @C Murphy's response, but setting a hidden field in your viewmodel is the best option. I would recommend using a checkbox, as it is boolean by default and easy to manipulate with its checked attribute.

The keypress event is deprecated, and doesn't fire on all keys - in particular, the Backspace and Delete keys do not trigger it, so someone could delete everything in a field and no update would occur. Instead, use the keydown event; this has sort of the opposite effect, as every key triggers it, including Shift and other keys that may not actually change the field. You can validate changes in other code if you want to.

I removed the code checking for changes per column, because I assume your update logic asks for all the object's data, or with EF probably expects an entire object to be passed.

Razor:

// A text field, change PropertyName and add where needed in markup
@Html.TextBoxFor(model => model.itemList[i].PropertyName, new { onkeydown = "markAsChanged(" + i + ")" })

// Hidden checkbox for the IsChanged property
@Html.CheckBoxFor(model => model.itemList[i].PropertyName, new { hidden = "" })

The Javascript:

// Modern browsersvar markAsChanged = function(i) {
    document.GetElementById('itemList_' + i + '__IsChanged').checked = true;
};

// Use for legacy support with jQueryvar markAsChanged = function(i) {
    $('#itemList_' + i + '__IsChanged').checked = true;
};

If you wanted to clean up your view and leave out the event handlers, you could add them with some more Javascript.

Post a Comment for "How Do I Capture Only Those Columns In Multiple Rows In Which User Has Changed Values?"