Dynamic content and loading of JQuery scripts several times - javascript

I am having a page that loads content dynamically. Depending on which menu item the user clicks, different tables are dynamically loaded and presented using jquery.
One column of each table is having an update linke used to update the content that specific row is representing. When clicking that link a JQuery UI Modal Dialog is presented with a form loaded from a server in which the user should update the content and post back.
This is how I understand it, please correct me if I am wrong. I need to load the jquery script at the same time as I load the dynamic content in order to bind the events between the javascript functions and the elements that is being loaded.
Assuming my assumption is correct I do load the content and the same JQuery UI Dialog scripts each time the user selects a different table. I load the content and jquery files from different javascript functions loaded together with the main index file.
The consequence is unpredictable behaviour (probably predictable using the same use case). When loading the table more than once and updating something so the modal dialog is presented, the dialog is not presented anymore after the first or second usage, as one example.
Could it be a problem that the jquery script is loaded more than once? If it is, what's the principle or patterna I should use for this kind of application. If all above is false assumption, still, what's the principle or patterns for designing this kind of solution where different kind of dynamic content is loaded at several places (all presented within the same index file) and all need the same jquery files.

Take a look a jQuery $.live() and $.delegate():
http://api.jquery.com/live/
http://api.jquery.com/delegate/
These will allow you to bind events to dynamically loaded content.

If I understand you correctly, you are asking how to bind events on dynamically generated content. You do not, in fact, have to load new script at the same time as new content in order to be able to hook events to said content.
What you want is the jQuery 'live' handler. You can specify the target of the binding using standard jQuery selectors. However, instead of the following syntax:
$('.foo').click(function(){ });
You would use
$('.foo').live('click', (function(){ });
The way this works is through event bubbling, where an event invoked on a child element (such as an input box) 'bubbles' up through all parent nodes. In this case, jQuery just watches the whole document for event bubbles, and then matches it against your specific selector conditions.

If I understand you correctly:
1) Multiple tables with an update link on each rows to update their content.
2) Update button opens a modal box with a form.
3) Form is posted and data is retrieved after being processed by the server to feed the concerned table row.
If the flow described above is correct, I don't see why you should load jQuery or jQuery ui more than once.
You should do something like
1) Load the page with all the scripts required.
2) Set up and ajax call with the jquery .ajax() method (doc)
3) Use the ajax call to submit the form data to the server and retrieve the results
4) Use the success callback of .ajax() to feed the row with the updated data. Within the success method you should be able to retrieve the context (a.k.a. the link you clicked) and identify the actual row you clicked.
I hope I make sense.
If by any chance you need to create new rows then you should consider checking the .live() and .delegate() method of jQuery.
Good luck.

Related

jQuery not working on AJAX loaded html content

