Why my YUI 2 server side pagination, Datasouce is not called on every click of pagination link - yui

My code looks like below. I am feching the json records from the server side using structs action. it is returning the records fine and i could able to see the table with data. pagination links created fine. when i click next and datasource is called on each click of any link on the pagination. if i click on colum header also, the datasource is being called.
my questions are:
1)When datasource is being called. because i am seeing sometime called and some times not. like when i got from 1page to 2page, datasource is called fine. when i go back to previous pages by clicking 'prev' link, datasource is being called. but after that if i click again on next to go to 2nd page, datasource is not being called. when exactly datasource is called and how many times it will called. is it for every link in the pagination calls datasource?
2)If my datasource returns 100 recods of data and my records per page is set to 25, then do i see the 4 pages. I am confused here with server side pagination and datasource calls.
datasource is not called for each page link and next or prev link clicks? if not, when datasource is called? please explain me. I know how many total records are there in the begining and my requirement is showing 25 records per page when ever user clicks on page number or next or prev links. i have the capability to bring corresponding 25 records based on the page number from server side.
3)how to capture the 'next' and 'prev' clicks on the pagination.
my requirement is to dynamically fetch the json data using datasource from the server whenever user click on page number links or next or prev.
Please help me out with this. I am new to YUI. I have to User YUI 2 only since we are already using it.
<div id="dynamicdata"></div>
<script type="text/javascript">
YAHOO.example.DynamicData = function() {
var myColumnDefs = [ // sortable:true enables sorting
{key:"PIN", label:"PIN", sortable:true},
{key:"CODE", label:"CODE", sortable:true}
];
// Customize request sent to server to be able to set total # of records
var generateRequest = function(oState, oSelf) {
// Get states or use defaults
oState = oState || { pagination: null, sortedBy: null };
var sort = (oState.sortedBy) ? oState.sortedBy.key : "PIN";
var dir = (oState.sortedBy && oState.sortedBy.dir === YAHOO.widget.DataTable.CLASS_DESC) ? "desc" : "asc";
var startIndex = (oState.pagination) ? oState.pagination.recordOffset : 0;
var results = (oState.pagination) ? oState.pagination.rowsPerPage : 25;
var total = YAHOO.util.Dom.get("total").value *1;
// Validate input
if(!YAHOO.lang.isNumber(total) || total < 0 || total > 200) {
YAHOO.util.Dom.get("total").value = 0;
total = 0;
alert("Total must be between 0 and 200.");
}
// Build custom request
return "sort=" + sort +
"&dir=" + dir +
"&startIndex=" + startIndex +
"&results=" + (startIndex + results) +
"&total=" + total;
};
// DataTable configuration
var myConfigs = {
generateRequest: generateRequest,
initialRequest: generateRequest(), // Initial request for first page of data
dynamicData: true, // Enables dynamic server-driven data
sortedBy : {key:"PIN", dir:YAHOO.widget.DataTable.CLASS_ASC}, // Sets UI initial sort arrow
paginator: new YAHOO.widget.Paginator({ rowsPerPage:10 }) // Enables pagination
};
var myDataSource = new YAHOO.util.DataSource("<%=request.getContextPath()%>/results.do?startIndex="+localStartIndex+"&rowsPerPage="+rowsPerPage);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
myDataSource.responseSchema = {
resultsList: "data",
fields: [
{key:"SSN"},
{key:"PIN"}
]
}
var myDataTable = new YAHOO.widget.DataTable("dynamicdata", myColumnDefs, myDataSource, myConfigs);
// DataTable instance
var myDataTable = new YAHOO.widget.DataTable("dynamicdata", myColumnDefs, myDataSource, myConfigs);
// Update totalRecords on the fly with values from server
myDataTable.doBeforeLoadData = function(oRequest, oResponse, oPayload) {
oPayload.totalRecords = 200;
return oPayload;
};
return {
ds: myDataSource,
dt: myDataTable
};
}();

As far as I remember, the DataTable will always ask for fresh data whenever it changes pages or sorts by a different column. It doesn't cache previous requests nor does it keep track what it has asked. If you don't see requests arriving on the server side it might be because of caching, but not in DataTable or DataSource but by the browser itself, which is a matter of issuing the proper headers on the server to tell the browser not to cache.
If I am not mistaken, that this is supported by the behavior you describe. The first page is requested twice, once when you first draw the table, once again when you return from page 2. All other pages are never requested twice. Why? Because the first time around the URL formed is slighty different from the URL when you return to it. The browser cache only knows about URLs.

Related

How to set Persistence for presented page number?

