running javascript on a page element that was created via ajax - javascript

I am using Javascript to make some changes to how a page displays depending on what the user inputs in the form. This works fine and dandy, except for on one element. That is because this element is changing via ajax depending on what the user selects earlier in the form.
I am using document.observe('dom:loaded', function() { to run my JS code, so obviously this one elements JS isnt working because the elements are added in after the dom loaded. What's the best way to run JS on this page element after they are loaded in?
Thanks!

You can handle events on the parent element, then when the event triggers you use the target property of the event object to find out in which child element the event was fired, for instance if you wanted to know when a button added dynamically was clicked you could do:
document.getElementById("parent").click = function(event){
if(event.target.id=="myButton"){
//handle click
}
}
<div id="parent">
<input type="button" id="myButton" /> <!-- added dinamycally -->
</div>
This is making use of Event bubbling

Related

How to remove all event listeners made from a specific loaded file?

<div id="loaded-content">
#Scripts.Render("~/someScript.js")
</div>
this appears to be equivalent to
<div id="loaded-content">
<script src="/someScript.js"></script>
</div>
When the above content is loaded with ajax every event listener from someScript.js becomes active and remains, even if the content is later removed via jQuery like so:
$("#loaded-content").remove();
What should be done to prevent the same event listeners from being activated multiple times if the content is constantly loaded and removed? I tried adding a global variable var scriptHasRun = false;, then the following code in someScript.js:
$(document).ready(function(){
if(scriptHasRun){
return;
}
scriptHasRun = true;
<more code>
});
It works for someScript.js, but then came someOtherScript.js that appears to be loaded the same way, so to prevent things in advance I used the same method with another variable var otherScriptHasRun = false; and the second time it gets loaded in the page it no longer works. It started working normally when I removed the check. I'd like to know how to replicate the circumstances of someOtherScript.js, or in case that's normal, what could be causing someScript.js to be loaded multiple times?
I see you are using jQuery. I'm not sure what you have in someScript.js, but you can use
$('#element').off('click', handleClick);
to unbind event from element before attaching it so it does not get attached multiple times.
other option I would try to use is to ad specific event related classes to element to mark them as already having the event attached and use something like the line below to attache the events so you can skip using variable scriptHasRun to check if script has been loaded.
$('#myElemetSelector:not(.boundToEventX)').addClass('boundToEventX').on('click', onElemetClickedFunction);
It's likely because the event listeners in someScript.js are bound to the body and the ones in someOtherScript.js are bound to the elements themselves, so the code that checks if the script has been run before isn't needed on them, but still is for someScript.js.

click on html element except a dynamically created elements?

I need to trigger click in an html page except a div.but that div is created dynamically after page load.I have tried following code.
$('html').click(function(e) {
if(!$(e.target).hasClass('flyoutdiv') ){
}
});
It is working only for element that is not created dynamically. "flyoutdiv" is created dynamically after page load.I need to trigger click in the entire page except that element.is there any solution?
You need to attach click event to flyoutdiv div like following.
$(".flyoutdiv").on('click',function(e){e.stopPropagation();})
to handle dynamic flyoutdiv you can use the code like following.
$("body").on('click',".flyoutdiv",function(e){e.stopPropagation();})
You need to use the method on for element created dynamically.
$('html').on('click', function(e) {
if (!$(e.target).hasClass('flyoutdiv')) {
}
});
After you created flyoutdiv, bind a event listener to him. After creation of div add $('.flyoutdiv').click(function(){//your code here});
It is much better than searching for target on every click.

Adding to innerHTML of document.body causes jQuery .on() to not find its target

So I have some dynamically generated HTML stuff. If you click a button, it adds some html that has another button, and you can add that other html several times, generating several copies of it. This is all inside of a <form> tag, so I need to use e.preventDefault() on each button to prevent javascript from trying to submit the data. Each button also has its own code for onclick. There's a problem with javascript-added click events on newly generated content however. If I have <button class="myBtn"></button>, then in javascript I have $(".myBtn").click(...), that will work just fine, but only for buttons that already exist when the javascript code is run, meaning newly generated buttons won't have the event attached. The solution to that problem is found here.
Now we come to the real issue. That all works perfectly, but only until I add to document.body.innerHTML. As soon as I execute the line document.body.innerHTML += "Text", the code from the link above no longer executes when the generated button is clicked.
I have an example here: https://jsfiddle.net/6hvgatLy/1/
You are re-writing the whole body innerHTML which will remove all event listeners
Use append() instead
Change
$("#deadlyBtn").click(function(e){
e.preventDefault();
document.body.innerHTML += "Now try clicking [Add new Input]"
})
To
$("#deadlyBtn").click(function(e){
e.preventDefault();
$('body').append("Now try clicking [Add new Input]")
})
DEMO
Alternatively you can change your event delegation to an asset that isn't being overwritten like body or document
$(document).on("click", ".formDiv .innerContainer .innerBtn", function(e){
e.preventDefault()
$(this).before($('<input type="text" placeholder="Textbox"/>'))
})

Ruby on Rails - JavaScript in dynamically generated partials

I know putting JavaScript in partials is a bad idea because the page will have to load up a new script every time a new partial is loaded. I am aware of and have read this question, but its answer did not work for me (putting the script into app/javascripts/application.js). I think it is because I am working with partials that are dynamically generated onto the page. I think the dynamically generated partial does not react to the script loaded up on the initial page.
For example, I have a "Rule" div with a select input that has a script to do something when the select input is changed. This works for every Rule div that is generated on page load. But then there is also a "+" or "ADD" button which will dynamically generate more Rule divs which do not respond to the script, unless that script is in the partial.
Is there a good way to keep the script out of the partial when the partial is dynamically generated?
JQuery sets listeners on page load (i.e. $(selector).on(etc.)), so it doesn't listen for events on dynamically added elements. There is a way around it, though. You need to use what is called a delegate.
$(document).ready( function() {
$('body').on('change', 'input.selector', function(e) {
// do something
});
});
I'm not sure what your event (here I put change) or selector for the select you are using (here I put input.selector), but if you replace those with the appropriate information, it should work even with dynamically added elements.
You can use JQuery to execute the code only after the document has loaded onto the DOM:
$( document ).ready(function() {
//Call your functions here
});
That way, your JS will have access to whatever is on the page, because you are ensuring that it is fully loaded.
If your divs are not in place on document ready, you can use event delegation, as suggested by ptd. Basically what this means is that you install a handler on a parent div (which will be present on document ready) which says, "hey, when you click on this dynamic div inside of me, call this function".
$('div#master').on('click', 'div.dynamic', function(event) {
console.log("action here")
var $dynamicDiv = $(event.currentTarget) //The current Target is the thing you clicked on, not the parent.
});
If you are adding elements to the DOM using AJAX calls, but want to keep your JavaScript in your assets folder only, here's a quick and clean way to accomplish this.
// /app/assets/javascript/foo.js
// On intial page load
$(document).ready(function() {
yourJavaScriptForPartials();
});
// After a subdomain field is loaded via AJAX
$(document).ajaxComplete(function() {
yourJavaScriptForPartials();
});
function yourJavaScriptForPartials() {
// Insert your javascript here.
};
Now, any JavaScript you put in the yourJavaScriptForPartials() function will be available both to the initially loaded DOM, and to any DOM elements added via AJAX. For reference, here is the JQuery page for the ajaxComplete event listener.

Javascript - how does this button fires something?

Javascript is not my speciality.
I have a page that contains an image. This image, when clicked, fires an Ajax code, that shows a floating box. Analyzing the page code, I don't see how this button can fire the code.
The button is declared like this:
<div class="leaderboard-text">
<span id="addon-add-language-button">
<image class="ajaxListAddButtonEnabled" listId="localizationList"
src="/itc/images/blue-add-language-button.png" />
<image class="ajaxListAddButtonDisabled" listId="localizationList"
style="display:none;"
src="/itc/images/blue-add-language-button-disabled.png" />
</span>
</div>
just after this code, I see this var being declared:
<script language = "Javascript">
var createList_localizationList = function() {
var reorderEnabled = false;
var preventLastRowDeletion = false;
var searchEnabled = false;
var list = new LCAjaxList();
list.initialize():
}
document.observe("dom:loaded", createList_localizationList);
</script>
As far as I see, the image is firing somehow this javascript, but how can the button do that if there's no "onclick" or href reference tied to it? Where is the line that tells which method should run when the image is clicked?
What should I look on the code to get a clue how this button works?
What I need is to fire the method used by this button using javascript.
any clues?
================
after reading all that you guys have written, I have used Safari's Inspect Element and identified this listener attached to the object:
is this of any help? Now the question: how do I fire the method associated with this image from javascript? Thanks guys.
My guess is that it's either one of the two statements
var list = new LCAjaxList();
list.initialize():
They seem really bad designed. A list object should take a DOM object to act upon. LCAjaxList probably hardcodes the element to bind to.
What you're looking for is .observe. That adds an event listener, so somewhere there may be
$('addon-add-language-button').observe('click', SomeFunction)
Event listeners are the preferred way to handle javascript events, rather than using an HTML onClick.
When the DOM is completely loaded on the page it fires the event listener "createList_localizationList", so there is no need for a user to click on anything. You can add an event liseter to the button for onclick, instead of when the DOM loads with your button.
You could try this:
$('ajaxListAddButtonEnabled').observe('click', createList_localizationList);
I am not sure if that class is used again, but maybe if you add an id to that element (id='someidname') to make sure you are not adding this to another element on the page.

Categories