I have a PHP admin dashboard in which am using bootstrap theme. We know it have inbuilt jQuery objects like drop-down menu, collapse, tabs, etc., And it all will work if we just added bootstrap js file.
Now the problem is when I get contents from ajax call and display it on my page, all javascript controls which loaded via ajax are not working.
Am using this ajax call for all my inner pages display. So it may have any bootstrap javascript control on loaded HTML.
So how can I fix this dynamically on every ajax call. My ajax loading javascript is below
$('a').bind('click',function(event){
event.preventDefault();
$.get(this.href,{},function(response){
$('#app-content-body').html(response)
});
});
Note : My problem is not in my above code. Actual problem is bootstrap javascript controls not working when I load html content from above code
jQuery is only aware of the elements in the page at the time that it runs, so new elements added to the DOM are unrecognized by jQuery. To combat that use event delegation, bubbling events from newly added items up to a point in the DOM that was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go that high up the DOM tree. Ideally you should delegate to the nearest parent that exists at the time of page load.
Change your click event to use on(), provided your version of jQuery supports it;
$(document).on('click', 'a', function(event){
If you're using jQuery older than version 1.7 use delegate():
$('body').delegate('a' , 'click', function() {
Note the operator order, they are different with on() reading a little more logically.

Dealing with partial views and javascript

I have set up a partial view to render in an index page. The partial view gets posted using Ajax to the server when a user clicks a sort button. This is so the entire page won't refresh just the partial view table.
The problem is after the first sort, the JavaScript in the index page is no longer effective. I worked around this by putting the js in the partial view itself to persist the events, but this produces js errors to saying 'continue' or 'ignore'.
It is because your newly injected elements ( via ajax) is not aware of the events bounded. So those event bindings are not availabel to them.
You should change your event bindings to use on so that it handles the current elements and future elements (added to DOM dynamically via ajax or so)
for example, if you want to handle the click event for elements with css class someCssClassSelector,
Change
$(".someCssClassSelector").click(function(){
//do something
});
to
$(document).on("click",".someCssClassSelector",function(){
//do something
});

Using JQuery to modify data written to document by functions

Most of my html is data that is provided via a Jquery request. It is written to the page by inserting it into a "main" div like such:
$("#main").html(passedData);
}
The page works great, but now i'm having problems trying to add any javascript to that data that is written to the div.
Namely I have tables that are inserted into the div and I am trying to write scripts that hide certain cells when others are clicked. I've used http://jsfiddle.net/ to make sure that all of my JS is correct, but for some reason it seems like the JS functions don't see that data in the div and won't manipulate it.
Is there anything I'm missing? When writing data to a page like this do you have to do certain things to reference that data with javascript?
You have to attach event handlers to those "future" elements like this:
$("#main").on("click", ".myelement", function(){
// Do something
});
Read more here. Also, it would be a lot easier if you posted your actual code.
It's hard to troubleshoot without the actual code, but I'm almost certain the problem is that when your jQuery code is executed, the elements that were pulled in through AJAX didn't exist. Therefor, no events will be attached to them.
You should look into using jQuery's .on() event handler. Attach it to a parent element that exists when DOM-ready is fired, and you can manipulate any elements inside it that were pulled in dynamically.

ajaxsetup and specific callback

My situation
First of all, I hope I can explain it right; I have an admin panel which will be fully ajax driven. It uses jquery to bind all internal (everything that uses domain.com/admin///* ) and instead of following the link it gets the page via ajax.
Problem
Lets say I have a table of news in which i want to dynamically delete one, it links to page which deletes the page. This link has the event to get the page dynamically linked to it, (because all the links are binded).
I want a good way to get feedback from the global ajax function handling the grabbing of the page and fadeout the row in the table. And thus a good way to reuse this.
$.ajaxcomplete works, but it KEEPS doing whatever i define, no way to reset it.

refresh form page with jQuery Mobile

In my mobile website, I dynamically create a form in javascript, so I need the 'reload' the page to get the jQuery Mobile style.
For a listview, we can simply call $("#mylistview").listview("refresh") but there is no such feature for form.
I know that we can call "refresh" one each element of the form, but by doing this, the style is not correctly applied. Indeed, all my checkbox get separated, they don't appears in one "inset"
I there any workaround ?
Docs in the release notes:
http://jquerymobile.com/blog/2011/08/03/jquery-mobile-beta-2-released/
Example:
$('#nameOfPage').trigger('create');
Quote:
New “create” event: Easily enhance all widgets at once
While the page plugin no longer calls each plugin specifically, it
does dispatch a “pagecreate” event, which most widgets use to
auto-initialize themselves. As long as a widget plugin script is
referenced, it will automatically enhance any instances of the widgets
it finds on the page, just like before. For example, if the selectmenu
plugin is loaded, it will enhance any selects it finds within a newly
created page.
This structure now allows us to add a new create event that can be
triggered on any element, saving you the task of manually initializing
each plugin contained in that element. Until now, if a developer
loaded in content via Ajax or dynamically generated markup, they
needed to manually initialize all contained plugins (listview button,
select, etc.) to enhance the widgets in the markup.
Now, our handy create event will initialize all the necessary plugins
within that markup, just like how the page creation enhancement
process works. If you were to use Ajax to load in a block of HTML
markup (say a login form), you can trigger create to automatically
transform all the widgets it contains (inputs and buttons in this
case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page"
).trigger( "create" );
Create vs. refresh: An important distinction
Note that there is an important difference between the create event
and refresh method that some widgets have. The create event is suited
for enhancing raw markup that contains one or more widgets. The
refresh method that some widgets have should be used on existing
(already enhanced) widgets that have been manipulated programmatically
and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new
unordered list with data-role=listview attribute after page creation,
triggering create on a parent element of that list would transform it
into a listview styled widget. If more list items were then
programmatically added, calling the listview’s refresh method would
update just those new list items to the enhanced state and leave the
existing list items untouched.

Categories