Related
Hi I have a Grid that is using cell edit and Inline editing. It saves to the ClientArray
$('#list').jqGrid({
datatype: "local",
colNames: ["Parameter Id", "Parameter Name", 'Parameter Value'],
colModel: [
{ name: "Id", index: "Id", align: "left", key: true, editable: false,hidden:true, jmap: 0 },
{ name: "ParameterName", index: "ParameterName", align: "left", editable: false, jmap: 1 },
{ name: "ParameterValue", index: "ParameterValue", align: "left", editable: true, edittype: "text", editoptions: { maxlength: 100 }, editrules: {required: true }, jmap: 2 }
],
pager: "#pager",
rowNum: 100,
rowList: [],
pgbuttons: false, // disable page control like next, back button
pgtext: null, // disable pager text like 'Page 0 of 10'
viewrecords: true, // disable current view record text like 'View 1-10 of 100'
height: '100%',
scrollOffset: 0,
sortname: "Name",
sortorder: "Asc",
gridview: true,
caption: 'Parameters',
autowidth: true,
hidegrid: false,
loadonce: true,
//beforeEditCell: function () {
// $("#list_ilsave").removeClass('ui-state-disabled');
// return;
//},
//afterEditCell: function (rowid, cellname, value, iRow, iCol) {
// $('#list').jqGrid('getCell', rowid, iCol).focus();
// return;
//},
width: totalWidth,
cellEdit: true,
cellsubmit: "clientArray"
});
$('#list').jqGrid('inlineNav', '#pager', {
edit: false,
add: false,
del: false,
save: true,
savetext: 'Save',
cancel: false
});
When I edit a Cell the save button remains disabled. If I manually Enable the button in beforeCellEdit, the editable cell hasn't got focus until you select another cell. This behavior is only happening in IE.
I have tried to fix both these issues individually in my commented out code, and I have found that the loss of focus is caused by the line
$("#list_ilsave").removeClass('ui-state-disabled');
I tried placing this line in beforeEditCell and in afterEditCell and it causes the input field to loose focus.
I was using JQ Grid 4.4.4 and I have tried updating to 4.6.0 after I read there were updates to Inline Editing after 4.4.4
UPDATE
I have changed my grid to use onSelectRow
onSelectRow: function (rowid) {
var $grid = $('#list');
var iRow = $("#" + rowid)[0].rowIndex;
$grid.jqGrid('editRow', rowid, {
keys: true,
oneditfunc: function(rowid, response) {
var $saveButton = $("#list_ilsave");
if ($saveButton.hasClass('ui-state-disabled')) {
$saveButton.removeClass('ui-state-disabled');
}
markCellAsDirty(rowid, $grid);
return true;
},
successfunc: function() {
alert('success');
return true;
},
aftersavefunc: function() {
alert('after save');
return true;
},
errorfunc: function() {
alert('error');
return true;
}
});
},
cellsubmit: "clientArray"
But I can't get any of the editRow events to fire other than oneditfunc. I also have an issue with getting the changed cells.
This method marks the cells as dirty / edited
function markCellAsDirty(rowid, grid) {
$(grid.jqGrid("setCell", rowid, "ParameterValue", "", "dirty-cell"));
$(grid[0].rows.namedItem(rowid)).addClass("edited");
}
I try to get the edited cells as follows
var editedRows = $grid.getChangedCells('dirty');
Before posting editedRows in an AJAX method to my server.
I'm not sure what you want to implement exactly, but I modified your demo to the following https://jsfiddle.net/OlegKi/byygepy3/11/. I include the full JavaScript code of the demo below
$(function () {
var myData = [
{ id: 10, ParameterName: "Test", ParameterValue: "" },
{ id: 20, ParameterName: "Test 1", ParameterValue: "" },
{ id: 30, ParameterName: "Test 2", ParameterValue: "" }
],
$grid = $("#list");
// change the text displayed on editrules: {required: true }
$.extend(true, $.jgrid.locales["en-US"].edit.msg, {
required: "No value was entered for this parameter!!!"
});
$grid.jqGrid({
datatype: "local",
data: myData,
colNames: ["", "Parameter Name", "Parameter Value"],
colModel: [
{ name: "act", template: "actions" }, // optional feature
{ name: "ParameterName" },
{ name: "ParameterValue", editable: true,
editoptions: { maxlength: 100 }, editrules: {required: true } }
],
cmTemplate: { autoResizable: true },
autoResizing: { compact: true },
pager: true,
pgbuttons: false, // disable page control like next, back button
pgtext: null, // disable pager text like 'Page 0 of 10'
viewrecords: true, // disable current view record text like 'View 1-10 of 100'
sortname: "Name",
iconSet: "fontAwesome",
caption: 'Parameters',
autowidth: true,
hidegrid: false,
inlineEditing: {
keys: true
},
singleSelectClickMode: "selectonly", // prevent unselect once selected rows
beforeSelectRow: function (rowid) {
var $self = $(this), i,
// savedRows array is not empty if some row is in inline editing mode
savedRows = $self.jqGrid("getGridParam", "savedRow");
for (i = 0; i < savedRows.length; i++) {
if (savedRows[i].id !== rowid) {
// save currently editing row
// one can replace saveRow to restoreRow in the next line
$self.jqGrid("saveRow", savedRows[i].id);
}
}
return savedRows.length === 0; // allow selection if saving successful
},
onSelectRow: function (rowid) {
$(this).jqGrid("editRow", rowid);
},
afterSetRow: function (options) {
var item = $(this).jqGrid("getLocalRow", options.rowid);
if (item != null) {
item.dirty = true;
}
},
navOptions: {
edit: false,
add: false,
search: false,
deltext: "Delete",
refreshtext: "Refresh"
},
inlineNavOptions: {
save: true,
savetext: "Save",
cancel: false,
restoreAfterSelect: false
},
formDeleting: {
// delete options
url: window.g_baseUrl + 'MfgTransactions_MVC/COA/Delete?',
beforeSubmit: function () {
// get value
var selRowId = $(this).jqGrid('getGridParam', 'selrow');
var parametricValue = $(this).jqGrid('getCell', selRowId, 'ParameterValue');
// check if empty
if (parametricValue === "") {
return [false, "Cannot delete: No value exists for this parameter"];
}
return [true, "Successfully deleted"];
},
delData: {
batchId: function () {
return $("#BatchId").val();
}
},
closeOnEscape: true,
closeAfterDelete: true,
width: 400,
msg: "Are you sure you want to delete the Parameter?",
afterComplete: function (response) {
if (response.responseText) {
alert("response.responseText");
}
//loadBatchListIntoGrid();
}
}
}).jqGrid('navGrid')
.jqGrid('inlineNav')
.jqGrid('navButtonAdd', {
caption: "Save Changed",
buttonicon: "fa-floppy-o",
onClickButton: function () {
var localData = $(this).jqGrid("getGridParam", "data"),
dirtyData = $.grep(localData, function (item) {
return item.dirty;
});
alert(dirtyData.length > 0 ? JSON.stringify(dirtyData) : "no dirty data");
}
});
// make more place for navigator buttons be rwducing the width of the right part
var pagerIdSelector = $grid.jqGrid("getGridParam", "pager");
$(pagerIdSelector + "_right").width(100);
// make the grid responsive
$(window).bind("resize", function () {
$grid.jqGrid("setGridWidth", $grid.closest(".container-fluid").width());
}).triggerHandler("resize");
});
where HTML code is
<div class="container-fluid">
<div class="row">
<div id="gridarea" class="col-md-6 col-md-offset-3">
<table id="list"></table>
</div>
</div>
</div>
and CSS code
.ui-th-column>div, .ui-jqgrid-btable .jqgrow>td {
word-wrap: break-word; /* IE 5.5+ and CSS3 */
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
overflow: hidden;
vertical-align: middle;
}
It demonstrate how one can implement starting inline editing on select row. Additionally I added optional column with template: "actions" which can be alternative implementation. I set property dirty in every item of data inside of afterSetRow callback and I added "Save Changed" button, which uses localData = $(this).jqGrid("getGridParam", "data") and dirtyData = $.grep(localData, function (item) { return item.dirty; }); to get the dirty (modified) data.
Hi everybody and happy new year :)
So, I use dataTables library. In their web site i found this example, where function must return the row of table, which was clicked.
var table = $('#example').DataTable();
$('#example tbody').on( 'click', 'tr', function () {
console.log( table.row( this ).data() );
} );
I try use this example for my code, but i have the error
Uncaught TypeError: aucTable.row is not a function
my code:
var mainTable = $('#mainTable');
$(document).ready(function () {
mainTable.dataTable({
'searching': false,
'ajax': 'assets/static_data/data.json',
'columns': [
{
title: "Name",
data: "name"
},
{
title: "Office",
data: "office"
},
{
title: "Extn.",
data: "extn"
},
{
title: "Salary",
data: "salary"
},
{
title: "Start date",
data: "start_date"
},
{
title: "Details",
data: null,
defaultContent: "<button class='details-btn btn'>More details</button>",
sorting: false
}
]
});
});
$('#mainTable').on('click', '.details-btn', function () {
var selectedRow = aucTable.row(this).data();
console.log(selectedRow);
$("<div id='details-dialog'/>").dialog({
modal: true,
show: true,
maxWidth: 620,
maxHeight: 300,
minWidth: 500,
minHeight: 200,
title: "Hello World"
});
});
Can somebody tell me, why I have this error? And why i can't get the row, which was clicked?
Tanks for everybody.
Best regard and have fun.
I'm not familiar with datatables, however you might try changing it to the following:
var mainTable = null;
$(document).ready(function () {
mainTable = $('#mainTable').dataTable({...});
});
$('#mainTable').on('click', '.details-btn', function () {
var tr = $(this).closest('tr');
var selectedRow = mainTable.row(tr).data();
console.log(selectedRow);
//...
});
Note that I'm storing the result to the $('#mainTable').dataTable() call in the mainTable variable so that you can reference it later when calling the row() function.
The other thing to note is that in your click handler, it looks like you need to find the tr from the datatable - calling mainTable.row(this) does not yield a row because this is the button that was clicked, not the row of the table.
See this link for an example that seems similar to what you're doing.
In the current code, the acuTable var not exist. So you can change your code in order to have an acuTable var pointing to the datatable instance, something like:
var mainTable = $('#mainTable');
var acuTable;
$(document).ready(function () {
acuTable = mainTable.dataTable({
'searching': false,
'ajax': 'assets/static_data/data.json',
'columns': [
{
title: "Name",
data: "name"
},
{
title: "Office",
data: "office"
},
{
title: "Extn.",
data: "extn"
},
{
title: "Salary",
data: "salary"
},
{
title: "Start date",
data: "start_date"
},
{
title: "Details",
data: null,
defaultContent: "<button class='details-btn btn'>More details</button>",
sorting: false
}
]
});
});
$('#mainTable').on('click', '.details-btn', function () {
var selectedRow = aucTable.row(this).data();
console.log(selectedRow);
$("<div id='details-dialog'/>").dialog({
modal: true,
show: true,
maxWidth: 620,
maxHeight: 300,
minWidth: 500,
minHeight: 200,
title: "Hello World"
});
});
I have used below code to simulate fixed header with vertical and horizontal scroll bars. See example on jsFiddle.
$('#liveTable').dataTable({
'bSort': false,
'destroy': true,
'aoColumns': [
{ sWidth: "85px", bSearchable: false, bSortable: false },
{ sWidth: "75px", bSearchable: false, bSortable: false },
{ sWidth: "80px", bSearchable: false, bSortable: false },
{ sWidth: "80px", bSearchable: false, bSortable: false },
{ sWidth: "85px", bSearchable: false, bSortable: false },
{ sWidth: "70px", bSearchable: false, bSortable: false },
{ sWidth: "70px", bSearchable: false, bSortable: false },
{ sWidth: "50px", bSearchable: false, bSortable: false }
],
'scrollY': 200,
'scrollX': true,
'info': false,
'paging': false
});
The above code is working fine in Desktop.
But in mobile devices when I scroll body of the content header part not moving accordingly. There is some delay (flickering effect) in header movement in mobile devices.
How to fix that header movement issue in mobile devices?
Try this if it works for you. It's the other way around, but it works. Maybe you'll just need to adjust width or whatsoever. Run it through jsFiddle to test it.
$.event.special.scrollstart = {
enabled: true,
setup: function() {
var thisObject = this,
$this = $( thisObject ),
scrolling,
timer;
function trigger( event, state ) {
scrolling = state;
var originalType = event.type;
event.type = scrolling ? "scrollstart" : "scrollstop";
$.event.handle.call( thisObject, event );
event.type = originalType;
}
$this.bind( scrollEvent, function( event ) {
if ( !$.event.special.scrollstart.enabled ) {
return;
}
if ( !scrolling ) {
trigger( event, true );
}
clearTimeout( timer );
timer = setTimeout(function() {
trigger( event, false );
}, 50 );
});
}
};
Ok, if the flickering effect exists, try something like this. Your scroll is ok. It's the effect that sucks.
document.getElementById("btn").addEventListener("click", function(){
var abc = document.getElementById("abc");
var def = document.getElementById("def");
abc.style["-webkit-transition-duration"] = "0ms";
def.style["-webkit-transition-duration"] = "0ms";
abc.style["-webkit-transform"] = "translate3d(0, 0, 0)";
def.style["-webkit-transform"] = "translate3d(100%, 0, 0)";
setTimeout(function(){
abc.style["-webkit-transition-duration"] = "1s";
def.style["-webkit-transition-duration"] = "1s";
abc.style["-webkit-transform"] = "translate3d(-100%, 0, 0)";
def.style["-webkit-transform"] = "translate3d(0, 0, 0)";
},
);
});
I was tried to use these approaches:
Using api().draw(false) function, but it resets scroll offset.
Using api().ajax.reload(null, false). It resets scroll offset too.
Using dataTable._fnDraw() function. It doesn't work too. There is a bug when you are trying a bit scroll and after _fnDraw() call it scrolls to previous position. When you are scrolling a lot - it works well.
My TypeScript code:
var dataTableOptions = {
serverSide: true,
ordering: true,
searching: true,
columns: [
{ "data": "id" },
{ "data": "workflowId" },
{ "data": "discovery" },
{ "data": "title" },
{ "data": "createdBy" },
{ "data": "createDate" },
{ "data": "status" }
],
ajax: (data, callback, settings) => {
// server side service call
},
dom: 'rtiS',
scrollY: 400,
scroller: {
rowHeight: 35,
loadingIndicator: true
},
initComplete: function () {
forceRefresh = _.throttle(() => {
//this.api().ajax.reload(false);
this._fnDraw();
}, 1000);
setInterval(() => {
forceRefresh();
}, 5000);
}
}
I didn't find any other way as get scrollTop of scroller before ajax call and after table refresh (api().ajax.reload) assign it again. It's works for me.
Datatable automatically refresh (with updated data) on server side operation, no need to force refresh.
$(document).ready(function() {
var dataTableOptions = {
serverSide: true,
ordering: true,
searching: true,
columns: [
{ "data": "id" },
{ "data": "workflowId" },
{ "data": "discovery" },
{ "data": "title" },
{ "data": "createdBy" },
{ "data": "createDate" },
{ "data": "status" }
],
ajax: (data, callback, settings) => {
// server side service call
},
dom: "frtiS",
scrollY: 400,
deferRender: true,
scroller: {
rowHeight: 35,
loadingIndicator: true
}
}
A live example can be found here
I'm sure there are a few (better) ways to do this, but I can't get any way to work. I'm trying to have datatables load new data (from different data source) when a button is clicked.
Here's what I have:
$(document).ready(function() {
$('#datatable2').dataTable( {
"ajax": {
"url":"simple4.php",
"type":"GET"
} ,
"paging": true,
"pageLength": 20,
"order": [[ 2, "asc" ]],
"aoColumns": [
{ "bSortable": false, "width": "25%" },
{ "bSortable": true, "width": "30%" },
{ "bSortable": true, "width": "15%" },
{ "bSortable": true, "width": "15%" },
{ "bSortable": true, "width": "15%" },
{ "bSortable": false, "width": "0%", "visible":false },
],
});
$( "#option2" ).click(function() {
table.ajax.url( 'simple3.php' ).load();
});
});
The initial table (from simple4.php) loads fine. I'd like it to change when I click on a button (with id=option2 in this case), but nothing happens when I click the button.
Just in case, here's the button code in case I'm missing something obvious:
<label class="btn btn-default">
<input type="radio" name="options" id="option2" value="1" autocomplete="off"> Compare 1 and 2
</label>
Not sure what the issue is. Any insight would be helpful.
UPDATE: see answers below explanation of the issue. One thing I didn't do, which apparently makes a major difference is using "dataTable" versus "DataTable". You need a capital D and capital T. Here's the fixed code that's working now:
$(document).ready(function() {
var table = $("#datatable2").DataTable({
"ajax": {
"url":"simple3.php",
"type":"GET"
} ,
"paging": true,
"pageLength": 20,
"order": [[ 2, "asc" ]],
"aoColumns": [
{ "bSortable": false, "width": "25%" },
{ "bSortable": true, "width": "30%" },
{ "bSortable": true, "width": "15%" },
{ "bSortable": true, "width": "15%" },
{ "bSortable": true, "width": "15%" },
{ "bSortable": false, "width": "0%", "visible":false },
],
});
$( "#option2" ).click(function() {
table.ajax.url( "simple4.php" ).load();
});
});
One more thing...my function that was supposed to fire when I clicked on my radio button wasn't working. Had to change from this:
$( "#option2" ).click(function() {
table.ajax.url( "simple4.php" ).load();
});
To this:
$('input[id=option2]').change(function(){
table.ajax.url( "simple4.php" ).load();
});
First, as the others have said the variable 'table' is not set.
Second, when you call
var table = $('#datatable2').dataTable({.....})
You are returning a jQuery object that won't have access to any of the DataTables API
To get a DataTables API instance you need to make a call like this:
var table = $('#datatable2').DataTable({....});
This should work, assuming that your data returned by your url is properly formed.
Source: https://datatables.net/faqs/#api
I can't try this now, but I think it gonna work:
var table = $('#datatable2').dataTable({...});
$( "#option2" ).click(function() {
table.ajax.url( 'simple3.php' ).load();
});
you are not setting var table = ... so when you call table.ajax... table var does not exists