Facing issue in sessionStorage Proxy implementation in Ext JS Grid view - javascript

I just created a Sencha fiddle wherein I have one panel with two grid views inside it. Both Grid views facilitates item selection from left to right and vice-versa. I'm trying to show the selected item from left grid view into right grid view. I'm using sessionStorage proxy to hold data while moving items from left to right grid view. I have to use sessionStorage because my requirement is to persist this selection across the pages.
Sencha fiddle link : https://fiddle.sencha.com/#view/editor&fiddle/2j7u
Although, I'm not getting any error but my implementation is not working. Even the console logs show the correct selection data. But still I'm unable to populate the right grid view.
One thing I noticed is that in browser debugger under Applcation -> SessionStorage, my sessionStorage object is always null. Don't know why but on console it shows the data.
Console logs from fiddle
sessionStorage value from debugger
Any pointers would be highly appreciated!
On a side note, the same implementation was working fine with Ext JS 4.2. But I'm facing issue while migrating to Ext JS 6.5
Thanks,
Dhiraj
Further troubleshooting:
Further, I have updated the same fiddle and was successful to make it work further, by commenting out 'suspendEvents' and 'resumeEvents' for my right grid 'store' --> store2 and 'sessionStore' --> sessionStore2 in tropos.selectDevices.addToSelect method. Along-with this I figured out that line 'store2.loadPage(1)' in tropos.selectDevices.updateGridViews method was clearing my grid on loading. I tried to avoid that using 'clearOnPageLoad' config setting for store to false. But it DIDN'T work so I commented this line to make it work. Now, although, it works but my main requirement of PRESERVING user selection is still not met because sessionStorage is still not working.
Updated fiddle: https://fiddle.sencha.com/#view/editor&fiddle/2j7u
Thanks,
Dhiraj

Try this code in your addToSelect :
example.selectDevices.addToSelect = function(storeObj){
var addRecs = [], newRecs = [],
store2 = Ext.getCmp('grid2').getStore();
//********************
//I just comment all *sessionStore2* references because is redundand,
//store2 is the same as sessionStore2
//********************
//sessionStore2 = Ext.data.StoreManager.lookup('currentlySelectedDevices');
//store2.suspendEvents();
//sessionStore2.suspendEvents();
Ext.each(storeObj,function(record){
var rec = record.copy();
rec.phantom = true;
addRecs.push(rec);
newRecs.push(record.data.hid);
});
example.selectDevices.selectedDeviceIds = example.selectDevices.selectedDeviceIds.concat(newRecs);
store2.add(addRecs);
//store2.commitChanges();
for(i=0; i < store2.data.items.length; i++) {
console.log("addToSelect: Selected Device Serial [" + i + "] from STORE_2: " + store2.data.items[i].data.hid);
}
//sessionStore2.add(addRecs);
//for(j=0; j < sessionStore2.data.items.length; j++) {
// console.log("addToSelect: Selected Device Serial [" + j + "] from SESSION_STORAGE_2: " + sessionStore2.data.items[j].data.hid);
//}
//sessionStore2.sync();
store2.sync();
//sessionStore2.resumeEvents();
example.selectDevices.updateGridViews();
};
EDIT: You have to mark the record as phantom = true in order the sync work properly

Related

Ag-grid: duplicate node id 107 detected from getRowNodeId callback , this could cause issues in your grid

I am going to do live data streaming on ag-grid datatable, so I used DeltaRowData for gridOptions and added getRowNodeId method as well which return unique value 'id'.
After all, I got a live update result on my grid table within some period I set, but some rows are duplicated so I can notice total count is a bit increased each time it loads updated data. The question title is warning message from browser console, I got bunch of these messages with different id number. Actually it is supposed not to do this from below docs. This is supposed to detect dups and smartly added new ones if not exist. Ofc, there are several ways to get refreshed data live, but I chose this one, since it says it helps to persist grid info like selected rows, current position of scroll on the grid etc. I am using vanilla js, not going to use any frameworks.
How do I make live data updated periodically without changing any current grid stuff? There is no error on the code, so do not try to speak about any bug. Maybe I am wrong with current implementation, Anyway, I want to know the idea or hear any implementation experience on this.
let gridOptions = {
....
deltaRowDataMode: true,
getRowNodeId = (data) => {
return data.id; // return the property you want set as the id.
}
}
fetch(loadUrl).then((res) => {
return res.json()
}).then((data) => {
gridOptions.api.setRowData(data);
})
...
If you get:
duplicated node warning
it means your getRowNodeId() has 1 value for 2 different rows.
here is part from source:
if (this.allNodesMap[node.id]) {
console.warn("ag-grid: duplicate node id '" + node.id + "' detected from getRowNodeId callback, this could cause issues in your grid.");
}
so try to check your data again.
if u 100% sure there is an error not related with your data - cut oof the private data, create a plinkr/stackblitz examples to reproduce your issue and then it would be simpler to check and help you.

