Codemirror autocomplete addon event binding - javascript

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);
}

Related

KendoUI grid does not fire saveChanges event

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.

Multiple click events for the same element?

Is it possible to have multiple click events for the same element? I have tried to simply have it like so:
$('#templates').click(function(e) {
do something..
});
$('#templates').click(function(e) {
do something else also..
});
Yet only the second event fires. I cannot find any decent answers explaining how to do this for a singular element in an on-click?
Note: the first click event calls server-side and loads a new PHP template (this may have an effect on what I can use in the second call I guess, as individually both clicks work but the server call does not work if I try a second click for the same element)
$('#templates').click(function(e) {
functionOne();
functionTwo();
});
function functionOne(){
}
function functionTwo(){
}
perhaps?
Please check this fiddle:
http://jsfiddle.net/DqSSd/
As you can see it should work well.
So please provide more information, and it would be better, if you provide JS fiddle as well.
Because so far the problem might be in:
second event is fired before first event returns the result
first event returns error from the server
some of events contains syntax error
etc
You may check something of those with investigation of NET calls to server (with Firebug or Chrome Developer toolbar).
Also for testing purposes you can type in console $('#templates').data("events"), so you will be able to see all events and handlers for particular element.

How can I see the event that is attached to an html element?

I am a new programmer and still learning.
This is the code that I am trying to figure out:
<div id="buy" class="buy button">Buy</div>
When I click on the div (button), some JavaScript code is executed but I don't know were it is. How can I tell what function is fired when click happens? Some how a listener is attached to this element.
In Google chrome's developer tools (click the wrench icon >Tools>Developer tools), select the element in the Elements tab, on the right open the 'Event Listeners' panel you'll will see all events
If you use Firefox and Firebug you can try installing FireQuery. It will make it so you can see the handlers bound by jQuery. http://firequery.binaryage.com/
You can't do it in a really good manner by "just" using ECMAscript itself. For instance, if there was a click event handler added by DOM Level 1 in the form of
document.getElementById('buy').onclick = function() {};
you can of course easily intercept that property on the node itself. Things are getting more complicated if DOM Level 2 comes into play with .addEventListener() respectevily .attachEvent(). Now you don't really have a "place" to look for where all the different listener functions where bound from.
It gets better by using jQuery. jQuery will hold all it's event handler functions in a special object which is linked to the DOM node of invocation. You can check for that by getting the .data()-expando property for a node like
$('#buy').data('events');
However, now I already described three different ways of binding event listeners to a node (actually its two because a library like jQuery also uses DOM Level 1 or 2 methods of course).
It's really getting ugly if an event is triggerd by delegation. That means, we bound our click event on some parent-node just waiting for that event bubbling up to us so we can check the target. So now we don't even have a direct relationship between the node and the event listener.
Conclusion here is, lookout of a browser plugin or probably a thing like VisualEvent.
You may use "Visual Event 2" script as a bookmark or same script as Chrome extension.
This script shows all js events attached to dom-elements.
Use jQuery("#buy").data('events');
http://api.jquery.com/jQuery.data/ may be interesting.
Event handlers attached using traditional element.onclick= handler or HTML <element onclick="handler"> can be retrieved trivially from the element.onclick property from script or in-debugger.
Event handlers attached using DOM Level 2 Events addEventListener methods and IE's attachEvent cannot currently be retrieved from script at all. DOM Level 3 once proposed element.eventListenerList to get all listeners, but it is unclear whether this will make it to the final specification. There is no implementation in any browser today.
If you're using FireFox, you should have FireBug installed. Once you have that, you can install FireQuery, which will show you what jQuery events are bound to which objects.
http://getfirebug.com/
http://firequery.binaryage.com/
This is the easiest way I've found of how to do it:
http://www.sprymedia.co.uk/article/Visual+Event
When working with events in Javascript, it is often easy to lose track
of what events are subscribed where. This is particularly true if you
are using a large number of events, which is typical in a modern
interface employing progressive enhancement. Javascript libraries also
add another degree of complexity to listeners from a technical point
of view, while from a developers point of view they of course can make
life much easier! But when things go wrong it can be difficult to
trace down why this might be.
It is due to this I've put together a Javascript bookmarklet called
Visual Event which visually shows the elements on a page that have
events subscribed to them, what those events are and the function that
the event would run when triggered. This is primarily intended to
assist debugging, but it can also be very interesting and informative
to see the subscribed events on other pages.
There's a bookmark button there you can drag to your toolbar (FF or Chrome), then just click the button on any page where you want to see the events attached. Works great! (at least for events attached by jQuery or other libraries).
Are you using jQuery? If so, you want to search for one of these three lines of code:
$("#buy").click //the div is refered by its id
or
$(".buy").click //the div is refered to by the style "buy"
or
$(".button").click //refered to by the style "button"
Most newer browsers have "Developer Tools" built into them by pressing F12 (at least in IE and Chrome). That may help you do some further debugging and tracing.
Below is something I’ve used in the past that I think may be what you're looking for. What this does is watch a property on a page element (In the example below, it's the document's "Title" property) and then display an alert with the JS callstack whenever that property is changed. You’ll need to get this into the DOM before whatever code you're trying to find fires, but hopefully you’ll be able to identify what’s causing the problem.
I would recommend using Firefox and getting Firebug for JavaScript debugging.
// Call stack code
function showCallStack() {
var f=showCallStack,result="Call stack:\n";
while((f=f.caller)!==null) {
var sFunctionName = f.toString().match(/^function (\w+)\(/)
sFunctionName = (sFunctionName) ? sFunctionName[1] : 'anonymous function';
result += sFunctionName;
result += getArguments(f.toString(), f.arguments);
result += "\n";
}
alert(result);
}
function getArguments(sFunction, a) {
var i = sFunction.indexOf(' ');
var ii = sFunction.indexOf('(');
var iii = sFunction.indexOf(')');
var aArgs = sFunction.substr(ii+1, iii-ii-1).split(',')
var sArgs = '';
for(var i=0; i<a.length; i++) {
var q = ('string' == typeof a[i]) ? '"' : '';
sArgs+=((i>0) ? ', ' : '')+(typeof a[i])+' '+aArgs[i]+':'+q+a[i]+q+'';
}
return '('+sArgs+')';
}
var watchTitle = function(id, oldval, newval) { showCallStack(); }
// !! This is all you should need to update, setting it to whatever you want to watch.
document.watch("title", watchTitle);
Right-click page, and choose to view the page's source
Find <script> tags
Look for $("#buy") and something mentioning onClick or .on("click",function(){...});
If you can't find it, search for something along these lines: document.getElementById("buy")
You have found the function, or code, where the event handler code is
$("#buy") is JQuery's way of saying find an element that has an id attribute of buy and if it has a . following it with some function, that function is acting upon the element that was found by JQuery.

Should changes to the value of a SELECT control made in code trigger the onChange Event?

I'm using the following code to watch for changes to a given SELECT element.
someSelectElement.change(function () { alert('change made'); });
And it works peachy when I change the value the selected item through the UI.
However, It doesn't seem to trigger the event if the value is changed via a script. For example, the following code executed in the debugging console changes the selected item, but does NOT fire the event.
$('#someSelectElement').val('NewValue')
I know it seems unusual to need to detect changes made to the control by the other code, and if it was my code I'd just manually trigger the event and call it a day. The trouble is, I am writing a jQuery plug-in that needs to do something when the value of a watched control changes whether it be through user intervention or some client-side script that the user of my plug-in is running.
I'm assuming the behavior of not triggering events in this situation is by design. If not, please speak up and let me know what I'm doing wrong. If so, is there a workaround where I can watch for changes made to the value of a SELECT element regardless of whether they were user or code initiated?
Code-driven changes to element values don't trigger native events. You can always trigger them yourself, of course, via the jQuery ".trigger()" method.
The Mozilla browsers have long had a "watch" feature, but that's not supported by other platforms.
Okay - so I might have a better solution to this than the interval timer solution.
Also note that this is a MUCH larger hack and the following is simply proof of concept and by no means is production-ready:
$(document).ready(function(){
function change(){
$('#test option[value=3]').attr('selected', 'selected');
}
// run it before changing it
alert('first go');
change();
var tmp = String(change).replace(/function change\(\){/, '');
tmp = tmp.replace('}', '');
tmp += 'alert(\'it changed\');';
change = function() { eval(tmp); };
// try it again - should get the second alert this time
alert('second go (post mod)');
change();
});
See the sample here.
Essentially, what I'm doing is:
Convert the function to a string
Replace the bounding function constructs
Add whatever functionality I want to inject
Reassign the modified function to the original function
Seems to work, but might not in the real world :)

Locating an element in a 'Facebox' box

Heres my link:
http://tinyurl.com/6j727e
If you click on the link in test.php, it opens in a modal box which is using the jquery 'facebox' script.
I'm trying to act upon a click event in this box, and if you view source of test.php you'll see where I'm trying to loacte the link within the modal box.
$('#facebox .hero-link').click(alert('click!'));
However, it doesn't detect a click and oddly enough the click event runs when the page loads.
The close button DOES however have a click event built in that closes the box, and I suspect my home-grown click event is being prevented somehow, but I can't figure it out.
Can anyone help? Typically its the very last part of a project and its holding me up, as is always the way ;)
First, the reason you're getting the alert on document load is because the #click method takes a function as an argument. Instead, you passed it the return value of alert, which immediately shows the alert dialog and returns null.
The reason the event binding isn't working is because at the time of document load, #facebox .hero-link does not yet exist. I think you have two options that will help you fix this.
Option 1) Bind the click event only after the facebox is revealed. Something like:
$(document).bind('reveal.facebox', function() {
$('#facebox .hero-link').click(function() { alert('click!'); });
});
Option 2) Look into using the jQuery Live Query Plugin
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
jQuery Live Query will automatically bind the click event when it recognizes that Facebox modified the DOM. You should then only need to write this:
$('#facebox .hero-link').click(function() { alert('click!'); });
Alternatively use event delegation
This basically hooks events to containers rather than every element and queries the event.target in the container event.
It has multiple benefits in that you reduce the code noise (no need to rebind) it also is easier on browser memory (less events bound in the dom)
Quick example here
jQuery plugin for easy event delegation
P.S event delegation is pencilled to be in the next release (1.3) coming very soon.

Categories

Resources