How Do I Capture Only Those Columns In Multiple Rows In Which User Has Changed Values?
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?"