I have a model, Color, with a foreign key mill that I'd like to autocomplete. Furthermore, I'd like to detect when the mill select box changes and do something with that in Javascript. However, I can't seem to trigger any JS off the select box being changed.
I set up my admin like so:
# admin.py
class MillAdmin(admin.ModelAdmin):
search_fields = ['name']
class ColorAdmin(admin.ModelAdmin):
class Media:
js = ['js/jquery/jquery.min.js', 'js/admin/some-function.js',]
autocomplete_fields = ['mill']
And I write some Javascript:
// some-function.js
console.log('loaded script');
document.addEventListener('change', (function(e) {
console.log('detected change event somewhere')
}))
console.log('event listener added')
In my browser console, when I visit the Color page, I see:
loaded script
event listener added
But when I select a mill, nothing more is logged.
Further notes:
The autocomplete itself is working just fine -- I am able to choose the mill I want, save, etc. Furthermore, if I remove autocomplete_fields = ['mill'] from my admin, I see that the vanilla select box does trigger the change event as expected:
loaded script
event listener added
detected change event somewhere
I dug around in the source code long enough to find that Django is using Select2, which promises to emit the change event just as if it were a normal select box. But if that is happening, something else in the page must be eating it, because I'm not seeing it. What's going on? If there's a conflict between Django and Select2, does anyone know a workaround? Thanks!
Events triggered by jQuery cannot be observed by native event listeners. Select2 uses jQuery's trigger function to handle events, which doesn't fire native DOM events, but you can swap the jQuery trigger for a native DOM one as illustrated here https://github.com/select2/select2/issues/4686
Related
As said in the title, I am trying to customize the contextmenu event. The situation is this: I want to catch the event, preventing it from firing on some elements (I'm ok here, all good), then I want to call it targeting another element (this is not working). At first I just tried dispatching it by creating a custom event and using myTargetElement.dispatchEvent(), the custom element does fire, but context menu won't open.
The reason I need this is that I want to open the contenteditable context menu when the user clicks anywhere. I've tried something similar to the last example on this MDN page, and I logged the event type, it is firing. Here's some example code of what I'm doing.
HTML
<div id="prevent">This div will prevent default event behaviour.</div>
<div id="my-target" contenteditable>Fire here the event and open context menu</div>
For instance, I cannot put one div inside the other.
JS
function showMenu(){
const preventer = document.getElementById('prevent');
const myTarget = document.getElementById('my-target');
const myEvent = new Event('contextmenu', {
bubbles:false //I had to use this, as setting it true was logging an error on Firefox
});
myTarget.dispatchEvent(myEvent);
console.log(myEvent.type); //it does log the event name
}
The listener that prevents default is not important, as when I just run the showMenu() (even when removing every other bit of js) on console it still has not the intended effect. I'm also able to listen to the 'contextmenu' event when I add a listener and run showMenu().
I'm beginning to think that there is not a direct solution to this, but workarounds and ideas would be really appreciated.
I am using this code form:
dom.document.getElementById("contents").addEventListener("click", {
(e0: dom.Event) => println("Got the click event at top level!")
}, false)
To experiment with event capturing in Reactjs. This works fine for the click event. However, when trying to do the same thing with UIKit events for the nestable component, as below:
dom.document.getElementById("contents").addEventListener("start.uk.nestable", {
(e0: dom.Event) => println("Got the start event at top level!")
}, false)
I am not getting anything. The nestable documentation lists four event names and I've tried all of them - but never get any response when manipulating nestables. It is my understanding that without capture the events should be bubbling up to the top level where the listener is attached; but when using devtools to monitor events on the entire document it seems like the nestable events are not fired.
Incorrect event type? Incorrect event name? UiKit swallowing its own events for some reason? Thankful for any help.
Apparently this is a consequence of UIKit's reliance on using jquery's .trigger() to send its custom events, which cannot normally be listened to except through jquery as per this bug report:
https://bugs.jquery.com/ticket/11047
This being the case I took to manually adding jquery listeners in my page setup and calling back into the Scalajs code through the normal #JSExport method.
I'm trying to click on "close" button in Gmail compose dialog using JS from chrome console. This button have a class "Ha". Classes are static and will not be changed after the refresh.
Screenshot
I've tried to use this code, but nothing happens:
document.querySelector(".Ha").dispatchEvent(new MouseEvent("mousedown"));
Here is the solution:
var test = document.getElementsByClassName("Ha")[0];
var e = document.createEvent('Event');
e.initEvent("mouseup", true, true);
test.dispatchEvent(e);
To answer the basic jQuery issue what you need is...
$( ".Ha" ).trigger( "click" );
to trigger a click event on the dom object in question. While when you click on an object using the mouse a mousedown, a mouseup, and a click event are all all triggered, by triggering through code you need to specify which specific event is triggered base on which event is monitored for by the web app. You also need to be careful about using class based selectors as classes can exist in more than one place in the dom structure and you could wind up triggering click events on the wrong dom object or on multiple dom objects which can cause unexpected results, the best way is to use an object's id tag if it exists.
As a side note be careful with the use case for what you are trying to do as you could be violating Google's terms of use by writing code to go around their UI and their own coding.
Is there a CKEditor event that I can hook up to that fires whenever the content changes? Ideally I'm looking for an event that fires when anything at all changes, so for example it could be the user typed something into the editor, or a toolbar item was used (e.g. changed the font color).
Currently I'm just hooking up to the key event which unsurprisingly only fires when a key is pressed, and not when for example the font color is changed via the toolbar.
CKEDITOR.instances['myEditor'].on('key', function () {
console.log("changed");
});
I've also tried using jQuery to delegate a click event on the CKEditor's parent like below. This partly works, for example it fires if you click the Bolt/Italic buttons, but not if you change the font color:
$(document).on('click', '#myEditor_DISPLAY', function(){
console.log("changed");
});
I've looked at the documentation here but haven't found anything. If there's only an event for the toolbar usage then I could make do with that because I can just hookup to both that and the key event.
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.