Angular Material Paginator not allowing back button to be pressed after retrieving data

I'm having an issue when using the material paginator. It retrieves the data correctly and the paginator data is updating correctly specifically the pageIndex is incrementing correctly but the items number does not update as shown below. I believe this is because of the onChangedPage($event) function because when I remove it everything works correctly but my data is of course not updated then.
screen shot of the item count
I'm wondering what could be causing this to not work considering the pageIndex is working correctly here is my code for the paginator. My code is dynamic.
html:
<mat-paginator
[length]="totalMessages"
[pageSize]="messagesPerPage"
[pageSizeOptions]="pageSizeOptions"
(page)='onChangedPage($event)'
></mat-paginator>
TS:
onChangedPage(pageData: PageEvent) {
console.log(pageData);
this.currentPage = pageData.pageIndex + 1;
const endingIndex = this.messagesPerPage * this.currentPage;
const startingIndex = endingIndex - this.messagesPerPage;
this.isLoading = true;
console.log(endingIndex);
console.log(startingIndex);
this.Service
.getFunction(this..ticketNumber, startingIndex, endingIndex)
.subscribe(data => {
****taken out for security reasons
}
Summary: Essentially I am paginating over an embedded array in a Mongo DB document and using the $slice method. My backend logic is fine I'm retrieving everything correctly but for some reason the paginator is not updating the position of the items I'm retrieving. Any help would be greatly appreciated thank you!
If anyone runs into this type of issue. I figured out the issue was because I was using a loading spinner during my call to the back-end for data. This changed the view and reset the page data. Once I removed the spinner it now works as expected.

multiple kendo grids using one script

I'm loading multiple partial views into the same cshtml page. All goes well until they need to use the scripts. As i'm using code like
var grid = $("#grid").data("kendoGrid");
var selected = grid.selected();
This code works fine with one grid, but starts showing issues when multiple grids are in place. The problem is that "#grid" is a reference to the name of the kendo grid. Is there a way to make this dynamic so it can be used by multiple grids?
I think the same problem would occur when there are multiple grids in the same page as it can't distinct what grid to refer to. Giving the grids different id's would work, but then the code in the script will return an undefined error on grid.selected().
Update:
So the solution of using
var grid = $(".k-grid").data("kendoGrid");
works to a certain point. It loads the data into the grid, but fails to do anything else. For example a part of my code for enabling an update and delete button doesn't work on the 2nd and 3rd partial view.
var grid = $(".k-grid").data("kendoGrid");
var selected = grid.select();
if (selected.length > 0) {
$("#btnCopy,#btnEdit,#btnDelete").removeClass("k-state-disabled");
} else {
$("#btnCopy,#btnEdit,#btnDelete").addClass("k-state-disabled");
}
Somehow the code only starts working for grid 2 and 3 after i have selected a row on grid 1, which is not as intended.
Instead of id(#Grid) you can use class(.k-grid):
var grid = $(".k-grid").data("kendoGrid");
The solution I found with help of a senior programmer is to save the grid data into a global variable like this.
var PartialGridData = PartialGridData || {};
After that I'm setting and changing the variable whenever changing the partial view.
PartialGridData.selectedGrid = $("#PartialGrid1").data("kendoGrid");
Where the name #PartialGrid1 is the name of the current grid.
This means I need to write this code as many times as I have grids, but it also fixes a lot of problems. After that I use it to select the correct data.
var grid = PartialGridData.selectedGrid;
var selected = grid.select();
if (selected.length > 0) {
$("#btnCopy,#btnEdit,#btnDelete").removeClass("k-state-disabled");
} else {
$("#btnCopy,#btnEdit,#btnDelete").addClass("k-state-disabled");
}
Another option would be to use e.sender.
function onRowSelect(e) {
var grid = e.sender;
var selected = grid.select();
if (selected.length > 0) {
$("#btnCopy,#btnEdit,#btnDelete").removeClass("k-state-disabled");
} else {
$("#btnCopy,#btnEdit,#btnDelete").addClass("k-state-disabled");
}
}
Both solutions have their drawbacks though. Not all methods get the variable e used for e.sender and changing partial views in a way that is not caught will cause the global variable not to be updated, so this has to be kept in check.

How can I make Qooxdoo virtual list scalable?

I need to show list of data , at least 1 million rows (Big data , machine learning).
I do not need to show at once , remotetablemodel of qooxdoo table works fine but instead of table i choose list as design choice.
Below is a test i've made.
//create the model data, 1mil items
var rawData = [];
for (var i = 0; i < 1000000; i++) {
rawData[i] = "Item No " + i;
}
var model = new qx.data.Array(rawData);
//create the list
var list = new qx.ui.list.List(model);
this.getRoot().add(list);
I understand the point that it will take long to generate rawdata and assign it to list.
But the problem is after assigning the list , the virtual list itself is almost non-responsive.
Scrolling is very slow , navigating by down arrow freezes a few secs too.
Qooxdoo virtual infrastructure is suppose to render only visible items if i understand correctly? But in above test case it is so slow.
I expect to work like remote table model .
Tested with qooxdoo latest 4.0.0 and 3.5.1 , on Chrome 35 stable.
I can reproduce you issue only with the source version and not with the build version. I found the reason why the performance is so slow. There is an runtime check in an internal method from the SingleValueBinding which has a huge performance impact on the rendering.
I opened a bug report for that:
http://bugzilla.qooxdoo.org/show_bug.cgi?id=8439
But as I sad this issue only occurs with your developer version. So your customers are not effected.
You can disable the check if you want. Just remove the check block:
https://github.com/qooxdoo/qooxdoo/blob/master/framework/source/class/qx/data/SingleValueBinding.js#L915
You can also load your model data in parts to improve the model creation. You can maybe load the next part when the user has scrolled to the end of the list. You can use the example you have already seen:
Infinite scroll in qooxdoo with virtual list

backbone.js and local storage with multiple browser tabs / windows overwrites data

just a very short question on using Backbone.js with LocalStorage:
I'm storing a list of things (Backbone collection) in LocalStorage. When my website is open in multiple browser windows / tabs and the user in both windows adds something to the list, one window's changes will overwrite the changes made in the other window.
If you want to try for yourself, just use the example Backbone.js Todo app:
Open http://backbonejs.org/examples/todos/index.html in two browser tabs
Add an item 'item1' in the first tab and 'item2' in the second tab
Refresh both tabs: 'item1' will disappear and you'll be left with 'item2' only
Any suggestions how to prevent this from happening, any standard way to deal with this?
Thxx
The issue is well-known concurrency lost updates problem, see Lost update in Concurrency control?.
Just for your understanding I might propose the following quick and dirty fix, file backbone-localstorage.js, Store.prototype.save:
save: function() {
// reread data right before writing
var store = localStorage.getItem(this.name);
var data = (store && JSON.parse(store)) || {};
// we may choose what is overwritten with what here
_.extend(this.data, data);
localStorage.setItem(this.name, JSON.stringify(this.data));
}
For the latest Github version of Backbone localStorage, I think this should look like this:
save: function() {
var store = this.localStorage().getItem(this.name);
var records = (store && store.split(",")) || [];
var all = _.union(records, this.records);
this.localStorage().setItem(this.name, all.join(","));
}
You may want to use sessionStorage instead.
See http://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage.
Yaroslav's comment about checking for changes before persisting new ones is one solution but my suggestion would be different. Remember that localStorage is capable of firing events when it performs actions that change the data it holds. Bind to those events and have each tab listen for those changes and view re-render after it happens.
Then, when I make deletions or additions in one tab and move over to the next, it will get an event and change to reflect what happened in the other tab. There won't be weird discrepancies in what I'm seeing tab to tab.
You will want to give some thought to making sure that I don't lose something I was in the middle of adding (say I start typing a new entry for my to-do list), switch to another tab and delete something, and then come back I want to see the entry disappear but my partially typed new item should still be available for me.

Categories