How to create JQuery-UI widgets dynamically - jquery-ui

I understand that I can use .on to bind functions to DOM elements when some event occurs on an element.
I have been using JQuery-ui, and I want to create different JQuery-ui elements once they have loaded on the page. For example, create a button when one is loaded on the page:
$(document.body).on('load', '.my-button', function(){
$(this).button()
});
However, this doesn't work (in fact, the handler is never reached).
How can I create JQuery-ui widgets when they load in the DOM?

jQuery does not fire any events when an element is created. Instead, use the watch plugin and run your button()s from there.

Related

How do programatically change the attributes of <sj:tabbedpanel>

I am using Struts jQuery plugin. Problem is with <sj:tabbedpanel>.
I want to preselect the tab depending on the input while loading the page.
I know there is property selectedTab="1".
But I want it to change it while loading the page using jQuery.
In jQuery-UI plugin, there is function $("#tab").tabs('selected',2) which does that.
What is the similar function which does the same thing here.
Try this:
<sj:tabbedpanel id="tabbed" selectedTab="%{selected}"></sj:tabbedpanel>
selected should be a parameter, which decides the opened tab.
If you still wanna use jQuery, please check the api: jQuery Tabs API
here is the important part:
A series of events fire when interacting with a tabs interface:
tabsselect, tabsload, tabsshow (in that order)
tabsadd, tabsremove
tabsenable, tabsdisable
If you want to do this from javascript then use option to set selected tab.
$("#tab").tabs( "option", "selected", 2);

How to bind backbone.js events to JQuery UI dialogue windows?

I'm very new to backbone.js but we're starting to use more and more JS on the front end and I wanted to use some framework to give the code structure - backbone seems to suit our needs.
So started off with a very simple test app that launches a dialogue window using jquery-ui. The problem I have is that since jquery-ui adds a wrapper DIV round the original template used by backbone, the events no longer fire.
I don't want to use the jquery-ui event model as I'd rather just use the one - how can I bind backbone's to this new structure?
It looks as though the call to _.template() is actually doing the wrapping in an extra div. The parent div with the events bound to it is being left behind appended to #well. A simple workaround is to call .parent() on the result of getting the element with the model class ID. See here for example
There's more than likely some information in the _ documentation that might shed some more light on the problem too.
OK - at the end of this project, I finally realised that I hadn't answered this. What happens is when you create a .dialog with JQueryUI, it actually detatches your original DOM element and moves it to the bottom of the DOM wrapped in it's own JQueryUI markup to turn it into a dialog.
Since the Backbone view's element has now been moved, Backbone doesn't pick up any events that fire as it's happening outside it's own "view" as far as it is concerned.
So what you have to do is reassign the view's element:
var dlg = this.$("#dialogue-properties").dialog({ ..});
this.setElement(dlg);
Where this is the view. This is done within the initialize method
You can create div wrapper in your view and modal it's content, as described here (first part of the post)
cocovan does a good job explaining the problem in his answer. However, as for the solution, the JQuery UI team actually added a method at the end of 2012 (Allow dialog to be attached to a element other than body) that takes care of this issue.
It is the appendTo(selector) method (jQuery Dialog appendTo method). So simply specify to which element you want the dialog appended.

jQuery Mobile - firing pageshow event only once

I am trying to execute a snippet of JS only once, after the page has completely loaded and JQM has taken care of all the ui modifications (i.e. listviews, buttons, etc.). I do want it to execute only on that page, and not on subsequent pages.
What I tried first, was pageshow
<script>
$('[data-role=page]').live("pageshow", function() {
alert("Ready!");
});
</script>
This has the problem that the function is now attached to the page div and gets executed every time any subsequent page gets shown. However, I only want this to be executed once, and only for the page that contains that JS snippet.
Is there a way to listen to the pageshow event, without actually attaching the function to it.
The only way I was able to do it was by binding and unbinding like this:
<script>
$('[data-role=page]').bind("pageshow.test", testfun);
function testfun() {
alert("Ready!");
$('[data-role=page]').unbind("pageshow.test", testfun);
}
</script>
But is there a more elegant way to do so?
jQuery has a one function to bind an event handler to be executed only once. Check the reference.
The pageinit event fires once per page just after the jQuery Mobile framework initializes its widgets; I think it may be what you're looking for.
pageinit
Triggered on the page being initialized, after initialization occurs.
We recommend binding to this event instead of DOM ready() because this
will work regardless of whether the page is loaded directly or if the
content is pulled into another page as part of the Ajax navigation
system.
Source: http://jquerymobile.com/demos/1.1.0-rc.1/docs/api/events.html
If you want to bind to a specific page and not the rest, then select only the page you want to alter... Here's an example:
<script>
$(document).delegate('#my-page-id', 'pageinit', function() {
alert("PageInit!");
});
</script>

Using specific elements of jQuery Mobile and not others

Is there any way of using jQuery Mobile for only certain features such as toggle on/off switches but not have it take over the entire CSS?
You can use native form elements:
http://jquerymobile.com/demos/1.0rc2/docs/forms/forms-all-native.html
Related:
Tell JQuery Mobile not to add classes?
You can set this per element with a data-role="none" attribute on the element or bind to the mobileinit event like so:
$(document).bind('mobileinit',function(){
$.mobile.page.prototype.options.keepNative = "select, input.foo, textarea.bar";
});
Notice how you can add classes to the selectors.
From the docs:
Or, if you'd like to prevent auto-initialization without adding
attributes to your markup, you can customize the selector that is used
for preventing auto-initialization by setting the page plugin's
keepNative option (which defaults to [data-role="none"]. Be sure to
configure this option inside an event handler bound to the mobileinit
event, so that it applies to the first page as well as subsequent
pages that are loaded.
Docs on this can be found here: http://jquerymobile.com/demos/1.0rc2/docs/forms/docs-forms.html

jQuery Mobile : calling JavaScript function

How can I call a JavaScript function while using jQuery Mobile?
Just like you would any other JavaScript function (considering jQuery IS JavaScript):
var myFunction = function(param1, param2){
// Do some work
}
myFunction(myValue, myOtherValue);
The same way you call a Javascript function without jQuery mobile.
This is not an answer to the question, but it adresses the OP needs.
When a page is loaded by jquery mobile, it is fetched with AJAX, so there is no DOMready anymore. Also - the contents of the page's head are not loaded. You have to put your code in a file and link it to all the pages. Then write pageshow event handlers.
Pages that jquery mobile loads in are always tagged with a data-url atribute. To get something done when the page is being displayed (just like it used to be with DOMready) you can:
$("div:jqmData(url='thatone.html')").live('pageshow',function(e){
//stuff
});
And this definition can be anywhere in the main page or in external scripts. It requires jQuery to be loaded. Thanks to the live method it doesn't require the page to exist before the event happens, or even at all.

Resources