Reputation: 33
The code I have is below using a simple DataTable . I get the data and all sorting is great but now I want to update the cell contents in last column only which is the "reason not covered" column and submit it back as update to DB possibly by AJAX calls . I am not sure whether to use Editor or JEditable to make the table editable and how to make it editable for that column alone . Have tried different options using makeEditable and Editor but cannot make the inline cell contents editable for column or cell .Have dataTables.editor.min.js in the script path. Also tried jEditable with jquery.jeditable.mini.js Any help deeply appreciated.
jquery-3.1.1.min.js, jquery.dataTables.min.js, dataTables.buttons.min.js, buttons.colVis.min.js, dataTables.editor.min.js
<script>
$(document).ready(function() {
$('#selectedDetails').DataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"fixedHeader": true,
"scrollY": '400px'
});
} );</script>
<table id = "selectedDetails" class="table table-striped table-bordered" cellspacing="0" width="80%">
<caption><h3>DETAILS FOR SELECTED FILTERS: <font color="brown">FORM ID</font>=<font color="blue"><%=request.getAttribute("formNameSelection")%></font> AND <font color="brown">COVERED IN AUTOTAX</font> = <font color="blue"><%=request.getAttribute("YesOrNoValueSelection") %></font> </h3></caption>
<thead style="background-color:#D7DBDD; border:solid 2px; border-color:black">
<tr>
<th>FORM ID</th>
<th>FIELD ID</th>
<th>FIELD NAME</th>
<th>FIELD TYPE</th>
<th>NO: OF HARD CALCS</th>
<th>NO: OF DROP ASSIGNEDS</th>
<th>COVERED IN AUTOTAX ?</th>
<th>REASON NOT COVERED</th>
</tr>
<thead>
</thead>
<tbody>
<c:forEach var="filterFieldInfo" items="${filteredValues}">
<tr>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.formId}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.fieldId}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.fieldName}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.fieldType}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.numHardCalcs}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.numDroptAssigneds}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.autoTaxCovered}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.reasonAutoTaxCovered}" /></td>
</tr>
</c:forEach>
</tbody>
</table>
Upvotes: 0
Views: 11625
Reputation: 15642
contentEditable anyone?
Says it's new for HTML5, and also a "Global HTML" attribute.
Seems to work pretty well on table cells.
Upvotes: 0
Reputation: 3735
I made one more. This one, the html is created server side. Also, it uses a pop over to allow the user to enter in the changes that way.
Like I said, I do not have access to the DataTable Editor library so I used the QTip2 (http://qtip2.com/) library instead.
Click on any cell in the office column.
http://jsbin.com/datecoy/edit?js,output
// Table defintion
$(document).ready(function () {
var dtTable = $('#example').DataTable({
columns: [{ title: "Name" }, { title: "Postition" }, { title: 'Office' }, { title: "Age" }, { title: "Start Date" }, { title: "Salary" }],
columnDefs: [{ targets: [2], className: "editColumn" }]
});
$('#example').on("click", ".editColumn", function () {
var index = $(this).index();
var cols = dtTable.settings()[0].aoColumns;
var colTitle = cols[index].title;
var data = dtTable.rows($(this).closest("tr")).data()[0];
DataTableDialog(this, colTitle, data[2]);
})
});
Upvotes: 1
Reputation: 33
THanks a bunch again ! I have modified code with your example to try make it work to see what I am missing , below is the modified script and html . In your example I just needed the Edit and Save button , no functionality needed for Add and Delete. Below still doesn't work , I dont actually see even an edit button . What are the parameters inside the function function (e, dt, bt, config) signify ?
<script>
$(document).ready(function() {
var myTable = $('#selectedDetails').DataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"fixedHeader": true,
"scrollY": '400px',
buttons: [{
text: "Edit", className :"editButton",
extend: "selectedSingle",
action: function (e, dt, bt, config) { editRow(e, dt, bt, config); }
}, {
text: "Save",
extend: "selectedSingle",
action: function (e, dt, bt, config) { saveRow(e, dt, bt, config); }
}
}],
dom: "Btp",
select: "single"
});
var dataObject = myTable.rows().data();
// keep the rows from deselection when you click on a textbox
// this means you have to click between textboxes to change edit rows when more than one is open
$("#selectedDetails").on("click", "input", function (e) { e.stopPropagation(); return false; });
table.on('user-select', function (e, dt, type, cell, originalEvent) {
if ($('#selectedDetails input').length > 0) {
e.preventDefault();
return false;
}
});
});
// Save the selected row (assuming its in edit mode)
function saveRow(e, dt, bt, config) {
var r = dt.rows(".selected").nodes()[0];
// if row is not edit mode, just return.
if ($("input", r).length === 0) { return; }
var d = dt.rows(".selected").data()[0];
var containsText = false;
$(r).children("td").each(function (i, it) {
var di = $("input", it).val();
if (di.length > 0) { containsText = true; }
$(it).html(di);
d[i] = di;
});
if (!containsText) {
alert("This row contains no data and will be removed");
dt.rows(".selected").remove().draw();
}
$(".editButton span").text("Edit");
}
// Puts a row in edit mode
function editRow(e, dt, bt, config) {
var r = dt.rows(".selected").nodes()[0];
if( $("span", bt[0]).text() == "Cancel"){
if($(r).hasClass("newRow")){
dt.rows(".selected").remove().draw();
}
else {
$(r).children("td").each(function (i, it) {
var od = dt.cells(it).data();
$(it).html(od[0]);
});
}
$("span", bt[0]).text("Edit");
return;
}
// if row already in edit mode, just return.
if ($("input", r).length > 0) { return; }
$(r).children("td").each(function (i, it) {
var h = $("<input type='text'>");
h.val(it.innerText);
$(it).html(h);
});
$("span", bt[0]).text("Cancel");
}
</script>
<table id = "selectedDetails" class="table table-striped table-bordered" cellspacing="0" width="80%">
<caption><h3>DETAILS FOR SELECTED FILTERS: <font color="brown">FORM ID</font>=<font color="blue"><%=request.getAttribute("formNameSelection")%></font> AND <font color="brown">COVERED IN AUTOTAX</font> = <font color="blue"><%=request.getAttribute("YesOrNoValueSelection") %></font> </h3></caption>
<thead style="background-color:#D7DBDD; border:solid 2px; border-color:black">
<tr>
<th>FORM ID</th>
<th>FIELD ID</th>
<th>FIELD NAME</th>
<th>FIELD TYPE</th>
<th>NO: OF HARD CALCS</th>
<th>NO: OF DROP ASSIGNEDS</th>
<th>COVERED IN AUTOTAX ?</th>
<th>REASON NOT COVERED</th>
</tr>
<thead>
</thead>
<tbody>
<c:forEach var="filterFieldInfo" items="${filteredValues}">
<tr>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.formId}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.fieldId}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.fieldName}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.fieldType}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.numHardCalcs}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.numDroptAssigneds}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.autoTaxCovered}" /></td>
<td style="width: 45px;text-align: center;" align="center"><c:out value="${filterFieldInfo.reasonAutoTaxCovered}" /></td>
</tr>
</c:forEach>
</tbody>
</table>
Upvotes: 0
Reputation: 3735
Here is something for you to look at.
All of my tables are made from an array data objects in JavaScript. Yours, I think, was made from an html table generated server side.
So, to closer emulate what you are doing I created a table server side and then tried to use my code to update it. It did not work. Below is what I had to do update it.
Basically, the code below uses an event handler that pops up an input box for the user to make the change and then save it. (I left all of that out)
// For my object array, this was all I had to do to update the data.
var dtTable = $($(target).closest("table")).DataTable();
var dtData = dtTable.rows($(target).closest("tr")).data()[0];
dtData.office = $(this).siblings("input").val();
dtTable.rows().invalidate().draw();
When I changed it to a server side table, the code above stopped working (even after changing it to work with array of arrays which server side tables use)
To get it to work, I had to update both the data object and the tables html node so it looked like this:
var columnIndex = $(target).index();
var dtTable = $($(target).closest("table")).DataTable();
var dtData = dtTable.rows($(target).closest("tr")).data()[0];
// here, I updated the data node
dtData[columnIndex] = $(this).siblings("input").val();
// then I updated the html td. Once that was done, it started working for the server side table.
$(target).html(dtData[columnIndex]);
dtTable.rows().invalidate().draw();
Upvotes: 0
Reputation: 3735
this one is a tad safer and more obvious. it puts in a textbox.
Also, I had to add a bit more to make the excel dump work.
http://jsbin.com/zufesop/3/edit?html,js,output
$(document).ready(function() {
// add editable column data
var dtData = $.map(dataStore.data, function(item){item.contentEdit = ""; return item;});
var dtTable = $('#example').DataTable( {
"data": dtData,
"select":"single",
"columnDefs":[{"targets":[6], render : function(ditem){return "<input type='text' value = '" + ditem +"'/>" ;}}],
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" },
{"data":"contentEdit", "className": ""}
],
dom: 'Bfrtip',
buttons: [
{
extend: 'excelHtml5',
text: 'Save as Excel',
// updates the data before being sent to excel
customizeData: function (a, b, c, d) {
var exd = a.body;
var dtdata = $('#example').DataTable().rows().data();
for (var ii = 0; ii < dtdata.length ; ++ii) {
var cur = dtdata[ii].contentEdit;
exd[ii][6] = cur;
}
}
}
]
});
// Uses key press event handler to keep the associated data object in sync
$("#example").on("keyup", "input[type='text']", function (){
var rData = dtTable.rows($(this).closest("tr")).data()[0];
rData.contentEdit = $(this).val();
$("#txtFollower").val($(this).val());
});
});
Upvotes: 0
Reputation: 3735
Here is a very simple one but not my first choice. Because it is content editable, you loose control of the width of the column and end up with some strange looking stuff.
Just click on a cell in the edit column and start typing.
event handlers keep the data object and the table cell in sync.
http://jsbin.com/zizepoh/edit?html,js,output
$(document).ready(function() {
// add editable column data
var dtData = $.map(dataStore.data, function(item){item.contentEdit = ""; return item;});
var dtTable = $('#example').DataTable( {
"data": dtData,
"select":"single",
"columnDefs":[{"targets":[6], render : function(ditem){return "<div contenteditable>" + ditem + "</div>";}}],
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" },
{"data":"contentEdit", "className": "contentEdit"}
],
dom: 'Bfrtip',
buttons: [ 'excelHtml5' ]
});
// Uses key press event handler to keep the associated data object in sync
$("#example").on("keypress", ".contentEdit div", function (){
var rData = dtTable.rows($(this).closest("tr")).data()[0];
rData.contentEdit = $(this).text();
$("#txtFollower").val($(this).text());
});
});
Upvotes: 0