Cannot subscribe on slickgrid scroll event - javascript

I'm using slickgrid as container for data, and trying to subscribe on it's onscroll event as of described in documentation, i.e.
task_list.onscroll.subscribe(function(e, args) {
console.log('scrolling occured');
});
Actually, I'm trying to do other processing afterwards, which is translating contents of the web page. The content is not fully translated, so I need to translate each time I scroll the page. However I get the message
Uncaught TypeError: Cannot read properties of undefined (reading 'subscribe')
How can I troubleshoot this error and find out why I get it?

There's a few small errors in your code, first the event names are camelCase so it should be onScroll and second if you want to subscribe to SlickGrid events then you need to use the grid object
grid.onScroll.subscribe(function(e, args) {
// ...
});
and don't forget to unsubscribe when leaving the page because you'll have quite a leak with the onScroll. I prefer to use the Slick EventHandler since it has an easier unsubscribeAll method that I can use when destroying/leaving the page
var eventHandler = new Slick.EventHandler();
var grid = new Slick.Grid("#myGrid", dataView, columns, options);
function something() {
eventHandler.subscribe(grid.onScroll, function(e, args) {
// ...
});
}
function destroy() {
eventHandler.unsubscribeAll();
}
Hopefully there's no error in my code but just to let you know I wrote by memory here so please double-check the code and look at the multiple SlickGrid Examples which all have easy code access

Related

JavaScript Events not adding to the DOM

As an exercise I have to do a little online bike reservation app. This app begins with a header which explains how to use the service. I wanted this tutorial be optional so I wrote a welcome message in HTML and if the user doesn't have a var in his cookies saying he doesn't want to see the tutorial again, the welcome message is replaced by a slider that displays the information.
To achieve that is fetch a JSON file with all the elements I need to build the slider (three divs : the left one with an arrow image inside, the central one where the explanations occur and the right one with another arrow). Furthermore I want to put "click" events on the arrows to display next or previous slide. However, when I do so, only the right arrow event works. I thought of a closure problem since it is the last element to be added to the DOM that keeps its event but tried many things without success. I also tried to add another event to the div that works ("keypress") but only the click seems to work. Can you look at my code give me an hint on what is going on?
Here is the init function of my controller:
init: function() {
var load = this.getCookie();
if(load[0] === ""){
viewHeader.clearCode();
var diapoData = ServiceModule.loadDiapoData("http://localhost/javascript-web-srv/data/diaporama.json");
diapoData.then(
(data) => {
// JSON conversion
modelDiapo.init(data);
// translation into html
controller.initElementHeader(modelDiapo.diapoElt[0]);
controller.hideTuto();
}, (error) => {
console.log('Promise rejected.');
console.log(error);
});
} else {
viewHeader.hideButton();
controller.relaunchTuto();
}
}
There is a closer look at my function translating the JSON elements into HTML and adding events if needed :
initElementHeader: function(data){
data.forEach(element => {
// Creation of the new html element
let newElement = new modelHeader(element);
// render the DOM
viewHeader.init(newElement);
});
}
NewElement is a class creating all I need to insert the HTML, viewHeader.init() updates the DOM with those elements and add events to them if needed.
init: function(objetElt){
// call the render
this.render(objetElt.parentElt, objetElt.element);
// add events
this.addEvent(objetElt);
},
Finally the addEvent function:
addEvent: function(objet){
if(objet.id === "image_fleche_gauche"){
let domEventElt = document.getElementById(objet.id);
domEventElt.addEventListener("click", function(){
// do things
});
}
else if(objet.id === "image_fleche_droite"){
let domEventElt = document.getElementById(objet.id);
domEventElt.addEventListener("click", function(){
// do stuff
});
};
},
I hope being clear enough about my problem. Thank You.
Ok, I found the problem, even if the element was actually created, it somehow stayed in the virtual DOM for some time, when the "getElementById" in "addEvent" was looking for it in the real DOM it didn't find the target and couldn't add the event. This problem didn't occur for the last element since there was nothing else buffering in the virtual DOM.
On conclusion I took out the function adding events out of the forEach loop and created another one after the DOM is updated to add my events.

Detach event handlers selectively

