How to make datatable specific column editable? - javascript

There are various questions put up on this topic but I do not understand them so can anyone help
here is my js code
$(document).ready(function () {
$('#myModal').toggle();
var List = [];
$.ajax({
url: '/urls/' + id,
type: 'POST',
dataType: "json",
data: 'data',
success: function (data) {
console.log("data length: ", data.length);
console.log("data : ", data);
for (var i = 0; i < data.length; i++) {
var Logs = {};
Logs.Info = data[i].Info;
for (var j = 0; j < Logs.Info.length; j++) {
var emplist = {};
emplist.Name = Logs.Info[j].Name;
emplist.dates = Logs.Info[j].dates;
for (var k = 0; k < emplist.dates.length; k++) {
var datelist = {};
datelist.Name = emplist.Name;
datelist.startDate = emplist.dates[k].startDate;
datelist.endDate = emplist.dates[k].endDate;
List.push(datelist);
}
}
}
emptablee = $('#Table').DataTable({
"data": List,
"columns": [
{"data": "Name"},
{"data": "startDate"},
{"data": "endDate"},
],
destroy: true,
"scrollY": "200px",
"scrollCollapse": true,
"paging": false
});
/*emptablee.destroy();*/
}
});
$("#close").on('click', function () {
$("#myModal").hide();
});
});
There are three columns in the table and I want to make a specific columns cell-like editable and show an input box and get the value edited to send.

For anyone checking this now, I've created a custom example in which you can make any column editable by just sending it in a metadata request from serverside.
here : https://github.com/sinhashubh/datatable-examples

If you want, for example, your startDate column to be editable, you need to init the Datatables like this so you can hit the column by class name:
{"data": "startDate", "className": "editable"},
then, with proper event handling
// Activate an inline edit on click of a table cell
$('#Table').on( 'click', 'tbody td.editable', function (e) {
editor.inline( this );
} );
and initializing Editor you will be good:
editor = new $.fn.dataTable.Editor( {
ajax: "../ajax/handle-data.php", // path to back-end data handling
table: "#Table",
fields: [ {
label: "Start Date:",
name: "startDate"
}
]
} );
Also, don't forget to add this outside of document ready handler because you need it as a global var:
var editor;
Full example here (note that Datatables Editor feature is not free) https://editor.datatables.net/examples/inline-editing/columns.html
You can also code up your own completely free version, which is slightly more complicated, without using Editor, but still using class names so you can trigger on click events for specific columns.

Related

Passing DropdownList value inside grid to the grid itself

