jqGrid, couldn't get showlink formatter working - javascript

Hi I am trying to get showlink formatter working by following this document from trirand.
What I want to achieve is a hyperlink I can click for a edit view to update/edit records. But for some reason, the column are empty where I want show a hyperlink.
Here is my code snippets, and link is the last column:
<script type="text/javascript">
$(document).ready(function () {
$("#grid_products").jqGrid({
jsonReader: {
repeatitems: false,
id: 'Guid'
},
url: '/Product/jqgridJSON/',
datatype: 'json',
mtype: 'GET',
colNames: ['ProductCode', 'ProductDescription', 'DefaultSellPrice', 'LastCost', 'Edit'],
colModel: [
{ name: 'ProductCode', index: 'Productcode' },
{ name: 'ProductDescription', index: 'ProductDescription' },
{ name: 'DefaultSellPrice', formatter: 'currency', index: 'DefaultSellPrice' },
{ name: 'LastCost', formatter: 'currency', index: 'LastCost' },
{ name: 'MyLink',
edittype: 'select',
formatter: 'showlink',
formatoptions: { baseLinkUrl: '/Product/Update/', idName: 'Guid' }
},
],
pager: '#pager',
rowNum: 10,
rowList: [20, 50, 100, 200],
sortname: 'ProductCode',
sortorder: 'asc',
viewrecords: true,
width: 'auto',
height: 'auto',
caption: 'Products'
}).navGrid('#pager', { edit: true, add: false, del: false });
});
</script>
#{
ViewBag.Title = "JSONGrid";
}
<h2>JSONGrid</h2>
<table id="grid_products"></table>
<div id="pager"></div>
The formatter from jqGrid is working for currency, but for some reason, it just didn't shown for hyperlink.
Update:
Got it working by using custom formatter.
...
{ name: 'MyLink',
formatter: myLinkFormatter,
},
...
function myLinkFormatter (cellvalue, options, rowObjcet) {
return 'Edit this product';
}

I suppose that you fill no value in JSON input for the 'MyLink' column. Because of this the hyperlink is empty. If you want to place the link with any fixed text in column I would recommend you to use custom formatter. See the recent answer for an example.
One more possible solution way is to use formatter: 'showlink' and include jsonmap: function() { return "Edit"; } to the 'MyLink' column definition. In the case you will not need to include in the JSON data "MyLink":"Edit" for every row of data. It's important to understand that the trick works only in case of usage jsonReader: {repeatitems: false} (so it should work for your grid).
If you have another problem you should include in the text of your question the JSON data which you use.
Some small remarks to your current code:
the usage of edittype: 'select' together with formatter: 'showlink' has no sense. You should remove it if you will do use formatter: 'showlink'.
the parameter height: 'atuo' should be height: 'auto'.
pager: $('#pager') is better to replace to pager: '#pager'. If you use pager: $('#pager'), the jqGrid will replace it internally to pager: '#pager' and the object $('#pager') will be discarded.
If you use jsonReader: { id: 'Guid'} and you don't plan to show the guids to the user you can remove the 'Guid' column from the grid. The id (the Guid in your case) will be used to assign ids of <tr> elements (table rows) of the grid. So you don't need to hold the same information twice

Related

Why won't data output to jqGrid without the use of "hiddengrid: true"?

