How do I destroy all jQuery UI widgets? - javascript

I have developed a large "single page application" using jQuery and jQuery UI. As I load various sections in the app it creates jQuery UI widgets like dialogs or date pickers. They tend to hang around and cause some issues when I reload certain sections. I would like the ability to call a function that destroys all jQuery UI widgets that have been loaded and remove them from the DOM. Any solution to catch all of them? Thanks!

In theory, it's easy enough to locate and destroy all widgets of a specific type on a page:
$(":ui-draggable").draggable("destroy");
So, it isn't unthinkable to create a loop around an array of widget types you know you're using, and delete every kind of widget on the list.

Use remove() or detach() to clear the contents of your jquery UI widgets and here is the difference
remove() removes the matched elements from the DOM completely.
detach() is like remove(), but keeps the stored data and events associated with the matched elements.

Related

drag to destroy an element in ruby on rails

I would like to simulate some sort of drag and drop to delete capability on my site (like the recycle bin/trash on windows/osx)
I have a bunch of objects in the database that are being represented by ruby as div on my site.
I know I can add a drag capability to each of the divs using jquery, but I am not sure what to do afterward.
How do I assigned a specific area (an image) to initiate the destroy command? Since each object has a unique id the destroy should come from the object , but should be triggered by the trash image
Do I need to render my UI after such an action or would rails take care of it, like it does now with the regular destroy that comes in scaffolding ?
I know that it is a bit of an abstract question, but I am still in the design process and haven't written much code.
Since you mention jquery, I'm guessing that you're using the Draggables from jQuery UI. You should also look at the docs for Droppable, which details how to handle drop events. After you catch the drop event you could either do a full page post to your server, which would refresh the page and update the UI, or you could make an AJAX call and update the UI via JS.

Execute JS function each time element with specified selector is added

I got to refactor big one-page application with complex UI.
There is following code in document.ready function
$('table.datatable').dataTable({ ... params ... });
$('div.tooltip').tooltip({ ... params ... });
$('ul.dropdownMenu').menu({ ... params ... });
As you can see in this code we search for different HTML controls and call to appropriate jQuery plugins that implement these controls' behavior.
However, since the page is very dynamic new datatables, tooltips and menus are added all the time and since JS functions were called at very beginning of application - those elements have no needed functionality unless I manually call appropriate plugin for them.
I'd like to eliminate the need to call jQuery plugin after each DOM change but don't know how to do it better.
One option is to fire an event each time I am adding anything to DOM and re-call this plugins in event's listener, however I don't like this solution because of need to remember fire the event each time.
I read about jQuery's on function which attach events also for not yet exists elements, but what event do I need? AFAIK there is no domchange event.
Any advises?
Your only option is to hook up your plug-ins on new items after they are added to the DOM. The best cross browser option would be to hook into each place that adds these types of elements to the DOM and simply deal with the new items there by calling some additional function on them. What you need to look for is where you can easily hook into your existing code after new elements have been added to the DOM and then fix up those new elements at that point. Without knowing your code and where the DOM is modified, we can't really advise the best way to do that.
Generically monitoring the DOM for new items with a single method is not possible in a cross browser fashion. Mutation observers are the latest standard way to do this, but it is not supported in many browsers yet. Mutation events came before mutation observers, but is now deprecated.
jQuery's .on() will not do what you want here - it can be used to handle dynamically added DOM elements, but not in the way you want. Your plug-ins could have been designed to handle their events with use .on(), but unless they were designed that way and you can take advantage of that, there isn't a simple way for you to use it to get your desired behavior without rewriting a portion of the plugin.

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.

Dynamic content and loading of JQuery scripts several times

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.

How can I force the DOM to re-eval in Javascript/jQuery?

I am dynamically appending HTML to a webpage and I'm also using jQuery to manage stuff.
When I add HTML code, jQuery ignores its existence.
For example:
$("td.elementToClick").click(...
Will work great with jQuery. But if somewhere in the code I append:
$("tr#myRowToAppend").append("<td class="elementToClick>...</td>");
jQuery will ignore this new element if I click on it.
As jQuery associates the events after the page finishes loading, I need one of two solutions:
- Force the DOM to re eval the page without changing the current layout (I don't wish a refresh, so location.reload() is out of the question).
- Force jQuery to add this new element to it's internal event manager.
I don't wish to use onclick="blabla()", I really need to use jQuery.
How can I accomplish this?
What you are looking for is jQuery live. From docs description: "Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events."
There is also a plugin liveQuery that supports a wider range of events if you want.
the live() method will alleviate most of your headaches.
I see this happening more often in IE and with cloned elements, to support IE you have to be much more careful with DOM manipulation.
I also see alot of questions on SO with people having issues of copying/moving dom elements to new parts of the dom without cloning it first, which doesn't workout so well in IE.
So you can use live or when you have to handle events from dynamically inserted DOM elements, make sure you clone them with clone(true) to specify you want the events copied:
$("body").append('<div id="one"></div>");
$("#one").mouseover(function(){});
$("body").append( $("#one").clone(true).attr('id','two') );

Categories