Related
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".
I am going to use JqGrid for many different web pages.
And I have some custom formatter, and custom edittype
for example, I want to use datepicker to edit dates
so, instead of using colModel's edittype as custom, and provide custom functions to do that, I would like "if possible" to write an extension to jqgrid edittype, so I can just write "date", and I will write an extension to replace it with the datepickeer.
As I said, it is for re-usability, so instead of doing custom edit type for every web page/jqgrid, I could do it only once in that place.
Is there any documentation on how to extend jqgrid?
I would start with custom formatter. jqGrid support predefined formatters like formatter: "integer", formatter: "date". You can "register" your custom formatter and unformatter as one more value which you can use. For example if you want to register formatter: "myCheckbox" you need define $.fn.fmatter.myCheckbox as formetter function and $.fn.fmatter.myCheckbox.unformat as unformatter function.
$.extend($.fn.fmatter, {
myCheckbox: function (cellValue, options, rowObject) {
// the code of the custom formatter is here
...
}
});
$.extend($.fn.fmatter.myCheckbox, {
unformat: function (cellValue, options, elem) {
// the code of the custom unformatter is here
...
}
});
The code from here uses Font Awesome 4.x and register new formatter: "checkboxFontAwesome4". "Registering" of custom formatters can simplify your code.
The next feature. jqGrid supports column templates starting with version 3.8.2 jqGrid (see the old answer). It allows you to define common settings used in colModel as one object and to use template property in colModel. For example if you have many columns which contains numbers you can define for example numberTemplate object as
var numberTemplate = {
formatter: "number", align: "right", sorttype: "number", width: 60,
searchoptions: {
sopt: ["eq", "ne", "lt", "le", "gt", "ge"]
}
};
then you can define tree columns "tax", "amount" and "total" as
colModel: [
...
{ name: "tax", template: numberTemplate },
{ name: "amount", template: numberTemplate },
{ name: "total", width: 70, template: numberTemplate },
...
]
In the way you defines columns where all the properties from numberTemplate will be applied in the columns. The default width: 60 defined in numberTemplate will be overwritten to the value width: 70 for the column "total".
The usage of column templates allows you to define once in your code templates for dates which uses jQuery UI Datepicker for example and uses in every column of every grid of your project just the corresponding reference on the template.
The current version of jqGrid on github supports "registering" of templates as strings. So the next version (higher as 4.6.0), which I hope will be soon released, will support the following syntax:
$.extend($.jgrid, {
cmTemplate: {
myNumber: {
formatter: "number", align: "right", sorttype: "number",
searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] }
}
}
});
(in the example I didn't included width in the template)
colModel: [
...
{ name: "tax", width: 52, template: "number" },
{ name: "amount", width: 75, template: "number" },
{ name: "total", width: 60, template: "number" },
....
]
See the pull request for more details.
As with any jQuery plugin, you can extend the plugin with $.extend() like this:
(function($) {
var extensionMethods = {
// ...
};
$.extend(true,$.jgrid, extensionMethods);
})(jQuery);
I have a grid that has a column in which the user can enter only a positive integer. Every other value is unacceptable.
For a text field i could have handled a similar scenario using a VType, but i am not able to add a VType to a column of a grid. Is it even possible to add one?
If yes, it would be great if someone could show me how to do it.
PFB the code for the grid:
xtype:'gridpanel',
id:'my-grid',
overflowY:'auto',
sortableColumns:false,
enableColumnHide:false,
enableColumnResize:true,
plugins:[
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit:1,
pluginId:'cellEditing'
})
],
store:new Ext.data.Store({
fields:['data1', 'data2'],
addRecords:false,
data:storeData
}),
columns:[
{
text:'NumberColumn',
dataIndex:'data1',
menuDisabled:true,
sortable:false,
flex: 4,
editor:{
xtype:'textfield',
allowBlank:false,
//tried adding vtype here...but didn't work...
},
renderer:function (value, metaData, record) {
return value
}
}
A vtype can be applied to a field never a column. A column only visualize a value while a fields allows you to enter and manipulate it. In your case you are using Cellediting which overlays the column with a Ext.form.Field instance, in your case a textfield which then allows you to enter/manipulate a value. So adding a valid vtype to a fieldconfig should work. Anyway there is no vtype for numeric so using it here is worthless in your case.
But your problem can easily be solved by using the following field:
{
xtype: 'numberfield',
allowDecimals: false,
minValue: 0,
allowBlank: false
}
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);
}
}
}
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