JQGrid getRowData error - jqgrid

I have the following JQ-Grid with a formatter function which returns some HTML as the column value:
jQuery("#list").jqGrid({
url:jsonUrl,
datatype: 'json',
mtype: 'GET',
colNames:['Id', 'Name', 'Phone', 'Action'],
colModel :[
{name:'id', index:'id', sortable:true},
{name:'name', index:'name', sortable:true},
{name:'phone', index:'phone', sortable:false},
{name:'details', index:'details', sortable: false,
formatter:function(cellvalue,options,rowObject){
return "<p class='trigger'><a href='#'><img src='/images/actions.jpg' /></a></p><div class='toggle_container'><div class='block'><table class='action'><tr><td><a href='#'><img src='/images/open.gif' /></a></td><td><a href='#'><img src='/images/edit.gif' /></a></td><td><a href='#'><img src='/images/delete.gif' /></a></td></tr></table></div></div>"
}
}
]
Later on, I try to get all the column / row data and export it to Excel. Is there a feature in JQ-Grid which allows you to export in Excel / PDF (fyi - I am using JSP/JAVA).
When I try to do something like this:
var mya=new Array();
mya=$("#list").getDataIDs(); // Get All IDs
var data=$("#list").getRowData(mya[0]); // Get First row to get the labels
I get a JavaScript error:
Message: 'l.p.colModel[...].name' is null or not an object
URI: http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.1.2/js/jquery.jqGrid.min.js

I think I may have an answer to your problem - or at least a workaround that will suffice. Take a look at the javascript below. This is the approach I use for ripping the data out of the grid:
var sCell;
var aDataIDs = $Grid.getDataIDs();
//Loop through table rows
for (var i = 0; i < aDataIDs.length; i++) {
try {
//Get row
var oRow = $Grid.getRowData(aDataIDs[i]);
}
catch (e) {
//If problem then fall back to this
for (var j = 0; j < _oJQGUserSettings.aColModel.length; j++) {
if (j > 0) sb.append('\t'); //Add tab
//Get cell data
sCell = $Grid.getCell(aDataIDs[i], _oJQGUserSettings.aColModel[j].name);
sb.append(sCell); //Add data
}
}
If you bear in mind that sb is a javascript stringbuilder class and _oJQGUserSettings.aColModel is just my encapsulation of the ColModel then this should probably give you what you need in terms of extracting the data from the grid as required. (I then copy it to the clipboard which allows me to paste the contents of the grid straight into Excel - handy!)
I suspect there is a bug in getRowData which is thrown when not all columns are displayed to the user. However I haven't isolated this for sure as yet.

Related

Datatable info is lost after i do a flitered search

I'm having a problem with a data table, whenever I use the search function in my table all the data is lost the moment I input anything on the search bar, I create this data table dynamically using AJAX, first I do a request to the server to get the data for my table.
function traerBecas() {
var ciclo = document.getElementById("ciclo").value;
$.ajax({
url: '/becas/listaBecas',
type: 'GET',
data: {
"ciclo": ciclo,
},
dataType: 'JSON',
success:function(response){
llenarTabla(response);
}
});
}
Once I get the response as a JSON I pass the info to another function to build each table row and insert it into the table.
function llenarTabla(jsonArray) {
var tabla = document.getElementById('becaBody');
tabla.innerHTML = "";
jsonArray.forEach(element => {
var trElement = document.createElement('tr');
var tdCLVBECA = document.createElement('td');
var tdINSTIT = document.createElement('td');
var tdCICLO= document.createElement('td');
var tdSECCION = document.createElement('td');
var tdFECINI = document.createElement('td');
var tdFECFIN = document.createElement('td');
var tdACCIONES = document.createElement('td');
var linkEditar = document.createElement('a');
var linkEliminar = document.createElement('a');
tdCLVBECA.innerText = element.CLV_BECA;
tdINSTIT.innerText = element.INSTIT.toUpperCase();
tdCICLO.innerText = element.CICLO;
tdSECCION.innerText = element.SECCION;
tdFECINI.innerText = element.FEC_INI;
tdFECFIN.innerText = element.FEC_FIN;
linkEditar.setAttribute("href","/becas/editar/"+element.CLV_BECA);
linkEditar.setAttribute("data-bs-toggle", "tooltip");
linkEditar.setAttribute("data-bs-placement", "top");
linkEditar.setAttribute("title", "Eliminar");
linkEditar.innerHTML = "<i class='fas fa-pen'></i>";
linkEliminar.setAttribute("onclick", "eliminacion("+element.CLV_BECA+")");
linkEliminar.setAttribute("data-bs-toggle", "tooltip");
linkEliminar.setAttribute("data-bs-placement", "top");
linkEliminar.setAttribute("title", "Editar");
linkEliminar.innerHTML = " <i class='fas fa-trash'></i>";
tdACCIONES.appendChild(linkEditar);
tdACCIONES.appendChild(linkEliminar);
trElement.appendChild(tdCLVBECA);
trElement.appendChild(tdINSTIT);
trElement.appendChild(tdCICLO);
trElement.appendChild(tdSECCION);
trElement.appendChild(tdFECINI);
trElement.appendChild(tdFECFIN);
trElement.appendChild(tdACCIONES);
tabla.appendChild(trElement);
});
}
Then I have the function to transform my table to a data table, and up to this moment, everything works alright. EDIT: Forgot to mention that this info is run first when the page is loaded, the table at the beginning is empty and then is filled with the info I requested.
$(document).ready(function() {
$('#myTable').DataTable({
responsive: true,
language: {
url: '//cdn.datatables.net/plug-ins/1.10.25/i18n/Spanish.json'
}
});
});
Then, once I have my table built, I try to use the search function that it generates, but then I run into the problem that the table doesn't find the info, loses the data, and doesn't return to the previous state once I delete the prompt on the search bar.
I'm at a loss of what to do, I have other data tables that don't have this problem, however, those tables aren't built using AJAX, they get their info directly from the controller with the compact() function in the PHP controller, and using Blade directives like #foreach loops.
You should open up your browser's dev tools and inspect the network request to your endpoint:
url: '/becas/listaBecas'
It could be a number of things, the network tab will show you if there is an error with the AJAX request. If the AJAX request has no error, you will want to look at your endpoint and debug the query that is being run to see why it's not returning any results.
Would also be a good idea to add a error catch for the AJAX call:
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("There was an error with the request");
}

jqgrid formatting based on certain value. spring jqgrid

I am new to the JQGRID, I need to format jqgrid based on certain values, lets say if the "NAME" column contains value of "HEMA" and "RAJU" then their respective row should contain the value of n/a (meaning their gender, mobile, location , country should be n/a). I am stuck as I could not figure out how to approach this problem in jqgrid. Guidance will be highly appreciated. I have attached image for clear explanation.
I did some searching but could not find anything closest I could find was formatter but did not work.
var url = "test/gridresult";
$(function(){
("#result").jqGrid({
url:url,
datatype: "jsonstring",
multiselect:false,
colNames:['Id','NAME', 'GENDER', 'MOBILE','LOCATION','COUNTRY'],
colModel:[
{name:'id',index:'id', resizable:true},
{name:'name',index:'name', resizable:true},
{name:'mobile',index:'mobile', resizable:true},
{name:'country',index:'country', resizable:true},
],
rowNum:100,
pager: '#prowed1',
sortname: 'id',
loadonce: true,
sortorder: "desc",
jsonReader;{
repeatitem:false,
root:"rows",
page:"page",
records:"records",
cell:""
}
});
});
this seems working, I am getting name from loop but how do I set n/a in a row for that particular name
var rows = $("#result").jqGrid('getDataIDs');
for (var i = 0; i < rows.length; i++)
{
var status = $("#resultTable2").getCell(rows[i],"NAME");
alert("initial value "+status);
if(status == "HEMA")
{
//need to set value of n/a for row that belongs to HEMA
}
}
<!-- begin snippet: js hide: false console: true babel: false -->
demo pic for my question
Guys I was able to fix it using formatter. Spent good amount of time and finally got it fixed.
function valFormat( cellvalue, options, rowObject ){
var val;
if(rowObject.name=='HEMA' ){
val='N/A';
}else{
val=cellvalue;
}
return val;
}
and in the jqgrid:
{name:'name',index:'name', resizable:true, formatter:valFormat},

jqgrid frozenColumns + (cell Edit & sortable/reordering of non frozen columns)

Please guide me on a work around for having a set of columns frozen and the rest having cell edit feature along with column reordering/ show- hide options using jqgrid.
Thank You.
Please try this, simple solution,
Hide or remove cellEdit: true
Then add the below lines in above and below the setFrozenColumns
Previous code:
$("#jqGrid2").jqGrid('setFrozenColumns');
New Code:
$("#jqGrid2").jqGrid("setGridParam", {cellEdit: false, sortable: false});
$("#jqGrid2").jqGrid('setFrozenColumns');
$("#jqGrid2").jqGrid("setGridParam", {cellEdit: true, sortable: true});
The problem is that the current implementation of setFrozenColumns have some restrictions. Editing (in any editing mode) and sortable: true is not allowed for frozen columns, but setFrozenColumns. Moreover sortable: true should don't allow to resort headers of frozen columns. On the other side setFrozenColumns contains simple test of some parameters (see here) and the method do nothing if some such parameters (like cellEdit or sortable) are set.
I suggested in the post (with the demo) the way how to implement a workaround. The way is modification of approach from the answer and this one.
I find your question interesting and so I created the demo which demonstrates how one do can implement your requirements. It displays the following results (animated gif):
It uses mostly the following code
// create the grid
$grid.jqGrid({
...
});
$grid.bind("jqGridLoadComplete jqGridInlineEditRow jqGridAfterEditCell jqGridAfterRestoreCell jqGridInlineAfterRestoreRow jqGridAfterSaveCell jqGridInlineAfterSaveRow", function () {
fixPositionsOfFrozenDivs.call(this);
});
$grid.jqGrid("setGridParam", {cellEdit: false, sortable: false});
$grid.jqGrid("setFrozenColumns");
$grid.jqGrid("setGridParam", {cellEdit: true, sortable: true});
fixPositionsOfFrozenDivs.call($grid[0]);
try {
var p = $grid.jqGrid("getGridParam"), tid = $.jgrid.jqID(p.id), colModel = p.colModel, i, n = colModel.length, cm,
skipIds = [];
for (i = 0; i < n; i++) {
cm = colModel[i];
if ($.inArray(cm.name, ["cb", "rn", "subgrid"]) >=0 || cm.frozen) {
skipIds.push("#jqgh_" + tid + "_" + $.jgrid.jqID(cm.name));
}
}
$grid.jqGrid("setGridParam", {sortable: {options: {
items: skipIds.length > 0 ? ">th:not(:has(" + skipIds.join(",") + "),:hidden)" : ">th:not(:hidden)"
}}});
$grid.jqGrid("sortableColumns", $($grid[0].grid.hDiv).find(".ui-jqgrid-labels"));
} catch (e) {}

Select a row in jqGrid based on cell value

colModel: [
{ name: 'Id', index: 'Id', hidden: true, search: false },
{ name: 'Name', index: 'Name', hidden: true, search: false },
]
Just as the setSelection method allows selection of a row in jqGrid based on the row number, is it possible to similarly select a row based on one of the cell values.
For e.g. in the colModel above, is it possible to select a row having a certain 'Id' or 'Name' value...assuming that these values are unique for each row.
In the loadComplete: portion of your jqGrid you could iterate over each row and test for the value you are looking for. If the value is found, select the row.
Ex
loadComplete: function () {
var rowIds = $(this).jqGrid('getDataIDs');
for (i = 1; i <= rowIds.length; i++) {
rowData = $(this).jqGrid('getRowData', i);
if (rowData['Id'] == idSearchValue ) {
$(this).jqGrid('setSelection',i);
} //if
} //for
...
There would also be the rowattr: but I can't seem to find where you can get the rowID of the current row. Oleg might see this and respond as well as it was his addition to jqGrid but I didn't have any luck with my testing or read though of where you would get the current rowId to pass to the setSelection method.
If you have an array of objects containing cells values, you will need another approach.
Eg. with your colModel, you would like to retrieve rows with these values:
let toSearch = [
{ Name: 'Arthur', Id: 150},
{ Name: 'Julien', Id: 90},
]
Then what you can do is to retrieve the whole data from the jqGrid table and seek after values dynamically:
let data = $grid.jqGrid('getGridParam', 'data');
let toSelect = data.filter((row,i) => {
return toSearch.some(toSelectRow => {
for(let prop in prevRow) {
if(prevRow[prop] != row[prop])
return false;
}
return true;
})
});
toSelect.forEach((row) => $grid.jqGrid('setSelection',row.id, false)); // Prevent firing onSelectRow event
Here we pass false to prevent from firing onSelectRow event, if you need it just remove false

jqGrid - edit data

I am quite new to jquery and jqgrid. I use ASP.NET WebForms. I am able to get some data prom server and show it in grid. I use PageMethods to get data from server. Usually my code is
function CreateGrid(){
$("#sestGrid").jqGrid({
datatype: GetData,
//toolbar: [true, "top"],
colNames: ['Name', 'Age'],
colModel: [
{ name: 'Name', index: 'Name', width: 170, align: 'left',
sortable: false, key: true },
{ name: 'Age', index: 'Age', width: 40, align: 'center',
sortable: false, editable: true },
],
ondblClickRow: function () {
var row_id = $("#sestGrid").getGridParam('selrow');
$('#sestGrid').editRow(row_id, true);
}
});
}
function GetData() {
PageMethods.GetSestevalniStevecData(GotData);
}
function GotData (data) {
$("#sestGrid").clearGridData(false);
for (var j = 0; j <= data.length; j++)
$("#sestGrid").jqGrid('addRowData', j + 1, data[j]);
}
So, now I would like to edit some data and post it to server. How can I do that using PageMethods? Should I use any other approach?
And one more thing. I checked the demos http://trirand.com/blog/jqgrid/jqgrid.html and in all edit examples you are able to edit only one row and then you have to save changes… Is it possible to edit more than one row and save all changes in one step?
Thanks all.
jqGrid is designed to be used together with ajax services. So if the user change the data of some row then the changes will be send to the server: to the URL which you configure through jqGrid parameter editurl. So the easiest way to implement row editing will be to include an ASMX web-service or a WCF service in you web site. It is not important whether you use ASP.NET WebForms, ASP.NET MVC or just pure HTML for your pages. So just choose the technology which you prefer and add the corresponding page to your site.
The ASMX or WCF should has a method with the signature like
public string MyDataEdit (string Age, string oper, string id)
(see this old answer for more information). The method should return the id of the new added item (the Name in your case) in case of Add operation.
One more small remark. You can change the definition of the ondblClickRow function from function() to function(row_id) and remove the line used getGridParam('selrow').
I used your example and changed it a bit:
ondblClickRow: function (rowid) {
if (rowid && rowid != lastsel) {
changedRows.push(rowid); //keep row id
jQuery('#jqgrid').editRow(rowid, true);
}
}
Under the save button click event:
$.each(changedRows, function () {
var row = $("#jqgrid").getRowData(this);
var Id = row['ID'];
var price = $(row['Price']).val(); //this is an input type
});
HTH someone :)

Resources