What's the cleanest way of executing something on an element that is dynamically loaded through js/jQuery? Basically the user adds a form that potentially has a wysiwyg editor in it (depending on the context); this is a textarea that needs to have something like $(".wysiwygTA").editor(); called on it. Of course I could do something like:
var newForm = 'some_form_loaded_via_ajax_with_a <textarea class="wysiwygTA"> in_it';
$(".formWrapper").append(newForm);
$(newForm).find(".wysiwygTA").each(function(){ $(this}.editor(); });
But that doesnt seem very clean to me. Ideally I want to do something in the fashion of
$(document).listenForAddedTextarea(function(textarea){textarea.edtior();});
So that I could add the form from multiple places. I could isolate the editor-invoke in a seperate function and just call that, but that still leaves me with an extra line of code each time I want to add an element.
So: what would be the best way around this? :o)
Best Regards,
Rasmus Dencker
There is no such thing as elementAdded event in JS. Your only option is the 1st one you mentioned. Adding scripts in HTML you are returning from the server is a bad idea IMO.
Use Bind method for binding dynamically:
$( document ).bind( "listenForAddedTextarea", function(textarea) {
textarea.edtior();
});
you can do one thing. Create an event and trigger that event whenever you want.
Create an 'listenForAddedTextarea' event like
$(document).on("listenForAddedTextarea", function(textarea) {
textarea.edtior();
});
Trigger the event
$(document).trigger("listenForAddedTextarea");
Related
If I dynamically create an element and then add an onclick="function()" to it, why doesn't that code get physically added to the element, the same way adding a class to it would?
Asking because I'm trying to pass a board game back and forth between players. I can send the innerHTML of the container element via AJAX to the next player and the physical game will load for them - but then any eventhandlers on dynamically created pieces are no longer there.
Do I have to create a function to put them back? I don't think that would be too difficult, but if there was a way to get the onclick code to be written to the html page when added to the elements so that it passes in the innerHTML that would be much easier.
You could pass around the innerHTML via AJAX as you are currently, but using onclick is vulnerable to XSS attacks, unless you do some sort of JS obfuscation.
Easier than obfuscation would be to share common Javascript for both players with click handlers. Like this:
// Assign an ID for every button, and handle each event separately.
const buttonElement = document.querySelector('#btnOne');
// This is the equivalent of `onclick`
buttonElement.addEventListener('click', function (event) {
alert('Element clicked through function!');
});
dynamically create an element, add event needs to use event delegation.
I have a set of links with a class app-context-link on my page – just some <a> menu elements.
They are generated when the page is loaded from some data that the page receives from a JSON.
I then apply the following on click jQuery function, to make sure that when a user clicks on one of those elements, a certain procedure is performed:
$(".app-context-link").on('click', function(e) {
e.preventDefault();
// do something
}
The problem is that when the user clicks on one of the items, I want to highlight the item they clicked, perform some action on the JSON, and then return a new menu to the user that has other elements of the same class app-context-link – in this case the "old" onclick function does not apply to the newly added items, right? And then I can't get them to behave in the same way because of that.
Does anyone have an idea how I could resolve it?
I know I probably have to rewrite everything very carefully with callbacks, etc. but maybe there's an easier solution already inside jQuery and I'm just missing something?
And as a bonus track – if I decided to leave the menu as it is and just to highlight the element clicked (through appending a class), how would I do that? Sorry if that last question sounds stupid, but I'm a novice and feel a bit confused...
Thank you!
You need to delegate event, e.g:
$(document).on('click', ".app-context-link", function(e) {
e.preventDefault();
// do something
});
Now selector will be filtered on each click.
document is an example, usually, you'd prefer to bind it to closest static container
function bindLink() {
$(".app-context-link").click(function() {
// do something
});
}
Now, everytime you change your data, you can call your bind function (bindLink()).
I have an HTML page with around 100 text boxes. I currently use a JS event listener (blur) to detect when a user leaves a text box. Within the event listener I use if statements to filter the action depending on which text box was used, i.e. if id == blah, if className == blahblah, etc.
Would it be considered a better practice to place onBlur() in the HTML tag of each text box in order to direct the action to specific functions, or am I on the right track?
Hey buddy as rightly told by Sergio. Its better to have event handlers in script element by DOM approach.
Now to simplify your task use EVENT DELEGATION
just attach document.body.onchange=detect
function detect()
{
var textboxvalue=event.target.value //event.target point to text box on which blur event fires
}
This simple code will do your task by bubbling of event. No need to use any arrays/conditionals/classes/ids/seperate event handlers
"change" event is same as "blur" event ."change" only fires if value of textBox has been changed so null/empty string is not applicable
Productivity is priority after performance, for me.
Since you're new, I would recommend a javascript library like jQuery. With this, you can do a simple statement to put the blur/keyup/change events on all, and handle it in one organized place.
I have no doubt this can be done with pure javascript, but a major benefit of a javascript library is the increase in productivity by writing fewer lines.
In your specific case, I would do a jQuery $.keyup() on all <input>s via an empty css class and if or switch off another empty class to specify sub-textboxes:
$('.myEmptyClassThatsOnEachOfThe100Textboxes').keyup(function(){
if($(this).hasClass('myEmptyClassThatsOnEachTextboxOfThisFirstType')){
//do stuff
}
else if(...
})
For example i'm using append, and for example i'm appendig button in to a div, and i have function $('button_id').click(... etc to work affter i append the div, how can i do that.I mean i get no errors, but the function is not starting, it's because i append and then i want to use the function but how to do that, i tryed with delegate, but same thing.I tryed with function in the button tag , onmouseover and then the function thing, but nothing it gives me function not found.What is the solution ?
I have two events, one event is click event that appends button, the other event is click event that does something if the button that was appended is clicked, but that second event is not working ?
Try using :
$(elem).live(...)
It will bind event for now and in the future.
Firstly, it always helps if you show us the exact source code. $('button_id') is the incorrect selector to start with, try something more along the lines of $('#button_id') as your selector. Also, are you appending dynamic content? Anyways, I've always used the delegate() function quite successfully, but have you tried using the live() function? Also, one more thing to make sure of is that you have the newest version of jQuery as your source.
As was stated as well, you can not have duplicate ids, if you want to have a pointer, use class, instead of id="some_id" use class="appended". To select those using jQuery, use the selector like this $('.appended').
Try something like this it will work as per your expectations.
$("#button_id").click(function(){
//On click code goes here
}).appendTo($("#div_id"));
It's difficult to determine the problem you're having without seeing your code, but delegate (or live) should be perfect for what you're trying to do:
$("body").delegate("#b", "click", function() {
alert("ok");
});
$("#example").append('<input type="button" id="b" value="Click" />');
The click handler above will fire when an element with id="b" is clicked, whether or not that element happens to be in the DOM right now or not.
However, as others have noted, it's important to remember that IDs need to be unique within a document, so by the sounds of it you may be better of using classes instead.
You can see an example of the above code running here.
So I have the small code snippet below, which I would ideally like to call the function to alert me with hello when the #results_more element is clicked...
$('results_more').observe('click', function(evt) {
alert('hello');
});
However, I think I'm doing something terribly wrong if something this easy doesn't work. Anything I may be overlooking with the Prototype library, or Javascript in general?
At face value, there shouldn't be anything wrong with your code, but you aren't giving enough information.
Does exactly one element with id="results_more" exist? What is the result if you alert($('results_more'))?
Has the element been created already at the point you are trying to register the event listener? You cannot register events on (or for that matter collect) elements that have not yet been added to the DOM. You can get around this by moving your code to after the element is created in your HTML or put it within a dom:loaded event listener.
Take a look at jsfiddle.net/zDa7m for a simple example.