I want this:
Without having to start like this:
But for some reason the data only shows up when I use "hiddengrid: true,"
I tried following this demo and was only able to get the example to work by adding "hiddengrid: true," like so:
<body>
<div class="center" id="overGrid">
<table id="jqGrid"></table>
<div id="jqGridPager"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#jqGrid").jqGrid({
url: 'api/codes',
editurl: 'api/codes',
colModel: [
{
label: "Edit Actions",
name: "actions",
width: 75,
formatter: "actions",
formatoptions: {
keys: true,
editOptions: {},
addOptions: {},
delOptions: {}
}
},
{
label: 'Id',
name: 'id',
width: 150,
editable: true
},
{
label: 'Title',
name: 'title',
width: 100,
editable: true
},
{
label: 'Code',
name: 'code',
width: 100,
editable: true
},
{
label: 'Original Url',
name: 'originalUrl',
width: 200,
editable: true
}
],
align: 'center',
viewrecords: true,
rowList: [10, 20, 30],
width: 925,
height: 445,
rowNum: 20,
loadonce: true,
hiddengrid: true, // <-------------------- HERE
toppager: '#jqGridPager',
pager: '#jqGridPager',
caption: "Database"
}); jQuery("#jqGrid")
.navGrid('#pager', { edit: false, add: false, del: false, search: false })
.navButtonAdd('#pager', {
caption: "Add",
buttonicon: "ui-icon-add",
onClickButton: function () {
alert("Adding Row");
},
position: "last"
})
.navButtonAdd('#pager', {
caption: "Del",
buttonicon: "ui-icon-del",
onClickButton: function () {
alert("Deleting Row");
},
position: "last"
});
function fetchGridData() {
var gridArrayData = [];
// show loading message
$("#jqGrid")[0].grid.beginReq();
$.ajax({
url: 'api/codes',
mtype: 'POST',
datatype: 'JSON',
success: function (result) {
for (var i = 0; i < result.items.length; i++) {
var item = result.items[i];
gridArrayData.push({
id: item.id,
title: item.title,
code: item.code,
originalUrl: item.originalUrl,
});
}
// set the new data
$("#jqGrid").jqGrid('setGridParam', { data: gridArrayData });
// hide the show message
$("#jqGrid")[0].grid.endReq();
// refresh the grid
$("#jqGrid").trigger('reloadGrid');
}
});
}
fetchGridData();
});
</script>
</body>
Examples such as this don't seem to be working for me on their own so I keep having to reference other sources such as this that are much more complex and informative but possibly the reason for why I continue to have issues every step of the way.
Side Note
I should probably point out that I was only just recently introduced to jqGrid as a result of this question I asked about a week ago: " How can I separate my output using “onclick” and format the data to 20 per page?
"
I did a fairly decent job of documenting the steps that brought me to this point so it might be worth checking out for an in depth look as to what I am dealing with.
In short I am building an API in Asp.Net Core that sends and receives JSON data to my MongoDb database and then outputs the data to a single HTML page using jqGrid. So far I have created functioning Get, Post, Put, and Delete methods that return and send JSON data to my MongoDb database.
Update:
I have gone through the docs suggested by Tony Tomov and I understand their meaning. I just haven't the slightest clue to the solution to this problem. Everything I have thought to be a possible solution and tried from before and after I posted this question has given me a blank page without any errors.

Free jqGrid, don't send new index on addrow with inlineNav

Just putting in a new grid, and everything seems to be working well, except for one thing. Using basic inline, it is sending a new incorrect key value for the column I have set with key: true. This is an auto-increment column in the database, so I just don't want to send any data for this column when ADDING, only for edit or delete is that required.
It is posting a parameter: row_id => jqg3 for the new key column and messing up my server script. So because adding the new row will auto-increment the row_id col, I don't need to send this.
How do I stop the jqGrid from sending this (row_id) index column value when saving a new added row?
free-jqgrid version is 4.14.0
$('#accts').jqGrid({
url:'/phpAJAX/Master/master_grid_v1.php',
editurl:'/phpAJAX/Master/master_grid_v1.php',
height: 'auto',
shrinkToFit: false,
width: 'auto',
datatype: 'xml',
mtype: 'POST',
postData:{
'arg1':'bol_acct'
},
colNames:[
'row_id',
'Customer',
'Trucker',
'Acct Num'
],
colModel:[
{name: 'row_id', hidden: true, key: true},
{name:'Customer', align: "center", editable: true},
{name: 'Trucker', align: "center"},
{name: 'Acct_Num', align: "center"}
],
sortname: 'Customer',
sortorder: 'desc',
viewrecords: true,
gridview: true,
caption: 'Bill of Lading Accounts',
rowNum: 10000,
pager:true
}).jqGrid('inlineNav', {
addParams: {
addRowParams: { extraparam: {'arg1':'bol_acct', 'oper':'add'} }
},
editParams: {
extraparam: {
'arg1':'bol_acct', 'oper':'edit'
}
}
})
One can use serializeSaveData callback of inline editing to modify the data, which will be send during inline editing. You can add serializeSaveData callback via
inlineEditing: {
keys: true,
extraparam: { arg1: "bol_acct" },
serializeSaveData: function (postData) {
var newPostData = $.extend(true, {}, postData);
if (newPostData.oper === "add") {
delete newPostData.id; // delete id parameter
}
return newPostData;
}
}

