I have a view panel in xpages and a computed field to show the row-count. I have 2 problems:
1st: how can i count only the rows of the current page of the pager?it seems that viewPanel.getRowCount() gets all rows from the beginning until the current page, so if i have 30 entries per page and i am in page 2, it shows 60 instead of 30.
2nd: even if i achieve the above, the pager only refreshes the view and i can't refresh the computed field or another panel. Can i put the computed field inside the view panel or make it somehow to be refreshed in each page change? i would prefer not to do it with full page refresh if possible...
Given the computed field refresh issue, even if you managed to get a count of rows (eg on a page-scope SSJS variable), it woudln't update the computed field.
It might be easier to to count to rows in the HTML table using clientside javascript ?
something like ..
page onload event :
get the HTML table
get the table rows property (array of rows in the table)
number or rows = that value (1st row = TH (header) row if there is one = row 0)
use javsscript to plug that value into a known DIV
You could also hijack the partial refresh issued from the pager and check for the ID that has been refreshed. If the ID match your view panel's ID, you could do another partial update in order to update another panel.
Example code for hijacking the partial refresh:
var sysHijackPartialRefresh = function(){
XSP._inheritedPartialRefresh = XSP._partialRefresh;
XSP._partialRefresh = function( method, form, refreshId,options) {
if (options){
if (!options.onComplete) {
options.onStart = function(){
};
options.onComplete = function(){
if (refreshId == "<client id of view panel>") {
// issue another partial refresh
XSP.partialRefreshGet(<client id of the other panel>);
}
};
}
}
this._inheritedPartialRefresh(method, form, refreshId, options); }
}
XSP.addOnLoad(sysHijackPartialRefresh);
See http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_events_and_partial_or_full_refresh for more information about partial updates.
The pager should have a "refreshID" property in which you can put the client ID (!) of the panel you want to refresh. Use getClientId() to compute the client ID of the panel.
For the row count: use the XPages debug toolbar (from openNTF) to check for a property of the view panel or the pager which gives you the current page number. If you got that, you can simply compute by using viewPanel.getRowCount() - (page number * number of rows per page).
Related
I am trying to change the recordtext of a display grid to a custom format. I am using a treeview as the selector that refreshes the display grid. I need to find the total records for the grid and I am able to get this value using the getGridParam records method when I click on the treeview node and load the display grid.
However, after I get this value and try to create the custom recordtext, the record count is the previous value, not the current records count. I know that the gridComplete happens before the loadComplete, but even placing the get in the gridComplete and the set int he loadComplete, it still doesn't work, even with a reloadGrid trigger. If I click on the treeview node twice, I get the correct value.
I am thinking it is a timing issue as to when the new value is ready to set the recordtext. Any help would be great, thanks in advance.
I recommend you to try updatepager method, which updates the information on the pager. Alternatively you can do for example the following:
loadComplete: function () {
var p = $(this).jqGrid("getGridParam");
p.records = 123;
p.recordtext = "My View {0} - {1} of <i>{2}<i>";
this.updatepager();
}
to see the viewrecords
So what I'm trying to accomplish is when the grid is fully loaded, I loop over a certain column that contains checkboxes. Depending on the value of the checkbox I should be able to disable it.
Problem is that I can't access the html element that's there. Am i doing something wrong or overlooking something?
What i've tried:
loadComplete: function() {
// Fetch all the ID's of the rows
var rows = $("#table").getDataIDs();
// Loop over the rows
if(rows.length != 0){
for(i=0; i < rows.length; i++) {
// Get the data so we test on a certain condition
var row = $("#table").jqGrid("getRowData", rows[i]);
if (row.gridCheckbox == 1) {
//disable the element
row.prop("disabled", "disabled");
}
}
}
}
It's important to understand that changing one element on the page follow in the most cases to web browser reflow: validation whether some property (position for example) need be changed in all other elements on the page. If you do changes in the loop then your JavaScript code can be really slow.
Thus it's strictly recommended to reduce the number of changes of the DOM. Especially to reduce the number of changes jqGrid provides rowattr, cellattr and custom formatters. If you need for example to set disabled attribute on some rows then you should now do this in loadComplete, but to use rowattr instead to inform jqGrid that some additional attributes (disabled="disabled") should be set on some rows. jqGrid collect first the string representation of the whole table body and it use one assignment of innerHTML to fill the whole body of the grid in one DOM operation. It improves essentially the performance. See code example in the old answer.
In jqgrid, when there are 6 records (Paging 5).
So, first page has 5 records and second page has 1 record now, user has deleted 6th record (from page #2).
Then, grid still remains on page #2 and no rows exists on page 2 as its deleted. It does not look good when 5 records on page 1 and no records on page 2 though, page selection appeared on page 2.
Can you please guide how to solve that. i think, it should be move to earlier page (last page).
Also, related issue:
when all 6 records are deleted. then, grid still appear.
Insted of that, there should be some label message to appear as no records exists.
How to achieve this ?
You can use reccount options which provides the number or records on the current page of the grid. If the number of records is 0 you can do additional action. For example you can trigger reloadGrid with additional page option (see the answer)
var $self = $(this), // or $("#gridId")
p = $self.jqGrid("getGridParam"), // get all parameters
newPage;
if (p.lastpage > 1) { // on the multipage grid
newPage = p.page; // the current page
if (p.reccount === 0 && p.page === p.lastpage) {
// if after deleting there are no rows on the current page
// which is the last page of the grid
newPage -= 1; // go to the previous page
}
// reload grid to show rows from the page with rows.
// depend on where you use the code fragment you could
// need reloading only in case
// p.reccount === 0 && p.page === p.lastpage
setTimeout(function () {
$self .trigger("reloadGrid", [{ page: newPage}]);
}, 50);
}
If you need to display some message text in the grid body you can follow the demo created for the answer. The demo just shows div with the message text in case of reccount === 0.
There is a simple form that has 6 dropdownlists and a gridview. When any of the dropdownlists change the value filters the grid by altering the selectcommand. A user can navigate in another page through a row of the grid.
From the other page a user has a back button that loads the page WITH a querystring which has the values of the dropdownlists.
I want to accomplish 2 things:
1) To put the values in the dropdownlists. This i have done easily.
2) The next thing is to make the grid show data based on this values. this is its normal operation.
I thought that if i add the following code in page load would do the trick but it didnt. I tried all the events but no luck.I can get the dropdownlists to hold the value i want but the grid shows ALL records:
if (!IsPostBack)
{
if (Request.QueryString["ret"] != null)
{
string[] retvalues = Request.QueryString["ret"].Split('_');
Update_Search(retvalues);
dsTodo.SelectCommand = dsTodo.SelectCommand + Build_Where();
GridView1.DataBind();
}
}
The last 2 lines exist in the selectedvaluechange evnets on the dropdownlists and they work fine to filter the grid in normal operation.
You are setting the SelectCommand but you are not executing it. Do this:
dsTodo.SelectCommand = dsTodo.SelectCommand + Build_Where();
dsTodo.Select(DataSourceSelectArguments.Empty);
GridView1.DataBind();
That's assuming that the DataSourceID property of the GridView1 is set to dsTodo.
I'm using jqGrid's filterToolbar method to let users quick search/filter the grid data. I'm using loadonce: true and datatype: local as my grid configs. I have a drop-down (select) filter type for one of my columns, which works fine.
Problem is when i try to update a row (using setRowData) that is not visible (because the filter/search result is hiding them), the row doesn't get updated when I reshow them by clearing the filter.
Any suggestions? I've tried triggering the reloadGrid event too, no luck.
Cheers
Update 1 - Reproducing the problem:
Here's how to reproduce the problem, using jqGrid's official demos:
Step 1
Browse to the jqGrid's demo page, and open the demo named 'Toolbar search' under 'New in version 3.7'
Step 2
In the demo grid, filter by the code column with the value 575878 so that only the first row is shown on the grid.
Step 3
Bring up the javascript console and update a row that's not currently visible, in this example update row 2:
jQuery("#toolbar").jqGrid('setRowData',2,{item_id:2,item:'blargh',item_cd:12345678});
Step 4
Unhide all the rows by clearing the filter value, and see that row 2 has not been updated!
Anything I'm doing wrong here? Possible workarounds?
You misunderstand how the grid are build. Grid can contain hidden columns, but no hidden rows. If one filter grid the full grid body will be removed and only the filtered rows will be inserted.
The method setRowData can be used to modify any row of the grid, but you can't modify something which is not present in the grid.
If you use local grid (datatype: 'local') then the data which you save in the grid will be saved in two internal jqGrid parameters data and _index. So you should modify the data object. To fill grid with modified data you need call .trigger("reloadGrid").
So if you want modify columns item_id, item and item_cd of the grid's data for the rowid=2 you can do the following steps.
1) Get references to the internal jqGrid parameters data and _index:
var $myGrid = jQuery("#toolbar"),
data = $myGrid.jqGrid('getGridParam', 'data'),
index = $myGrid.jqGrid('getGridParam', '_index');
2) Get reference to the object which represent the rowid which you need:
var rowId = '2',
itemIndex = index[rowId],
rowItem = data[itemIndex];
3) Modify the data item like you as need:
rowItem.item_id = 2;
rowItem.item = 'blargh';
rowItem.item_cd = 12345678;
4) Refresh grid contain (if needed) by reloading the grid
$myGrid.trigger('reloadGrid');