Is there any setting to store the current presenting page number like as persistentLayout:true?
I created Back Button with history.back(); that always back to first page of table.
There is no built in way of doing this, but you could use the pageLoaded callback to store the current memory in local storage:
var table = new Tabulator("#example-table", {
pageLoaded:function(pageno){
//pageno - the number of the loaded page
localStorage.setItem('currentPage', pageno);
},
});
And then on page load set the page of the table after you have instantiated it with the setPage function
table.setPage(localStorage.getItem('currentPage') || 1)

DataTables reload table with different pageLength param

Based on this question.
I initialize my datatables.js table with the following code:
var table_entity = $('#myTable').DataTable({
"pageLength":getParameterByName('pageLength'),//getting param from query string
fixedHeader: true,
"ajax": {
"url": myUrl,
"data": function(d) {
d.type = $('#mytype').val();
}
}
});
So I know how to reload my datatable with different ajax params. Now I need to reload it with different pageLength param which does not belong to ajax section and is recorded during datatables init stage. I tried to pass it directly during reloading with the following code:
table_entity.ajax.reload({
"pageLength":77 //some new param different from the initial one
});
But it did not work, the table is reloaded with initial pageLength value. Any ideas how to fix it would be welcome. Thank you.
UPD_1
managed to do that with
1st: complete destruction of a table:
$('#MyTable').DataTable().destroy();
$('#MyTable tbody').empty();//note tbody here
2nd: reinit the table with updated params:
table_data.displayStart = Number(getParameterByName('displayStart'));
table_data.pageLength = Number(getParameterByName('pageLength'));
table_data.iDisplayStart = Number(getParameterByName('displayStart'));
table_data.iDisplayLength = Number(getParameterByName('pageLength'));
$('#MyTable').DataTable(table_data);
Note 2 params - iDisplayStart and iDisplayLength here
Is it possible to do the same without destruction of the table, but during ajax.reload phase? Thank you.
Is it possible to do the same without destruction of the table, but
during ajax.reload phase?
You can hook into the xhr.dt event and update page.len() from there. Example :
$('#example').on('xhr.dt', function(e, settings, json, xhr) {
table.page.len(json.data.length).draw()
})
Will dynamically set the page length to maximum i.e length of data. Demo -> http://jsfiddle.net/d72zbyus/
So you could use table.page.len(77).draw() or whatever. xhr.dt is triggered after each AJAX request.
It is not clear to me where your new pageLength come from exactly. If it is part of the returned JSON (as I suspect) you could do table.page.len(json.pageLength).draw().

Pagination with Keypress (right arrow key)

I am facing an issue in pagination counter, I am using yii2 pagination, on keypress it is going to another page i.e http://localhost/web/index.php?r=test/page=1
so I need to increment the page value in the upper url
I am already doing like this but it is not working, the value is increment only once, and I need to increment the value for every page
<script type="text/javascript">
var val = 1;
$(document).keydown(function (event) {
val++
if (event.keyCode == '39') {
window.location.href = "localhost/web/index.php?r=test/page="+ val;
}
});
</script>
please give some suggestions, thanks a lot.
Looks like you're defining the page number (val) as 1 on every page so when you click the right arrow it sends you to page 2 every time. You'll need to first get the query parameter page to decide the value of val. Here's an example of getting query parameters with vanilla javascript How can I get query string values in JavaScript?.
You're also incrementing the page count on any button press, that looks like it should be within the right arrow keyCode condition.
Of course this won't work because you assign "1" to "val". So after keydown, "val" should always be "2". You need to store the page number somewhere else, for example, get it from url;
var pageNumber = getParameter('page');
$('document').on('keydown', function(event){
if(event.keyCode === 39) && window.location.href = ......
})

How to set different page size for first page in Orchard CMS

