adding functions to injected elements - javascript

Okay how can i add function to injected elements(which that element dosent exist on first browser load). Please read through my example carefully , i hope you can understand.
For example:
i go to www.website.com , when it loads it loads up "functions.js" and "other.js" , inside "functions.js" there's a code that injects a new div with ID when user click on a button.
The injection code as shown below:(functions.js --jquery)
$('a#button').click(function(){
$('a#button').after('<div id="new">New div<br>Another link</div>');
});
However there's another on click functions loaded in another js file which is "other.js" (loaded same time as function.js load).
Inside "other.js" has the code for the onclick function when the new div's link (#newdivlink) is clicked.
other.js :
$('a#newdivlink').click(function(){
alert('you clicked on new div's link yay?');
});
But the problem is , the onclick function for the new div's link(#newdivlink) cant be executed as the script can't find the div (as it is being injected after i loads).
Or is there some problems ?
P/S if you are asking why not combine both scripts , i don't want, as i want to try this technique out.

Try using 'live' instead of click:
$('a#newdivlink').live('click', function(){

use live() for jQuery version < 1.7 or on() for version >= 1.7

What you probably need is jQuery.live.
$('a#newdivlink').live("click", function(){
alert('you clicked on new div's link yay?');
});

Related

ready function triggers in every page

I have a rails app, if the user is not logged in, I am redirecting to a page, which has one br tag with a class. Like this
<br class="logged">
In the Javascript on ready of that function, I am triggering a modal as follows.
$(document).ready(function(){
$('.logged').ready(function(){
$('#open-login').click();
});
});
This is working fine, except this modal is getting triggered on every page of the app. I mean that br tag is there in only page of the app, how it is ready for every page is what I don't understand. If anyone can tell what went wrong with my approach, it would be of great help.
ps: It's rails application
You can try this:
$(document).ready(function(){
if ($('.logged').length > 0)
$('#open-login').click();
}
});
Into if condition you can declare an element of specific page and in only that page you can execute an action.
The jQuery .ready() method can only be called on a jQuery object matching the current document. Attaching it to a $('.logged') selector still makes its handler function get called when the document is ready - it doesn't care about the selector.
MarcoSantino's answer will work for your needs, although you may find it cleaner to add the logged-in class to the body tag instead of inserting a new br tag, and then use the following in your JavaScript:
$(document).ready(function(){
if ($(body).hasClass('logged-in')) {
$('#open-login').click();
}
})

Trying to load another html page into a div using jQuery. I looked at other posts but mine still isn't working

Please have a look. EDIT: here is a link to a fiddle for the entire code: http://jsfiddle.net/e77aqubx/
This is a section of the jQuery (everything above it seems to be working fine). I am trying to get portfolio.html to show up in the #portfolio div (which is not visible until you click the link for it). The portfolio.html is in the same folder in the directory so I don't think I have to worry about the link.
$("#portfolio_link").click(function(){
$(".header").hide();
$("#about").hide();
$("#portfolio").show();
$("#portfolio").load("portfolio.html");
});
I have a div set up for it in the html as
<div id="portfolio">ooh blah dee</div>
In the jQuery I also tried:
$("#portfolio").show(function(){
$("#portfolio").load("portfolio.html");
});
Have you considered using IFrames? If I understand your issue correctly you can simply change the display of the element on action using something like .toggle()
example: JSFiddle
Edit:
As far as the current code, i would really need to see some more info as your code appears, at a simple form anyway, correct. Can you provide your file structure, or the results from the networking tab in dev tools when you run the event? Or even give this a shot on your .load():
$( "#portfolio" ).load( "portfolio.html", function() {
alert( "Load was performed." );
});
However it's important to remember that .load() is an ajax call so everytime you run your display method you're rendering a view via ajax instead of that one time iframe.
Hmm, the problem might be that the #portfolio_link element is created in the DOM after you attempt to attach the event listener. This could be solved by attaching the event listener to the 'body' tag and filtering down to any click events on children matching the '#portfolio_link' DOM selector.
Try this:
$('body').on('click', '#portfolio_link', function(){
$('.header').hide();
$('#about').hide();
$('#portfolio').show();
$('#portfolio').load('portfolio.html');
});
Jquery works in chain.
Also try first to load and then hide.
Can you use Firebug or Chrome devoper tools to see
what is happening with DOM?

JQuery Mobile do X to every div with given class

I'm building a JQuery mobile site which has an image slider on 2 pages. The sliders are activated using the following JS:
$(function () {
$("#slider").excoloSlider();
});
where '#slider' is the name of the div that gets rendered as the slider.
I have this slider on the 2 pages and have given both the same id, and don't want to insert the above code into both pages. To make things easy I want to be able to make add the above code into a.js file that I'm referencing at the top of both pages.
However, the script only kicks in when one of the pages are the first page to be navigated to. So, I assume this means the code is only being called in the once, and due to the AJAX loading of the subsequent page, it isnt called when this new page loads.
So, how can I run the code to affect any/all pages which feature the slider?
I dont know how many times you have to call .excoloSlider(); function. In case you have to call it each time the page is visited, then you need to use any of these page events, pagecontainershow or pagecontainerbeforeshow.
If you use pagecontainershow, you can run .excoloSlider(); on #slider even if you have the same id in a different page. This way, you specify in which page to look for #slider.
$(document).on("pagecontainershow", function () {
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
/* check if #slider is within active page */
var slider = activePage.find("#slider").not(".slider");
if(slider) {
slider.excoloSlider();
}
});
Update
I have added .not(".slider") selector to exclude already rendered slider. The function .excoloSlider() will be called on new sliders only.
Demo
Try to use class instead of id since id is unique, then you can change your jQuery code to:
$(function () {
$(".slider").excoloSlider();
});
Use jQuery Mobile API for the navigation system
$(window).on( "navigate", function( event, data ) {
$("#slider").excoloSlider();
});
Edit
Use pageinit
From the jQM docs:
Important: Use $(document).bind('pageinit'), not $(document).ready()
The first thing you learn in jQuery is to call code inside the
$(document).ready() function so everything will execute as soon as the
DOM is loaded. However, in jQuery Mobile, Ajax is used to load the
contents of each page into the DOM as you navigate, and the DOM ready
handler only executes for the first page. To execute code whenever a
new page is loaded and created, you can bind to the pageinit event.
This event is explained in detail at the bottom of this page.

Fancybox link to display another fancybox

Sometimes it makes sense to have a link within a fancybox to launch another fancybox (or load content within the current one).
Say, you have a fancybox error message on login. You also have a "email me my password" widget that works via a fancybox. You may want to combine the two to say (in a fancybox):
Bad password!
Forgot my password!
Unfortunately, this will not work. I considered adding the following js:
$('#fancybox-content a').live('click', function(){
$(this).fancybox();
});
Surprisingly, this sort of worked: You have to click on the link twice and then the right thing happens. Ugh.
Finally, I found a hacky ugly work-around (it works!):
$('#fancybox-content a').live('click', function(){
var href = $(this).attr('href'); //assume there is a selector inside href
$.fancybox($(href).html()); //find the html manually and load
});
What is the right way to accomplish this?
This is i how i solved this problem in my projects:
$('a.fancybox').live("click",function(event) {
event.preventDefault();
var href = $(this).attr('href');
$.fancybox({href: href})
});
In this way you can add fancybox to any current un future A elements with .fancybox class so you don't have to define new events after opening fancybox.
Version 2 is already using "live", so using class names - `$(".fancybox").fancybox();' - would also work on elements loaded using ajax
You should be telling elements to open a Fancybox from within your plugin.
Somewhere you have the following ->
$(document).ready(function(){
$("#my_element").fancybox();
});
That's a very basic function to open a Fancybox, and not only that, but it will also what to open based on the href of the element. You don't need to do any leg work here.
So if you have ->
Forgot my password!
Simply add an ID, such as 'x' for simplicity ->
<a id="x" href="#forgot-password">Forgot my password!</a>
Then, enable the Fancybox plugin for this element.
$(document).ready(function(){
$("#my_element").fancybox();
//this is for our new container to fire
$("#x").fancybox();
});
That should be all you need.

jQuery code repeating problem

I have a piece of code in jQuery that I use to get the contents of an iFrame after you click a link and once the content is completed loading. It works, but I have a problem with it repeating - at least I think that is what it is doing, but I can't figure out why or how.
jQuery JS:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
$("#fileuploadframe").load(function(){
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{action:"savePage",html:response, id: theID},
function(data){
alert(data);
});
});
});
HTML Links ( one of many ):
<a href="templates/1000/files/index.php?pg=0&preview=false"
target="fileuploadframe" class="pageSaveButton" rel="0">Home</a>
So when you click the link, the page that is linked to is opened into the iframe, then the JS fires and waits for the content to finish loading and then grabs the iframe's content and sends it to a PHP script to save to a file. I have a problem where when you click multiple links in a row to save multiple files, the content of all the previous files are overwritten with the current file you have clicked on. I have checked my PHP and am pretty positive the fault is with the JS.
I have noticed that - since I have the PHP's return value alerted - that I get multiple alert boxes. If it is the first link you have clicked on since the main page loaded - then it is fine, but when you click on a second link you get the alert for each of the previous pages you clicked on in addition to the expected alert for the current page.
I hope I have explained well, please let me know if I need to explain better - I really need help resolving this. :) (and if you think the php script is relevant, I can post it - but it only prints out the $_POST variables to let me know what page info is being sent for debugging purposes.)
Thanks ahead of time,
Key
From jQuery .load() documentation I think you need to change your script to:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
var lnk = $(this).attr("href");//LINK TO LOAD
$("#fileuploadframe").load(lnk,
function(){
//EXECUTE AFTER LOAD IS COMPLETE
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{
action:"savePage",
html:response,
id: theID
},
function(data){alert(data);}
);
});
});
As for the multiple responses, you can use something like blockui to disable any further clicks till the .post call returns.
This is because the line
$("#fileuploadframe").load(function(){
Gets executed every time you press a link. Only add the loadhandler to the iframe on document.ready.
If a user has the ability via your UI to click multiple links that trigger this function, then you are going to run into this problem no matter what since you use the single iframe. I would suggest creating an iframe per save process, that why the rendering of one will not affect the other.

Categories

Resources