jqGrid - how to delete row from local data?

I am really new to the jqGrid. I'm loading local file (I'm parsing csv file into json and then transfer the array to jqGrid). Table generated through jqGrid should allow user to modify, add and delete the data in the grid. I tried to resolve my problem using various answers from here like:
Adding new row to jqGrid using modal form on client only
There I have found the example made by Oleg for the 4.7 version of jqGrid and reproduced the same code for my purpose. The result was that I am able to delete row which I added after the grid initialisation but I am unable to delete any other row which was loaded from the array.
Another interesting thing is that I am able to modify the rows loaded from array, the only thing I cannot do with the grid is to delete rows loaded from array. I appreciate any advices.
Here is part of the code with jqGrid:
var delSettings = {
onclickSubmit: function () {
var $this = $(this), p = $this.jqGrid("getGridParam"), newPage = p.page;
if (p.lastpage > 1) {// on the multipage grid reload the grid
if (p.reccount === 1 && newPage === p.lastpage) {
// if after deliting there are no rows on the current page
// which is the last page of the grid
newPage--; // go to the previous page
}
// reload grid to make the row from the next page visable.
setTimeout(function () {
$this.trigger("reloadGrid", [{page: newPage}]);
}, 50);
}
return true;
}
};
$("#jqGrid").jqGrid({
datatype: "local",
data: results.data,
editurl: "clientArray",
colModel: [
{
label: 'Id',
name: 'Id',
width: 60,
editable: true,
key: true,
sorttype: 'number'
},
{
label: 'Company',
name: 'Company',
width: 90,
editoptions: {size: 40},
editable: true,
sorttype: 'string'
},
{
label: 'Address',
name: 'Address',
width: 100,
editoptions: {size: 40},
editable: true
},
{
label: 'City',
name: 'City',
width: 80,
editoptions: {size: 40},
editable: true
}
],
height: '100%',
viewrecords: true,
caption: "Baza klientów Klimatest",
pager: "#jqGridPager",
sortable: true,
ignoreCase: true,
cmTemplate: {editable: true, searchoptions: {clearSearch: true }},
rowNum: 5,
rowList: [5, 10, 20],
});
// toolbar searching
$('#jqGrid').jqGrid('filterToolbar', { defaultSearch: 'cn'});
$('#jqGrid').jqGrid('navGrid',"#jqGridPager",
{ edit: true, add: true, del: true, search: true, refresh: true, view: true},
// options for the Edit Dialog
{
editCaption: "The Edit Dialog",
recreateForm: true,
closeAfterEdit: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Add Dialog
{
closeAfterAdd: true,
recreateForm: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Delete Dialog
delSettings,
// options for the Search Dialog
{
},
// options for the View Dialog
{
});
// add first custom button
$('#jqGrid').navButtonAdd('#jqGridPager',
{
buttonicon: "ui-icon-calculator",
title: "Column chooser",
caption: "Columns",
position: "last",
onClickButton: function() {
// call the column chooser method
jQuery("#jqGrid").jqGrid('columnChooser');
}
});
EDIT
Data source is the result of parsed CSV file via Papaparse.js plugin (array of objects), which looks like this:
Id: "100,1"
Address: "Strefowa 8"
Company: "DSSE Sp. z o.o."
City: "Warsaw"
I edited the code just like Oleg suggested and I'm still able to delete only records which are added via interface of jqGrid.
I don't know if it may help, but when I click delete icon and confirm that I want to delete selected row, that row is no longer highlighted, but still visible. Thanks for feedback.
You have clear error in your code near // options for the View Dialog block. The View option should be included after delete and search options (see the documentation). So your current code don't use delSettings options.
I recommend you additionally to include test data in your next questions, because some problems exist only with some specific format of input data.
UPDATED: The problem is in the data which you use. The value for Id which you use contains comma ("100,1"). It's not allowed for jqGrid. First of all id in HTML should not use characters which have special meaning in CSS. The second problem: delGridRow method uses commas in separator to delete multiple rows at once. So the usage of id="100,1" will follows to attempt to delete tow rows: one row with id=100 and the second one with the id=1. By the way I'm developing now jqGrid in my fork of GitHub. I fixed many restrictions with the usage of special characters in ids. So you will be do able to use id="100,1" and successfully delete the rows if you would use jqGrid from my fork.
I recommend you to use underscore if you need to construct id which consist from multiple numbers: Id: "100_1" instead of Id: "100,1".

jqGrid wrong data format?

Im trying to put some data into jqGrid and force it to be displayed in a treeview.
My problem is, the 6th item (cid=6) is not showing in the grid. The 4th item looks like it has some subitems, but expanding this branch shows nothing. The 6th item is nowhere to find in the tree (I suppose, I've defined it as subitem of cid4).
Here is a working example of this code http://jsfiddle.net/498jhxcg/
(my production code uses POST/AJAX/JSON, the example is changed to localdata. Grid is displayed in the same wrong way in both cases.)
Is the data in wrong format, or the jqgrid is wrong defined? (btw. changing parent_id to parentid did not helped.)
var myjsondata = '{"rows":[
{"cid":"1","name":"cat1","lvl":"0","parent_id":"null","isleaf":true,"expanded":false,"loaded":true},
{"cid":"2","name":"cat2","lvl":"0","parent_id":"null","isleaf":false,"expanded":false,"loaded":true},
{"cid":"3","name":"cat3","lvl":"1","parent_id":"2","isleaf":true,"expanded":false,"loaded":true},
{"cid":"7","name":"cat7","lvl":"1","parent_id":"2","isleaf":true,"expanded":false,"loaded":true},
{"cid":"4","name":"cat4","lvl":"0","parent_id":"null","isleaf":false,"expanded":false,"loaded":true},
{"cid":"6","name":"cat6","lvl":"1","parent_id":"4","isleaf":true,"expanded":false,"loaded":true},
{"cid":"5","name":"cat5","lvl":"0","parent_id":"null","isleaf":true,"expanded":false,"loaded":true}
],"records":7,"total":1}';
$('#jgtable').jqGrid({
ExpandColumn:'id',
datastr: myjsondata,
datatype: 'jsonstring',
colNames: [
'Id',
'Name',
'Parent id',
'isLeaf?',
],
colModel: [
{ index: 'cid', name: 'cid', width:"75px"},
{ index: 'name', name: 'name', width:"75px"},
{ index: 'parent_id', name: 'parent_id',width:"75px"},
{ index: 'isleaf', name: 'isleaf', width:"75px"},
],
pager: '#pager',
rowNum: 10,
rowList:[2, 10, 25, 50, ],
height: 'auto',
minHeight: '250px',
recordpos: 'right',
viewrecords: true,
gridview: false,
treeGrid: true,
treeGridModel : 'adjacency',
treedatatype: "local",
treeReader : {
level_field: "lvl",
parent_id_field: "parent_id",
leaf_field: "isleaf",
expanded_field: "expanded",
loaded_field: "loaded",
index_field: "cid",
},
jsonReader: {
repeatitems: false,
},
});
It seems to me that you should add key: true property to the definition of cid column. You can use alternatively (or to do both things) the option jsonReader: { id: "cid" }. In the case the value of cid property of input data will be interpreted as the id of the item and the value from parent_id will be correct.
see http://jsfiddle.net/OlegKi/498jhxcg/19/

How to make only the clicked cell editable instead of all the editable cells in the row clicked - using jqgrid?

At present I'm getting all the cells (with editable:true) in the row editable in which i clicked and not only the clicked the cell. The table is similar to the table in this link: http://www.ok-soft-gmbh.com/jqGrid/ClientsideEditing4.htm. I've gone through the link: http://www.trirand.com/jqgridwiki/doku.php?id=wiki:cell_editing, but didn't help (may be due to my fault in the way i tried) and also tried the answers given in stackoverflow related questions (used the attributes: cellEdit: true, cellsubmit: "clientArray").
Please help me using the above link as reference http://www.ok-soft-gmbh.com/jqGrid/ClientsideEditing4.htm (I think mainly the "onSelectRow", "ondblClickRow" functions need to be updated. i tried onSelectCell etc. but failed! ).
Thanks in advance.
If you need to use cell editing you have to include cellEdit: true in jqGrid definition. If you use local datatype then you should use cellsubmit: "clientArray" additionally. If you want to save data on the remote source you have to implement editing in your server code and specify cellurl option of jqGrid. The documentation describes what jqGrid send to the server on saving of cell.
I'm currently working on an Angular 2 app with Typescript, and I had a different need where I wanted to be able to click a row in the grid, but only have one cell editable. I didn't like the user experience where the user had to click the actual cell to edit it. Instead, clicking the row highlights the row and then makes the one cell editable. Here's a screenshot:
The trick was that I needed to set cellEdit to false on the grid and then set the individual column editable to true when declaring my column model array, and write a change event for the editoptions of the column. I also had to write code for the the onSelectRow event of the grid, to keep track of the current row selected and to restore the previous row selected. A snippet of the Typescript code is below:
private generateGrid() {
let colNames = ['id', 'Name', 'Total', 'Assigned', 'Distributed', 'Remaining', 'Total', 'Assigned', 'Remaining', 'Expiration'];
let self = this;
// declare variable to hold Id of last row selected in the grid
let lastRowId;
let colModel = [
{ name: 'id', key: true, hidden: true },
{ name: 'name' },
{ name: 'purchasedTotalCount', width: 35, align: 'center' },
{ name: 'purchasedAssignedCount', width: 35, align: 'center' },
{ name: 'purchasedDistributedCount', width: 35, align: 'center' },
{ name: 'purchasedRemainingCount', width: 35, align: 'center' },
// receivedTotalCount is the only editable cell;
// the custom change event works in conjunction with the onSelectRow event
// to get row editing to work, but only for this one cell as being editable;
// also note that cellEdit is set to false on the entire grid, otherwise it would
// require that the individual cell is selected in order to edit it, and not just
// anywhere on the row, which is the better user experience
{ name: 'receivedTotalCount',
width: 35,
align: 'center',
editable: true,
edittype: 'text',
editoptions: {
dataEvents: [
{
type: 'change', fn: function(e) {
//TODO: don't allow decimal numbers, or just round down
let count = parseInt(this.value);
if (isNaN(count) || count < 0 || count > 1000) {
alert('Value must be a whole number between 0 and 1000.');
} else {
self.updateLicenses(parseInt(lastRowId), count);
}
}
},
]
}
},
{ name: 'receivedAssignedCount', width: 35, align: 'center' },
{ name: 'receivedRemainingCount', width: 35, align: 'center' },
{ name: 'expirationDate', width: 45, align: 'center', formatter: 'date' }
];
jQuery('#licenseManagerGrid').jqGrid({
data: this.childTenants,
datatype: 'local',
colNames: colNames,
colModel: colModel,
altRows: true,
rowNum: 25,
rowList: [25, 50, 100],
width: 1200,
height: '100%',
viewrecords: true,
emptyrecords: '',
ignoreCase: true,
cellEdit: false, // must be false in order for row select with cell edit to work properly
cellsubmit: 'clientArray',
cellurl: 'clientArray',
editurl: 'clientArray',
pager: '#licenseManagerGridPager',
jsonReader: {
id: 'id',
repeatitems: false
},
// make the selected row editable and restore the previously-selected row back to what it was
onSelectRow: function(rowid, status) {
if (lastRowId === undefined) {
lastRowId = rowid;
}
else {
jQuery('#licenseManagerGrid').restoreRow(lastRowId);
lastRowId = rowid;
}
jQuery('#licenseManagerGrid').editRow(rowid, false);
},
});
}
Additionally, I wanted the escape key to allow the user to abort changes to the cell and then restore the cell to its previous state. This was accomplished with the following Angular 2 code in Typescript:
#Component({
selector: 'license-manager',
template: template,
styles: [style],
host: {
'(document:keydown)': 'handleKeyboardEvents($event)'
}
})
// handle keypress so a row can be restored if user presses Escape
private handleKeyboardEvents(event: KeyboardEvent) {
if (event.keyCode === 27) {
let selRow = jQuery('#licenseManagerGrid').jqGrid('getGridParam', 'selrow');
if (selRow) {
jQuery('#licenseManagerGrid').restoreRow(selRow);
}
}
}

Categories