We got the need to display a blog posts page that display X posts - first post is displayed as a header and the rest are in 2 columns. The page has a show more button at the bottom that fetches the next page posts using ajax and adding them at the bottom.
Is it possible to get X+1 items for the subsequent pages?
Any hint, even in code are welcome since we use a sourced version of orchard installation.
So before cluttering the comments above this is my proposed solution.
I think there was a slight misunderstanding about changing the controller action which I'd like to clarify (I hope I understood everything correctly now):
Orchard.Blogs | BlogController | Item Action
public ActionResult Item(int blogId, PagerParameters pagerParameters) {
// This is all original code
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var blogPart = _blogService.Get(blogId, VersionOptions.Published).As<BlogPart>();
if (blogPart == null)
return HttpNotFound();
if (!_services.Authorizer.Authorize(Orchard.Core.Contents.Permissions.ViewContent, blogPart, T("Cannot view content"))) {
return new HttpUnauthorizedResult();
}
// This is the actual change:
// Use the pagerParameters provided, otherwise fall back to the blog settings
pager.PageSize = pagerParameters.PageSize.HasValue ? pager.PageSize : blogPart.PostsPerPage;
// This is all original code again
_feedManager.Register(blogPart, _services.ContentManager.GetItemMetadata(blogPart).DisplayText);
var blogPosts = _blogPostService.Get(blogPart, pager.GetStartIndex(), pager.PageSize) // Your new page size will be used
.Select(b => _services.ContentManager.BuildDisplay(b, "Summary"));
dynamic blog = _services.ContentManager.BuildDisplay(blogPart);
var list = Shape.List();
list.AddRange(blogPosts);
blog.Content.Add(Shape.Parts_Blogs_BlogPost_List(ContentItems: list), "5");
var totalItemCount = _blogPostService.PostCount(blogPart);
blog.Content.Add(Shape.Pager(pager).TotalItemCount(totalItemCount), "Content:after");
return new ShapeResult(this, blog);
}
So the change is very subtle, but this way I would configure the blogs default pageSize to 7 items and for every subsequent Ajax-Request I'd provide a "pageSize"-Parameter with the desired size.

Extension Library Name Picker gets local Names.nsf even though DB is on server

I have a Name Picker on an XPage with a dataProvider dominoNABNamePicker with the addressBookSel = all-public and people and groups = true. With the database on a Domino server using the Notes Client it displays my local Names.nsf. If I open the DB in a brouse it selects the correct names.nsf from the server.
Can't figure out if this is the result of settings in my client, the server or XPages. Does the same thing on two different PC's.
I would think that the all-public would force it to open only public NABs but it does not appear so.
I asked the same question myself.
The answer, in the control add
addressBookDb="SERVER!!names.nsf"
From here.
Can I have the extlib name picker running in xPINC lookup the directory on the server?
After a fair bit of frustration I have this working for the Notes Client and the Web Client. Perhaps this is obvious to most of you, but it sure wasn't to me.
First on the Name Picker I created a namePickerAggregator. Then I added a dominoNABNamePicker
in the addressBookDb I put the following SSJS:
var server:String = #Name("[CN]",session.getCurrentDatabase().getServer());
var allNABs:Array = session.getAddressBooks().iterator();
var pubNABs = new Array;
var privNABs = new Array;
while (allNABs.hasNext()) {
var db:NotesDatabase = allNABs.next();
if (db.isPublicAddressBook()){
pubNABs.push(db.getFileName())
} else {
privNABs.push(db.getFileName())
}
db.recycle()
}
if (pubNABs[0] == ""){
return privNames[0];
break;
} else {
return server + "!!" + pubNABs[0];
break
}
I then added a second dominoNABNamePicker with the same block of code except the return is
if (pubNABs[1] != "") {
return server + "!!" + pubNABs[1];
break;
} else {
return "";
}
This code works for both the Notes Client and the Web client so I'm now a happy camper, unless I find a gotcha somewhere.
Here is what I eventually did. I set a limit on the maximum number of address books (not great but it works) of 4 you can create as many as you want. So I created a couple of sessionScope variable that I created in the after Page Loads event on the XPage. I used this formula.
var allNABs:Array = session.getAddressBooks().iterator();
var pubNABs = new Array;
var privNABs = new Array;
while (allNABs.hasNext()) {
var db:NotesDatabase = allNABs.next();
if (db.isPublicAddressBook()){
pubNABs.push(db.getFilePath())
} else {
privNABs.push(db.getFilePath())
}
db.recycle()
}
sessionScope.put("ssPublicNABs", pubNABs);
sessionScope.put("ssPrivateNABs", privNABs);
because I use several different Name Pickers on the same page I did not want to repeat having to cycle through the Address books.
Then I created 4 NamePicker controls and added 1, 2 , 3 and 4 dominoNABNamePickers providers to each of the successive controls. Then set the rendered property based on the number of public Address books so they would not blow up on me. The db name property on each of the providers is :
var server:String = #Name("[CN]",session.getCurrentDatabase().getServer());
var pubNABs:Array = sessionScope.get("ssPublicNABs");
return server + "!!" + pubNABs[0];
where pubNABs[n] returns the correct filePath for the NAB. It works well in both Notes Client and the Web.
Then to make it not blow up on a local disconnected replica I created 4 more controls and did the same thing but used the privNABs with appropriate rendered properties so that there is no conflict. Seems like the long way around and I'm sure that there is an easier way, but it works.

Resources