KendoUI grid does not fire saveChanges event - javascript

I have a problem with events in KendoUI grid control. I assigned "saveChanges" event after grid initialization. I use popup for data editing. I want to fire event "saveChanges" when the user pushes "Save" button. Unfortunately the event is not fired. I can't figure out what is the problem, moreover, other events work. The grid is initialized within MVC helpers. Events are assigned in JavaScript.
Here is the JavaScript code that I'm using:
function bindGridEvents() {
var that = this;
//kendoGrid is an abbreviation of: $("#grid").data("kendoGrid")
kendoGrid.bind("dataBound", function () { }); // works
kendoGrid.bind("edit", function (event) { }); // works
kendoGrid.dataSource.bind("error", function (event) {}); // works
kendoGrid.bind("saveChanges", function (event) { console.log("This event is not fired!"); });
kendoGrid.bind("save", function (event) { }); // works
}
I've already spent a lot of time for finding the solution on my own without success. I will appreciate any help.
EDIT:
I have found what the problem was. Documentation says:
saveChanges event is fired when the user clicks the "save" command
button.
But when the popup shows the command with label "Save" is of type "update". That is why it does not work in edit mode. It works in toolbar only. It's not obvious at first and the documention don't say too much so be aware of that.

Without seeing the code I can't be sure. The event will not fire without you doing any changes I believe. Nice example which works for me is here. If you dealing with the actual dataItem edit not via the grid features, make sure you mark the item as "dirty". Ideally post your code as JsFiddle or JSBin.

Related

Javascript click event listener fires only once

I have a Chrome extension that intercepts and checks tweets before they get posted. To do this, I've add an event listener to the Tweet button. Sine the content is dynamic, I use the solution proposed in this thread:
initialize : function() {
let that = this;
let jsInitChecktimer = setInterval(checkForJsFinished, 111);
function checkForJsFinished () {
if (document.querySelector("div[data-testid='tweetButtonInline']")) {
clearInterval (jsInitChecktimer);
console.log("Button found");
that.addSubmitNewTweetClickHandler();
}
}
},
addSubmitNewTweetClickHandler : function() {
let that = this;
let buttonSubmitTweet = document.querySelector("div[data-testid='tweetButtonInline']");
buttonSubmitTweet.addEventListener('click', function(e) {
console.log("CLICK");
// Stop default event from happening
e.preventDefault();
e.stopImmediatePropagation();
// Do stuff
});
},
If the tweet passed the checks alright, it gets submitted by programmatically triggering the event using .trigger('click').
This works fine, but only once. After a tweet has been submitted and posted, the event listener on the Tweet button is gone, and I cannot intercept the next tweet to check it. I've tried calling initialize() after submitted again -- maybe the button gets removed and newly added to the DOM (it actually disappears fire a moment when submitting a tweet) -- but the querySelector finds the button immediately. But even after calling initialize() again, no click even on the Tweet button fires.
What could be the issue here? My problem is that I don't even know where to look for and how to debug this.
After many more hours, I've finally figured it out. The problem was essentially the highly dynamic content of the new Twitter website. After submitting a tweet, the Tweet button gets indeed removed and added again. In needed to do a serious of changes:
Use a MutationObserver to keep track of any changes. Every time there's a change, call the initialize() function. To avoid too many calls, I do this in case of certain changes (unnecessary detail here)
Change the addSubmitNewTweetClickHandler() method so that the event listener first gets removed in order to avoid duplicate listeners (please note that I use objects hence the use of this compared to my original question)
addSubmitNewTweetClickHandler : function() {
let that = this;
let buttonSubmitTweet = document.querySelector("div[data-testid='tweetButtonInline']");
buttonSubmitTweet.removeEventListener('click', this.handleSubmitNewTweetClick );
this.handleSubmitNewTweetClick = this.handleSubmitNewTweetClick.bind(this)
buttonSubmitTweet.addEventListener('click', this.handleSubmitNewTweetClick );
},
This change required to create the reference function handleSubmitNewTweetClick
Overall, it's still not a perfect solution since I call initialize() many unnecessary time. However, I failed to reliably identify when the Tweet button was added to the document. When I used the MutationObserver none of the added nodes had the attribute data-testid which I need to identify the correct button. I have node idea why this attribute was not there. Maybe the attribute is added some times after added to button, but even with an additional MutationObserver looking for attribute changes I could detect this.
Anyway, it works now and it's only for a prototype.

How do I debug issues with an event handler added to the window object in Firefox?

I'm working on some code where I want send custom events to the window object where I have an event listener that will perform an action. This works fine for one of the listeners, but I have a second one I want to use, but it's not registering all the time. Is there a way to debug this as the javascript console isn't very helpful? Or, is there a way to detect if the event listener has been added to the window object using Javascript? If I look at the HTML element in the inspector, I can see if the event is attached or not manually.
My code looks something like this:
$.when($.ready).then(function () {
// Set up the event listener to capture search terms.
window.addEventListener('search_terms', function(evt) {
saveSearchTerms(evt.detail);
});
window.addEventListener('profile-update', function(evt) {
console.debug('got the event');
console.debug(evt.detail);
updateProfile(evt.detail);
});
});
The firt one works fine. It's the second one that's giving me issues.
Thanks.