I've defined a DropdownList inside a KendoGrid. The DropdownList it's in a column on that Grid and it's showing the fields that come from the datasource correctly but, when I select one of those fields in the dropdown, it isnt passing/updating it's value to the grid itself.
I know that I need to use the change event to pass the value there but am not being able to do that somehow.
Can you help? I'll drop an image with the current code.
Thank you for the help.
if ('#viewMode.ToUpper()' == "EDIT") {
var grid = e.sender;
var items = e.sender.items();
items.each(function (e) {
var dataItem = grid.dataItem(this);
var promtypedropdown = $(this).find('.equipDropDownEditor');
$(promtypedropdown).kendoDropDownList({
dataTextField: "Text",
dataValueField: "Value",
dataSource: {
transport: {
read: {
dataType: "json",
url: '#Url.Action("GetPromoTypesCodeDetail", "Omni")'
}
},
width: 150,
schema: {
data: function (response) {
return response.data.data;
},
}
},
change: function(e){
var uid = $(e.sender.element).closest("tr").attr('data-uid');
var model = $("#omniDataGrid").data("kendoGrid").dataSource.getByUid(uid);
model.PROMOTION_TYPE = this.text();
For the future, I got it working adding the this line of code:
model.set("PROMOTION_TYPE", this.text());

Accessing specific data from csv file and show on html

Having some problems accessing specific data from a csv file. Currently I can see all data in the console but when I try to show a specific data getting undefined. For example in my console I get all data and I want to extract the subtitles and show it on the html in a class score-text.
My console looks like this:
subtitle 1,
name1,65%
name2,65%
name3,65%
name4,65%
total,70%
,
subtitle 2,
name1,65%
name2,65%
name3,65%
name4,65%
total,30%
,
subtitle 3,
name1,65%
name2,65%
name3,65%
name4,65%
total,60%
,
subtitle 4,
name1,65%
name2,65%
name3,65%
name4,65%
total,50%
$.ajax({
url: 'test.csv',
type: "GET",
dataType: "text",
success: function (data) {
var rows = data.split(/\n/);
for (var rowIndex in rows)
{
var columns = rows[rowIndex].split(/,/);
for (var colIndex in columns)
{
var colValue = columns[colIndex].trim();
console.log(colValue);
}
}
$(".score-text").each(function( index, value ) {
value.innerHTML = result[columns[2]] = rows[2];
});
}
});
Why don't you try putting the insertion part into the loop?
var columns = rows[rowIndex].split(/,/);
for (var colIndex in columns)
{
var colValue = columns[colIndex].trim();
console.log(colValue);
$(".score-text").append(colValue);
}

Dynamic Javascript sourced data - DataTable

I am using DataTable in my application. My application is not a server hosted one. (I will render the HTML directly in my standalone application. Well, that is a different story.)
Currently I am populating DataTable like below,
$(dataTableSelector).dataTable({
"sDom": 't <f> <i> <p> > ',
"bRetrieve": true,
"aaSorting": [],
"aaData": rows,
"aoColumns": columns,
"oLanguage": {
"sSearch": "",
"sInfo": "_START_ - _END_ Total: _TOTAL_ ",
"sInfoFiltered": "(filtered from _MAX_)"
}
});
Here rows are my entire data, in array of arrays as a Javascript sourced data.
But now my problem is, if the data I am going to render with DataTable is huge, then loading takes longer time.
So I am trying to change the data table similar to server side processing(but please note that I don't have any server. It is just a local HTML page). On clicking next,it should load next only, page data.Till then, it should not load the same.
Say, I have a function in javascript
function loadData(start,end, searchString){
//Function to fetch records from a Table with start and end numbers of records.
//searchString is optional.
//rows= GetDataFromTable(start,end, searchString);
return rows;
}
So, whenever the next or previous button is clicked in the data table, or searched, my javascript method should be called and it should repopulate Datatable. Any ideas?
You can load from a local variable into Datatables on every user interaction by using the ajax option and providing your own custom function. One example of its use is on their site, called "Pipelining data to reduce Ajax calls for paging".
Below is a simple example of slicing and filtering a large array and returning a small set based on the selections made on the Datatable. Note that Datatables sends more parameters which I haven't used, but you should use them to make a proper implementation. Also, it's possible that Datatables sends request.length = -1, but I have not dealt with that either.
JavaScript
var rows;
$(document).ready(function() {
rows = getLongArrayOfData();
$("#example").dataTable({
"columns": [
{"data": "column1", "title": "Column 1"},
{"data": "column2", "title": "Column 2"}
],
"serverSide": true,
"ajax": getRows()
});
});
function getRows() {
return function ( request, drawCallback, settings ) {
var dataFiltered;
var recordsTotal = rows.length;
if (request.search.value !== "") {
dataFiltered = rows.filter(FilterStartsWith(request.search.value));
}
var recordsFiltered =
(dataFiltered === undefined) ? rows.length : dataFiltered.length;
var dataSliced =
(dataFiltered === undefined ? rows : dataFiltered)
.slice(request.start, request.start + request.length);
var returnData = {
draw: request.draw,
recordsTotal: recordsTotal,
recordsFiltered: recordsFiltered,
data: dataSliced
};
drawCallback(returnData);
};
}
function FilterStartsWith(wordToCompare) {
return function(element) {
if (typeof element == "object") {
returnValue = false;
for (var property in element) {
if (element.hasOwnProperty(property)) {
if (startsWith(element[property], wordToCompare)) {
returnValue = true;
break;
}
}
}
return returnValue;
}
return startsWith(element, wordToCompare);
}
}
function startsWith(element, wordToCompare) {
if (typeof element != "string") element = new String(element);
return element.slice(0, wordToCompare.length) == wordToCompare;
}
function getLongArrayOfData() {
var retArr = new Array();
for(i=1; i<=100000; i++) {
retArr.push({column1: i, column2: "abc" + (500+i)});
}
return retArr;
}
HTML
<table id="example">
<thead>
</thead>
<tbody>
</tbody>
</table>

Refreshing Pagination in DataTables?

I'm having a strange issue that's only arising in my dataTable in select environments. I've written a function that allows the user to delete a row, then if it's the last row on that particular page, reload the Table and send the user to the 'new' last page.
However, on some servers, it's not working properly -- I think it has to do with the fact that with after using fnClearTable and fnDraw, the pagination of the table still holds the last 'empty' page.
Here's the function I'm working with now:
function fnDelete(elem) {
if (selected.length > 0) {
var c;
c = confirm("Are you sure you want to delete the selected Agency?");
if (c) {
var deleteURL = urlstr.substring(0, urlstr.lastIndexOf("/") + 1) + "delete.do";
deleteRecord(deleteURL, selected[0]);
if ($(".tableViewer tbody tr:visible").length === 1) {
oTable.fnClearTable();
oTable.fnDraw();
oTable.fnPageChange("last");
}}}}
In addition, here's my delet function.
function deleteRecord(deleteURL, iid){
var didDelete = false;
jQuery.ajax({
type: "POST",
url: deleteURL,
dataType:"html",
data:"recordID="+iid,
async : false,
success:function(response){
didDelete = true;
oTable.fnDraw(true);
selected = [];
selectedRecord = [];
enableButtons(selected);
},
error:function (xhr, ajaxOptions, thrownError){
<%-- is the message in a range we can handle? --%>
if ((xhr.status >=400) && (xhr.status < 500)) {
alert(xhr.responseText);
}
else {
alert('<spring:message arguments="" text="Internal Server Error" code="ajax.internal.server.error"/>');
}
}
});
return didDelete;
}
Again, this issue is only coming up on certain computers. Can anyone help?
Also, here's the configuration for my DataTable::
oTable = $('#${tableName}_grid').dataTable({
bDestroy: true,
bSort: true,
bFilter: true,
bJQueryUI: true,
bProcessing: true,
bAutoWidth: true,
bInfo: true,
bLengthChange: true,
iDisplayLength: ${sessionScope.displayLength},
sPaginationType: 'full_numbers',
bServerSide: true,
sAjaxSource: "<c:url value='${dataUrl}'/>",
aaSorting: [<c:forEach items="${sortInfo}" var="oneSort"> [${oneSort.columnIndex},'${oneSort.ascending ? "asc":"desc"}']</c:forEach>],
aoColumns: [
<c:forEach items="${columns}" var="curCol" varStatus="colLoop">
{sName: '${curCol.fieldName}', bSortable: ${curCol.sortable}, bSearchable: false, sTitle: "<c:out value='${curCol.title}'/>", sType: '${curCol.displayType}', bVisible:${curCol.visible}, vdbType:'${curCol.vdbType}', sClass:'${curCol.displayType}'}${colLoop.last ? '' : ','}
</c:forEach>
],
aoColumnDefs:[{sClass:"color_col", aTargets:['color']}],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
$('#${tableName}_grid tbody tr').each( function () {
if ($.inArray(aData[0], selected)!=-1) {
$(this).addClass('row_selected');
}
});
return nRow;
},
fnInfoCallback: function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
if(myPos>=iStart && myPos<=iEnd){
//alert(myPos+" visible")
}else{
selected = [];
selected = [];
selectedRecord = [];
$('tr').removeClass('row_selected');
enableButtons(selected);
}
},
fnDrawCallback: function ( oSettings ) {
$('#${tableName}_grid tbody tr').each( function () {
var iPos = myPos = oTable.fnGetPosition( this );
if (iPos!=null) {
var aData = oTable.fnGetData( iPos );
if ($.inArray(aData[0], selected)!=-1) {
$(this).addClass('row_selected');
}
}
var htxt = '';
$(this).find('.color').filter(function(i,tdata){
htxt = '';
htxt = '#'+($(tdata).text());
return true;
}).css("background",htxt);
$(this).dblclick( function(){
var iPos = myPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(iPos);
var iId = aData[0];
selected = [];
selectedRecord = [];
selected.push(iId);
selectedRecord.push(aData);
$('tr').removeClass('row_selected');
$(this).addClass('row_selected');
enableButtons(selected);
<%-- in case there is no edit button or its enablement is more complex,
// click the button instead of assuming it will call fnEdit.
// Do first() because jQuery is returning the same element multiple times.--%>
$(".${tableName}_bttns > span.edit-doubleclick:not(.disabld)").first().click();
});
$(this).click( function () {
var iPos = myPos = oTable.fnGetPosition(this);<%-- row index on_this_page --%>
var aData = oTable.fnGetData(iPos);
var iId = aData[0];
var is_in_array = $.inArray(iId, selected);
<%-- alert("iPos: " + iPos + "\nData: " + aData + "\niId: " + iId + "\nselected: " + selected + "\nis_in_array: " + is_in_array); --%>
selected = [];
selectedRecord = [];
if (is_in_array==-1) {
selected.push(iId);
selected.sort(function(a,b){return a-b});
selectedRecord.push(aData);
selectedRecord.sort(function(a,b){return a[0]-b[0]});
}
else {
selected = $.grep(selected, function(value) {
return value != iId;
});
selectedRecord = $.grep(selectedRecord, function(value) {
return value != aData;
});
}
if ( $(this).hasClass('row_selected') ) {
$(this).removeClass('row_selected');
}
else {
$('#${tableName}_grid tr').removeClass('row_selected');
$(this).addClass('row_selected');
}
enableButtons(selectedRecord);
});
});
} ,
"sDom": '<"H"lTfr>t<"F"ip>',
"oTableTools":{
"aButtons":[ {
"sExtends":"print",
"bShowAll": true,
"sInfo": printmsg,
"sButtonClass":"ui-icon fg-button ui-button edit-print DTTT_button_print",
"sButtonClassHover":"ui-icon fg-button ui-button edit-print DTTT_button_print"
} ] }
});
$('#${tableName}_grid_filter input').attr("maxlength", "255").attr("size", "35");
$('#${tableName}_grid').ready(function(){
$(".DTTT_containerc").remove();
BuildToolBarButtons();
var tt;
$(".DTTT_containerc").each(function(){
tt = $(this).find("#Print").attr("title");
$(this).find("#Print").remove();
$(this).find(".DTTT_container").remove();
}
);
$(".DTTT_container > button").attr("title",tt).css("border","1px solid #9597A3").removeClass("ui-state-default");
$(".DTTT_containerc").append($(".DTTT_container").removeAttr("style"));
});
});
Your datatable is configured to load data using ajax. This means that any action against the data happens asynchronously. Specifically, the fnDraw() function allows control to go to the statement where you change the page page before the new data is back from the server. You should move the logic that takes you to the last page to the fnDrawCallback. I believe that should resolve your issue.
Thought I'd write a response to help others to show how I fixed it.
#Gavin was correct in that it was in the wrong place -- I moved the function in question to the sucess callback in AJAX. However, to fix it fully, I had to 'premptively' read what page the deletion was happening on (using fn.PageChange plugin), subtract 1 (bc DataTables is zero-based) and send the user there.
Hope this helps anyone! #Gavin, thank you for your help and for leading me int he right direction!
you can keep on the same page after the table refreshed. you need to use the following snippet to keep your pagination same after refreshing datatable. just copy paste following js code on a separate file and hook it with your current page.
$.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
if(oSettings.oFeatures.bServerSide === false){
var before = oSettings._iDisplayStart;
oSettings.oApi._fnReDraw(oSettings);
oSettings._iDisplayStart = before;
oSettings.oApi._fnCalculateEnd(oSettings);
}
oSettings.oApi._fnDraw(oSettings);
};
and now, you might be used the "fnDraw" to refresh the dataTable. So now, instead of that code. change it like this.
oTable1.fnStandingRedraw();
Now, your dataTable will keep the same page after refreshing it.

Passing dynamic JSON data to create a HTML table

I have a function that receives JSON data, it can be any length and contain any number of columns and rows of data.
I have read that jqGrid would be a good jQuery plugin to use for this scenario but I cannot get it to work.
I have the following code to try and get my table to be populated:
//This code is in another section of my web page but the data is valid
//and is populated over a websocket
var ss = $.parseJSON(data);
var theGrid = jQuery("#list1")[0];
theGrid.addJSONData(ss.NewDataSet.SECURITY_GROUPS);
//alert(ss.NewDataSet.SECURITY_GROUPS[0].NAME);
$(document).ready(function() {
jQuery("#list1").jqGrid({
datatype: "local",
height: 250,
multiselect: true,
caption: "Manipulating Array Data"
});
});
<table id="list1"></table>
Maybe give DataTables a try if jqGrid isn't working for you. It's probably my favorite, and super easy to load via JSON as you've described.
Here's how to load from an AJAX source: http://datatables.net/release-datatables/examples/data_sources/ajax.html
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": '../ajax/sources/arrays.txt'
});
});
UPDATE
var columnArr = [];
var valueArr = [];
var data = ss.NewDataSet.SECURITY_GROUPS; //data is your SECURITY_GROUPS object
//Strip the titles off your first array item only since they are all the same.
$.each(data[0], function(key, value) {
columnArr.push({"sTitle" : key});
});
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
innerArr.push(innerValue);
});
valueArr.push(innerArr);
});
$('#example').dataTable( {
"aaData": valueArr,
"aoColumns": columnArr
});

Categories

Resources