I have a html richText editor. My code structure is like this:
function richTextEditor(div)
{
var self=this;
self.instanceIdentifier=Math.floor(Date.now());
//Richtext editor creation logic
$(document).on('click.'+self.instanceIdentifier,function()
{
//some logic
})
self.destroy=function()
{
//delete all properties of self
// detach all listeners
$(document).off('click.'+self.instanceIdentifier) ;
}
}
Our app is single page application, and there are multiple richtexteditor instances opened in different panes. I need to destroy the instance when the node corresponding to this has been removed. Destroy should remove all the event handlers attached by that instance.
So far Date.now() for uniquely identifying the handler is working but I think there must be some elegant way to do that.
var div1=$('#notes')[0];
var editorInstance1=new richTextEditor(div1);
//remove is not a valid jquery event, its just for illustration
// I am getting remove event from another library
$(div1).on('remove',function(){
editorInstance1.destroy();
})
Please suggest if this is the correct way to go.
What you want is a GUID or UUID. There is a great answer to this question here.

Telerik Kendo UI grid loses custom command event handler after persisting (and restoring) its state

I have isolated the issue, see and try the full source here.
Steps to reproduce:
Press Ctrl+Enter to run the snippet
Click on 'Say Hello' custom command button, and check if the event
handler runs
Click on top left 'Save State' button
Click on 'Load State' button, and restore the previous state.
Now click again on 'Say Hello' button and demonstrate the event handle will not run, instead something weird is happening.
Notes: Please do not search for the solution around the localStorage. The issue can be reproduced by using different server side state persisting solution. (as my original app does)
Any idea where to patch? ... or workaround?
Hopefully this will help you out.
http://dojo.telerik.com/EDUCO/4
I have added the following piece of code for you:
dataBound: function (e) {
$(".k-grid-SayHello").on('click', function (a) {
console.log(e);
a.preventDefault();
alert('Hello');
});
},
When the rebind occurs I suspect that it is losing the connection to the event handler so all I have done if looked for the button based on it's class name and reattached it.
Obviously you can adapt the solution to meet your needs but this is something I do for my projects when I need to "invoke" custom actions on buttons/ dynamically create things on the fly.
Any issues let me know.
To keep function references after calling grid.setOptions()
I added the function references back to the deserialized configuration object before passing it to the setOptions method.
( http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#methods-setOptions )
$(document).ready(function () {
var grid = $("#myGrid").data("kendoGrid");
var originalOptions = grid.getOptions();
var savedOptions = JSON.parse(localStorage["myGrid-options"]);
if (savedOptions) {
var detaylarFunc = originalOptions.columns[3].command[0].click;
savedOptions.columns[3].command[0].click = detaylarFunc;
grid.setOptions(savedOptions);
} else {
grid.dataSource.read();
}
});
//Custom command
function Detaylar(e) {
e.preventDefault();
var grid = $("#myGrid").data("kendoGrid");
options = grid.getOptions();
localStorage["myGrid-options"] = kendo.stringify(grid.getOptions());
}

Event listeners won't be called in IE -- what's wrong here?

Technical context:
dojo 1.8.1
dgrid 0.3.4-pre
IE 10.0.9200
Short version:
I have some dojo/on events I'm listening too (from _WidgetBase), but they'll sometimes get called and sometimes don't. dgrid, pagination and IE are in the mix. What could be the problem?
Details:
I have this weird situation with a dgrid grid, and as much as I've tried, I have not been able to isolate the actual cause of the issue. I'll be as thorough as I can, but feel free to ask for more information.
I have a dgrid component that's using pagination and a combo box that has some values on which I will filter by. This is pretty much how it is set up (simplified, actual code references other modules and has stuff more modularized):
// GridContainerWidget
var CustomGrid = declare([Grid, CompoundColumns, Selection, Keyboard, Pagination], {
selectionMode: "single",
rowsPerPage: 20
});
var grid = new CustomGrid({
deselectOnRefresh: false
}, domContainer);
The grid is later on bound to a JsonStore.
My filter is set up in the following way:
// SearchBarWidget
// inside a custom widget, inheriting from _WidgetBase
var self = this;
var statusCombo = new ComboBox({
store: new Memory(/* data and labels */),
onChange: function (selection) {
self.emit("status_changed", self.getSomeData());
}
}, comboDomContainer);
And back to the widget that encapsulates both the filter and the grid:
// GenericListWidget, contains both the SearchBarWidget and the GridContainerWidget
var self = this;
this._searchToolbar.on("status_changed", function (data) {
// ... some "calibrations" ...
self._grid.set("query", { newCriteria: "something" });
});
This is where it gets weird:
Sometimes in IE emit("status_changed") will be called but the callback on("status_changed") won't be called. Some other times, emit will be called and the callback will be called too (expected).
This has to do with the pagination or the grid refresh somehow, but I've not been able to isolate the exact same steps that reproduce the issue
In digging deeper into this, I've seen IE reaches the point where it executes the following: (dojo/on, lines 314 to 322)
var nativeEvent = target.ownerDocument.createEvent("HTMLEvents");
nativeEvent.initEvent(type /* "status_changed" */, !!event.bubbles /* true */, !!event.cancelable /* true */);
// ... copies properties ...
return target.dispatchEvent(nativeEvent) && nativeEvent; // returns true
I verified that the remove() call for the on hook is never being called
I verified that the DOM element on which events are being triggered and listened onto are actually the same, every time
My question is: how can I find the underlying issue and make sure that my on() callback gets called every time?
You are running into https://github.com/SitePen/dgrid/issues/379 which was fixed in dgrid 0.3.7. To resolve the issue as it pertains to the paging controls in the Pagination extension, you will either need to update your version of dgrid or apply the changeset yourself.
This is due to a rather ridiculous and annoying IE bug present in IE9 and IE10 (fixed in IE11):
https://connect.microsoft.com/IE/feedback/details/799780/ie10-addeventlistener-function-is-fired-by-a-different-event
https://connect.microsoft.com/IE/feedback/details/802397/ie9-ie10-events-can-be-sent-to-the-wrong-listeners

Chrome/jQuery Uncaught RangeError: Maximum call stack size exceeded

I am getting the error "Uncaught RangeError: Maximum call stack size exceeded" on chrome. here is my jQuery function
$('td').click(function () {
if ($(this).context.id != null && $(this).context.id != '') {
foo($('#docId').val(), $(this).attr('id'));
}
return false;
});
Note that there are tens of thousands of cells in the page. However, I generally associate stack overflows with recursion and in this case as far as I can see there is none.
Does creating a lambda like this automatically generate a load of stuff on the stack? is there any way round it?
At the moment the only workaround I have is to generate the onclick events explicitly on each cell when rendering the HTML, which makes the HTML much larger.
As "there are tens of thousands of cells in the page" binding the click-event to every single cell will cause a terrible performance problem. There's a better way to do this, that is binding a click event to the body & then finding out if the cell element was the target of the click. Like this:
$('body').click(function(e){
var Elem = e.target;
if (Elem.nodeName=='td'){
//.... your business goes here....
// remember to replace $(this) with $(Elem)
}
})
This method will not only do your task with native "td" tag but also with later appended "td". I think you'll be interested in this article about event binding & delegate
Or you can simply use the ".on()" method of jQuery with the same effect:
$('body').on('click', 'td', function(){
...
});
You can also get this error when you have an infinite loop. Make sure that you don't have any unending, recursive self references.
Mine was more of a mistake, what happened was loop click(i guess) basically by clicking on the login the parent was also clicked which ended up causing Maximum call stack size exceeded.
$('.clickhere').click(function(){
$('.login').click();
});
<li class="clickhere">
login
</li>
This problem happened with me when I used jQUery Fancybox inside a website with many others jQuery plugins.
When I used the LightBox (site here) instead of Fancybox, the problem is gone.
U can use
$(document).on('click','p.class',function(e){
e.preventDefault();
//Code
});
I recently just ran into this issue as well. I had a very large table in the dialog div. It was >15,000 rows. When the .empty() was called on the dialog div, I was getting the error above.
I found a round-about solution where before I call cleaning the dialog box, I would remove every other row from the very large table, then call the .empty(). It seemed to have worked though. It seems that my old version of JQuery can't handle such large elements.
I was getting this error because of my mistake that I forgot to declare one of the variable which was passed in Ajax data.Only mode was declaredat first.
data: {
tmp_id: tmp_id,
mode: mode
}
Declared the tmp_id variable also and it worked fine.
let tmp_id=$("#tmp_id").val();
let mode=$("#mode").val();
$.ajax({
url: 'my-url',
method: 'post',
data: {
tmp_id: tmp_id,
mode: mode
}
dataType: 'json',
success: function(response) {
console.log(response);
}
});
}
In My case I was html element insted of value
|
|
var uname=$("#uname");<-
let data={
uid:uid,
.....
};
$.post("url",data,(responseText)=>{
..
}).fail((xhr)=>{
..
});
then I updated
|
|
var uname=$("#uname").val()<-

Categories