KendoUI Combobox Mouse Events

Im trying to catch the oncontextmenu and onmousedown events of a control that is a kendoUI combobox.
I've created (modified existing) a Jsfiddle that shows an example of what we are trying to achieve.
Jsfiddle
document.getElementById("cbo1").oncontextmenu = function(ev){
alert(ev);
return false;
};
document.getElementById("cbo1").onmousedown = function(ev){
alert(ev);
};
You can see that the mouse down and the context menu items are not firing for the comboBox input but they are firing fine for the standard input.
Any ideas on how i can get the mouse events firing for the combobox input?
This question is similar to this, except you want a click and oncontext event for kendo combobox which is a non registered event and that is not posible using jquery alone since kendo UI doesn't expose it to jQuery refer to this kendo forum post.
To summary the answer, you can to this by modifying the answer form above question, dont forget move your return false otherwise the right click options will appear.
$(element.input).bind("contextmenu", function (e) {
binding.get();
return false
});
refer to this jsfiddle
This is how I did it...
var $parent = $(element.input).closest('.k-combobox')
$parent.on({ 'mouseenter': function(){ }, 'mouseleave': function(){ } });
Works just fine.
EXPLANATION:
You can't put the event (directly) onto the Element.Input or onto the control (itself). But you're using jQuery...so you can find the control-container & put the event on that...and voila!
For those that need visuals..

Codemirror autocomplete addon event binding

Does anyone know how to bind "shown", "select", and "close" event to the completion object of show hint addon of codemirror? The reason I want to bind those event because I want to auto position the completion list. somehow, the list is off the window when the cursor is at really bottom of the page. but when I looked at the completion demo on the codemirror site. it does not have this issue and it is auto positioned. please help, thanks
Here is the document from codemirror site. it is not really clear that how it works. and there is no example or demo like jQuery doc.
The following events will be fired on the completions object during completion:
"shown" ()
Fired when the pop-up is shown.
"select" (completion, Element)
Fired when a completion is selected. Passed the completion value (string or object) and the DOM node that represents it in the menu.
"close" ()
Fired when the completion is finished.
This addon depends styles from addon/hint/show-hint.css. Check out the demo for an example.
ok, I have solved the problem myself by reading, comparing and debuging CodeMirror Source. and I think it is a mistake of CodeMirror. Basically, there is a line in the show-hint.js of download version which is different in the demo linked file.
You need to move the code below the line 169 and above the "var box" initialization. so that the "var box" can get the correct number after calling getBoundingClientRect(). Hopefully they can fix this problem soon than later.
(options.container || document.body).appendChild(hints);
I am not sure to understand your answer but I had the same problem. The "pick" signal (and other completion signals) seem to be emitted against the "data" and not the "editor" object.
Here is a simple way to subscribe to the "pick" event for example:
var completion = cm.state.completionActive;
console.log('handling the completion object:', completion);
var pick = completion.pick;
completion.pick = function (data, i) {
var completion = data.list[i];
console.log('picked', data, completion);
pick.apply(this, arguments);
}

Can jQuery click events be unbound or reset?

I've discovered a resource leak on a webpage I'm working on.
This webpage has two textfields, that upon click show a modal dialog, perform a data request to the backend, and then present that information in a table that the user can select an entry from for use in the textbox they originally clicked.
I'm binding the click events to the textboxes like so:
var $field = $('#one-of-the-text-fields');
$field.click(function () {
App.DialogClass.show();
App.DialogClass.PopulateTable();
App.DialogClass.GotoPageButtonAction(actionArgs); // Offender!
});
...Which calls...
App.DialogClass = (function($) {
var pub {},
$gotoPage = $('#pageNumberNavigationField'),
$gotoPageButton = $('#pageNumberNavigationButton');
// ...SNIP unimportant other details...
pub.GotoPageButtonAction = function (args) {
$gotoPageButton.click(function () {
var pageNumber = $gotoPage.val();
pub.PopulateTable(args); // Breakpoint inserted here...
});
};
return pub;
})(jQuery);
I noticed the leak because when I ran through using Chrome's JavaScript debugger, I'm always having one extra breakpoint hit every time I click a different button (e.g. the first time I click field A, the breakpoint is hit twice. When I hit field B after that, the break point is hit three times. If I click A after that, the breakpoint is hit four times. Extrapolate as necessary.)
Nowhere in my code am I doing anything about an existing click event for a given field. I suspect my leak stems from the fact that the events are not getting cleaned up. That being said, I am also not terribly familiar with JavaScript/jQuery. What are some techniques for removing click events from a control?
Sure. Just unbind them:
$field.unbind('click');
However, bear in mind that this will remove all event handlers for click, not just yours. For safety, you should use namespaces when binding handlers:
$field.bind('click.mynamespace', function(){
// do something
});
Then,
$field.unbind('click.mynamespace');
So, then, only your handler will be removed.
If you have used .bind() to bind them .unbind() removes the events
If you have used .on() to bind them .off() removes the events
JQuery offers the unbind function to unbind event listeners.
Note that you may also do it in vanilla JS using removeEventListener.
But instead of unbinding, you probably should not bind each time in GotoPageButtonAction : once is enough.

Categories

Resources