Two Default Grids Defenition:
initialise(){
$("#ExpenseTable").jqGrid({
datatype : "local",
mtype : 'GET',
colModel : [ {name:'expnsId',label:'ID', width:150 },
{name:'userName',label:'NAME', width:150 },
{name:'catName',label:'CATEGORY', width:150 },
{name:'date',label:'DATE', width:150 },
{name:'amount',label:'AMOUNT', width:150 },
{name:'status',label:'STATUS', width:150 }],
pager : '#ExpPager',
rowNum : 10,
rowList : [ 10, 20, 30 ],
sortname : 'invid',
sortorder : 'desc',
viewrecords : true,
autowidth : false,
caption : 'Expenses Details',
onSelectRow : function(expnsId) { dispExpensData(expnsId); }
});
$("#tabs").tabs();
getTokens();//Gets the tokens for the logged in user.
refreshExpenseGrid();//Populates data to the grid
dispLeaveGrid();// It ll call the next default grid
}
}
$("#LeaveTable").jqGrid({
datatype : "local",
mtype : 'GET',
colModel : [ {name:'leaveId',label:'ID', width:150 },
{name:'userName',label:'NAME', width:150 },
{name:'fdate',label:'DATE', width:150 },
{name:'tdate',label:'DATE', width:150 }
{name:'status',label:'STATUS', width:150 }],
pager : '#ExpPager',
rowNum : 10,
rowList : [ 10, 20, 30 ],
sortname : 'invid',
sortorder : 'desc',
viewrecords : true,
autowidth : false,
caption : 'Leave Applications',
onSelectRow : function(leaveId) { displeaveData(leaveId); }
});
refreshLeaveGrid();//Populates data to the grid
securedUI();//This ll call the below function, to check whether the remaining tabs can be visible or not
Secured UI Function:
function securedUI(){
var secToken = "DELETEUSER";
if(!checkRoleToken(secToken)){//If users dont have token to delete user, the buttons ll be disabled
$('#expDelete').attr('disabled', 'disabled');
$('#lveDelete').attr('disabled', 'disabled');
$('#delUser').attr('disabled', 'disabled');
$('#roleDel').attr('disabled', 'disabled');
$('#tokenDel').attr('disabled', 'disabled');
}
var secToken= "VIEWUSER";
if(checkRoleToken(secToken)){
showUserdetails();//3rd Grid Defn:Contains the table definition for user grid.
initialiseRole();//4th Grid Defn: Role grid
showtokens();//5th Grid Defn: token grid
}
Check Token:
function checkRoleToken(newToken){
for( var i = 0; i<tokens.length; i++ ){
var token = tokens[i];//Tokens is like cache, which contains all the tokens that are assigned for the current user.
if(newToken == token.tokenName){
return true;
}
}
return false;
}
The html page:
<script type="text/javascript">
$(document).ready(function() {
initialise();
});
</script>
The LeaveTable is 2nd grid and i have 3 more grids. But i dont want to show them to all of the users, instead admin users should able to see them. Tokens are the key to find the user have the right to do any operation in the Application. Tokens, that are assigned for the user will be loaded to a client-Side Cache like Array tokens.
Every function like ADD, DELETE, UPDATE & VIEW have their tokens at the start of the function that stored in a variable. That token variable will sent to CheckToken() as argument. There it will check that token against the token cache. It ll return true or false. The operation will cancelled or continued according to that result.
In the above code, at the end of the LeaveTable grid defenition, you can see a function call securedUI();. Inside that function i am doing two things. 1.Disabling Delete Buttons, 2.Disabling the 3rd, 4th & 5th grids, for those who dont have tokens DELETEUSER & VIEWUSER.
Actually what i am getting now is, the 3rd, 4th & 5th grids are not getting displayed for those who have token VIEWUSER. Look at the functions securedUI() & checkToken(), what they should do!!! securedUI() have VIEWUSER token and the current user also, so the checkToken() should return true, so it should get into the if block and execute the functions calls inside the if block. But its not doing it. I cant able to get any clue about where i am going wrong.
So, i turned on the firebug and checked it step by step. Magically, now its going into the if block and shows the grid for admin users. Now i felt that it worked then i turned turned off the firebug and reloaded the page again. Ooops, again that 3 remaining grids are not displaying. Can you now able to get an idea about my problem!!!
Any suggestions!!!
It seems to me that you should just place all your JavaScript code inside of jQuery(document).ready handle: jQuery(document).ready(function() {/* place your code here */});
If you do use this handle, please post more full code of your example inclusive full HTML code. You can reduce the code example to have example more compact. Important is only that the problem stay in the code and everyone can reproduce the problem.
Related
I am creating a page where I'm using DataTables.js to display information and the plan is to have a submit button on each row that submits a form with the row information.
At first I used a jstl loop to generate the table which worked but this ran into some issue with having a tag in the loop of the table to submit each row.
So now, in the servlet, I have a List that is passed from the controller and to the servlet and is the converted to a Json string using Gson. In the console, when navigating to the page, I can confirm that the the string has the correct data since I printed it out in the console.
Now my question is how do I utilize this attribute, that I do set using req.setAttribute("allX", allX) to pass it to the JSP.
I have a script tag at the bottom of the JSP to populate the table which is
<script>
$(document).ready(function () {
var allx = ${allX}
$('#allTable').DataTable({
"data" : allx
});
});
</script>
Above in the jsp I have a tag with the id allTable.
What I really need help with is correctly displaying the data in the table from the Json string and then adding a submit button to each row that submits the information in the row back to the servlet, which at this point and will probably only ever be one data point per row. I'm okay with handling the data in the servlet and processing it for use elsewhere, its just this table data, I having a huge issue with.
Not sure, if I understood your question correctly, but I assume you have no issue in collecting the data and composing the response to the client, but having issues with displaying the data in the datatables on the client side.
You would want to send an array of objects, so datatables can display it properly. Each element in that array would be an object, describing a complete row. Here is an example:
// You can use array of objects. Each object will be a row in the table.
// Compose it on the server or client side and give to DataTables for processing.
// Your objects can have many keys. You can tell DataTables which to use. In this
// example, I use allX.id and allX.type, while ignoring allX.color.
var allX = [
{ id: '0', type: 'pencil', color: 'blue' },
{ id: '1', type: 'pen', color: 'orange' },
{ id: '2', type: 'marker', color: 'black' }
];
var table = $('#allTable').DataTable({
data: allX, // allX here is our array, which contains the data to display in the table
columns: [{
data: 'id', // object key to look for value
title: 'ID' // give a title to your column
},
{
data: 'type', // our second column description
title: 'Type'
},
{
width: '30%', // our buttons column
orderable: false // we will describe it further in 'columnDefs'
},
],
"columnDefs": [{
"targets": -1, // -1 = last column
"data": null, // no data for this column, instead we will show default content, described in 'defaultContent'
"defaultContent": "<button id='submit-btn'>Submit</button> <button id='delete-btn'>Delete</button>"
}],
});
// catch a button click event
$('#allTable').on('click', 'button', function() {
// create an object from a row data
var rowData = table.row($(this).parents('tr')).data();
// fire a function, based on the button id that was clicked
if (this.id === 'submit-btn') {
submitData(rowData);
} else if (this.id === 'delete-btn') {
deleteData(rowData);
}
});
function submitData(data) {
// Process your row data and submit here.
// e.g. data === { id: '1', type: 'pen', color: 'orange' }
// Even though your table shows only selected columns, the row data
// will still contain the complete object.
// I would recommend against sending a complete object. In your case,
// with a single data point, perhaps it is fine though. However,
// always send bare minimum. For example, if you want to delete an
// entry on the server side, just send the id of the entry and let
// the server locate it and delete it by id. It doesn't need all other
// fields.
}
function deleteData(data) {
// Just an example how you can have various buttons on each row.
}
Hi I have a problem in a jquery asp.net project:
I have on one page 2 grids - the main grid is loaded while the second grid is disabled(hidden). When I click on one row in the main grid the second grid is shown then and shows the data if some exist regarding to this row. If there is now data I want to create new data in the second grid. I tried to handle this with url (to get the data), editurl (to modify existing data) which works fine and now I need e.g. a addurl to create new data.
Has anyone an idea to fix this problem because I didn't really found something on the net about this..
onSelectRow: function (id) {
var rid = jQuery('#tblJQGridBereitschaft').jqGrid("getGridParam", "selrow");
if (rid) {
var row = jQuery('#tblJQGridBereitschaft').jqGrid("getRowData", rid);
}
var bs_id = row.ID;
function seturl(bs_id){
jQuery("#tblJQGridBereitschaftFahrtkosten").setGridParam({ loadonce: false })
jQuery("#tblJQGridBereitschaftFahrtkosten").setGridParam({ datatype: "json" })
jQuery("#tblJQGridBereitschaftFahrtkosten").setGridParam({ url: '#Url.Action("GetFahrtkosten", "Bereitschaft")?BS_ID=' + bs_id +'', page: 1 }).trigger('reloadGrid');
jQuery("#tblJQGridBereitschaftFahrtkosten").setGridParam({ editurl: '#Url.Action("ModifyFahrtkosten", "Bereitschaft")?BS_ID=' + bs_id, page: 1 }).trigger('reloadGrid');
// Here I need the "addurl"
jQuery("#tblJQGridBereitschaftFahrtkosten").setGridParam({ loadonce: true })
}
seturl(bs_id);
$("#headerFahrtkosten").show();
$("#jqgrid_containerfahrtkosten").show();
},
Thanks for any help or tips!
I am using jquery datatable to show data. I customize the paging function. For example each page has 10 record. First my function take 10 records. If user click next button then my function take more than 10 records. If user click 'previous' button and then my function save last page. Because if user click 'next' button then same records are not pull again. Existing records are shown. Thus the same records don't occur. But if the user never clicked the back button. And for example on page 3, if user sort coloumn and then table show first page with out saving last page number. So that if user click next button, after that same records will be fetch one more time. And same records wiil be shown on table. So that i must save last page number after sorting coloumn in jquery table. I searched this problem to find solution. I find solutions only like as below:
$('#example').dataTable( {
stateSave: true
} );
How can i save last page number, after coloumn sorting (because of showing first page). And how can i store this last page number on variable to use when i fetch data from server.
The following example will add the current page and the previous page numbers to the request parameters sent to your server.
$(document).ready(function() {
//vars
var previousPage = null;
// DataTable
var table = $('#example').DataTable( {
"serverSide": true,
"ajax": {
"url": "yourAjaxDataSource.url",
"type": "POST",
"data": function ( dtData ) {
var info = $('#example').DataTable().page.info();
var currentPage = info.page + 1;
var customData = $.extend( {}, dtData, {
"currentPage": currentPage,
"previousPage ": previousPage
} );
return customData;
}
},
"columns": [
{//1st Column:
"data": "foo" },
{//2nd Column:
"data": "bar" }
],
//this will always be called after the table is drawn
"drawCallback": function( settings ) {
var info = $('#example').DataTable().page.info();
previousPage = info.page + 1;
}
} );
} );
On the server side, if you're using PHP, you can access the new request parameters you added like this:
<?php
$currentPage = $_POST['currentPage'];
$previousPage = $_POST['previousPage'];
?>
I'm trying to reset a numberfield so that it displays the empty text contents when a pop up is called again. In my current situation, I have a time spinner, that is for hours. If I set this to, say, 12, if I close the popup and reopen, it will default to 0, rather than the emptytext, which is set to 'hh'. Code is below.
xtype : 'numberfield',
itemId : 'HrItemId',
id : 'HrId',
width : 50,
emptyText : 'hh',
maxValue : 23,
minValue : 0,
maxLength : 2,
enforceMaxLength : true,
listeners : {
change : function(textField, newValue, oldValue,eOpts) {
if (newValue < 0 || newValue > 23) {
checkMaxValue('vfcHoldHrItemId');
} else {
me.PopupWindow.queryById('continueButton').enable();
}
}
}
me.PopupWindow.queryById('HrItemId').setValue(0 ); // works, and shows in Firefox debugger as an object
me.PopupWindow.queryById('HrItemId').reset(); // shows in Firefox debugger as undefined
First of all, make sure that me.PopupWindow.queryById('HrItemId') really returns the expected number field. Number fields do have reset method since Ext 1 so the only way how it would "become" undefined is that you're not calling it on a numberfield.
There's another problem I see in the above code and it is that you use ids on components. That is a bad, or better say a deadly, practice as ids propagate down to html markup. Html ids must be unique on a page.
That means if you have a window with a form and fields and fields have ids, you mustn't have two instances of that window. If you do an unpredictable behavior ensues.
Okay, so in a nutshell, what I need to do is to automatically apply a set of sorting criteria and data filters to the jqGrid when it loads. The intent is that the user will start with about 10 pre-filled filters and then, if they so choose, they can alter those filters or the sorting however they see fit.
So far, with much Google-ing, trial and error and sweat, I have the following working:
-> I can load/save the sort column & sort order in a session cookie.
-> I can load the search dialog with pre-defined search filters. After the grid loads, I can open the modal dialog and see the proper filters and if I click "Find" the appropriate data is posted to the server and the right results are returned to the screen.
The thing that is biting me in the butt right now is, I think, the easy part, but it escapes me. I can't seem to do either of the following:
( A ) The ideal thing would be if I could attach these filters to the grid and it's post data in advance of the initial load so that there is only a single trip to the server.
( B ) The workable solution, though less ideal, would be for the grid to load the first page of the unfiltered data first, and then apply the filters and re-query the server for the filtered data.
Since I can manually click the "find" button today and it works, I thought that "B" would be a good next-step. So, in my gridComplete function, I have the following code:
$('#AccountGrid').clearFilter({gridName:'AccountGrid', pagerName:'AccountPager'});
$('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:1, op:'ne'});
$('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:3, op:'ne'});
// $('#fbox_AccountGrid').searchFilter().search();
// $('#fbox_AccountGrid .ui-search').click();
$('#AccountGrid').trigger('reloadGrid');
NOTE: "clearFilter" and "addFilter" are extension functions I have added to jqGrid to simplify adding and removing filters on the grid. They work exactly as desired at this point.
As you can see with those last three lines of code, I have tried using the built-in function, as well as going after the find button directly and even just forcing the entire grid to refresh. Either way, there is no attempt by the grid to go get new data (I am using Fiddler to watch for it).
What am I doing wrong in trying to force the grid to reload with the new filters?
And, if you know how, can you give me some direction on how to get the initial load of the grid to respect these filters?
TIA
Tony
Here is the full grid configuration (minus the extra columns and some colModel "cruft"):
jQuery('#AccountGrid').jqGrid({
url: '<my URL>',
width: 950,
height: 330,
shrinkToFit: 'true',
datatype: 'json',
mtype: 'POST',
multiselect: true,
multiboxonly: true,
multiselectWidth: 20,
colNames: [
'Account ID'
],
colModel: [
{ name: 'AccountID', index: 'AccountID', sortable: false, hidden:false, search:true }
],
gridComplete: function () {
// add the search criteria to the grid
if (initialLoad == true){
$('#AccountGrid').clearFilter({gridName:'AccountGrid', pagerName:'AccountPager'});
$('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:1, op:'ne'});
$('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:3, op:'ne'});
// $('#fbox_AccountGrid').searchFilter().search();
// $('#fbox_AccountGrid .ui-search').click();
$('#AccountGrid').trigger('reloadGrid');
initialLoad = false;
}
},
jsonReader: {
repeatitems: false,
id: 'AccountID'
},
pager: jQuery('#AccountPager'),
rowNum: 50,
rowList: [10, 15, 25, 50, 75, 100],
onSortCol : function (sortname, indexColumn, sortorder){
$.cookie('AccountGrid_sortname', sortname);
$.cookie('AccountGrid_sortorder' , sortorder);
},
sortname : $.cookie('AccountGrid_sortname') ? $.cookie('AccountGrid_sortname') : 'AccountID',
sortorder: $.cookie('AccountGrid_sortorder') ? $.cookie('AccountGrid_sortorder') : 'asc',
viewrecords: true,
imgpath: ''
});
$('#AccountGrid').jqGrid('navGrid','#AccountPager',
{ view: false, add: false, edit: true, del: false,
alertcap:'No Account Selected',
alerttext: 'Please select an Account from the grid before performing this operation.',
editfunc: showAccountEditDialog },
{}, // default settings for edit
{}, // default settings for add
{}, // delete
{closeOnEscape: true, multipleSearch: true, closeAfterSearch: true }, // search options
{}
);
And, by request, here is the code I have for add/clear filter:
/*
This is a grid extension function that will insert a new filter criteria
on the specified grid with the provided field, operation & data values
*/
(function ($) {
jQuery.jgrid.addSearchFilter =
{
// get/set the parameters
addFilter: function (options) {
var grid = $(this);
// get offset values or assign defaults
var settings = $.extend({
gridName: '',
field: '',
data: '',
op: ''
}, options || {});
// get the column model object from the grid that matches the provided name
var colModel = grid.getGridParam('colModel');
var column;
for (var i = 0; i < colModel.length; i++) {
if (colModel[i].name == options.field){
column = colModel[i];
break;
}
}
colModel = null;
if (column){
// if the last filter has a value, we need to create a new one and not overwrite the existing ones
if ($('#fbox_' + options.gridName + ' .sf .data input').last().val()){
$('#fbox_' + options.gridName).searchFilter().add();
}
// assign the selections to the search dialog
$('#fbox_' + options.gridName + ' .sf .fields select.field').last().val(column.index).change();
$('#fbox_' + options.gridName + ' .sf .data input').last().val(options.data);
$('#fbox_' + options.gridName + ' .sf .ops select.default').last().val(options.op).change();
}
}
}
})(jQuery);
jQuery.fn.extend({ addFilter: jQuery.jgrid.addSearchFilter.addFilter });
/*
This is a grid extension function that will clear & reset the filter criteria
*/
(function ($) {
jQuery.jgrid.clearSearchFilter =
{
// get/set the parameters
clearFilter: function (options) {
var grid = $(this);
// get offset values or assign defaults
var settings = $.extend({
gridName: '',
pagerName: ''
}, options || {});
// clear the filters and "pop" the dialog to force the HTML rendering
$('#fbox_' + options.gridName).searchFilter().reset();
$('#' + options.pagerName + ' .ui-icon-search').click();
$('#fbox_' + options.gridName).searchFilter().close();
}
}
})(jQuery);
jQuery.fn.extend({ clearFilter: jQuery.jgrid.clearSearchFilter.clearFilter });
First of all because you don't post the code which define the jqGrid I make some assumption myself. I try to base on indirect information from your question.
1) I suppose that you use server side datatype parameter of jqGrid like 'json' or 'xml'.
2) You don't use loadonce:true parameter. In general if would be possible to make server reload from the grid having loadonce:true, but in the case you have to reset the value of datatype parameter to initial value (one from the value 'json' or 'xml').
The following three old answer: this (in case of single value searching) and this (in case of advanced searching or the toolbar searching with additional parameter stringResult:true) will give you enough information about setting the searching filters and reloading the grid corresponds to the new filters. Another answer shows how to clear the searching filter if it is no more needed.
Loading of the grid at the first time with the filters is another question. It can be very easy implemented. You should just use datatype:"local" instead of datatype:"json" or datatype:"xml" which you really need. In the case the url parameter of jqGrid will be just ignored at the first load and jqGrid send no request to the server. Then you set the filters like you as need and only then use $("#youGridId").trigger("reloadGrid");
The reason why the reloadGrid didn't work in your case I could not know exactly, but I suppose that you didn't set the search:true parameter of the jqGrid which one confuses frequently with the _search property of the postData parameter (see here).