In jQuery Mobile, how do you target the element created using loadPage? - callback

I load a "page" into the DOM using $.mobile.loadPage(). I then want to target the element created, but I haven't figured out how to do this. This is what I thought would work:
var toc = $.mobile.loadPage('toc.html');
toc.trigger('customevent');
The above does not work in part because toc is a "deferred promise object" rather than a good ol' jQuery DOM reference. Additionally, it does not work because the second line is triggered before loadPage finishes. Is there a way to fire a callback after loadPage?
Thanks!

If you know the id of the page being loaded then you can bind the 'pagecreate' event to that object with .live() like so:
$('#blah').live('pagecreate', function () {alert('created');});
This will fire after the page has been loaded into the dom.

I just was just able to figure this out, even if you don't have the id, here's an example of how i am performing an action (fadeIn) on the the inserted element....
$(document).bind('pageload',function(evt,data){
$(document).unbind('pageload');
$(data.page).fadeIn();
});
$.mobile.loadPage('mypage.html',{'pageContainer':$('#my_item')});

You can use pageshow in order to fire a callback when the page is loaded. Please refer to the jQuery Mobile Events API for more detail.
An example would be something like:
$('div').live('pageshow',function(event, ui){
...
});

Related

Waiting for sap.ui.table.Table rendered after bound model has changed

I have sap.ui.table.Table which rows are bound to an JSONModel.
var oListModel = new sap.ui.model.json.JSONModel();
//oTable created here (sap.ui.table.Table)
oTable.setModel(oListModel);
oTable.bindRows("/");
When the table is rendered, i.e. the DOM is created for this table, i need to reference to the DOM to pass the DOM elements (table rows) to a library which will make them draggable.
My problem is: How do i know when the DOM for the table is created after the model has been changed and the table is rerendered? I didnt find any listener. The view controller's listener onAfterRendering() didn't help me.
The model is filled with data after a XMLHTTPRequest is successful. When i set the model in the success handler of the xht request and try to access the DOM elments directly afterwards they don't exist yet.
Thank you for your help!
You can add an event delegate
var oMyTable = new sap.ui.table.Table();
oMyTable.addEventDelegate({
onAfterRendering: function() {
$table = this.getDomRef() ....
}
});
a better way is to extend the control see Using addDelegate to extend a control to use third party functionality
UPDATE
the example in that blog doesn't work anymore fixed here
I had a similar issue recently where i had to access an element after a smartform (where the element is present) rendered onto the view. I posted my query here as well as my final solution (based on the accepted answer of #Dopedev). I am using XML views - including nested XML views - here however and the onAfterRendering didn't help for me as well.
I guess you could look at this solution - like it's mentioned in the accepted answer, it may not be an optimal solution, but it sure works. In my case there is not much of a performance issue with the binding of the DOMNodeInserted since it is being called in the onAfterRendering of the nested view that consists of only the smartform with an immediate unbinding upon finding.
The condition if (id === "yourtableid") { } should be enough to identify and pass on. Since you have a table and thus several child nodes, unbinding is imperative at this point.
Mutation Observer is the preferred method but i guess you may need to check the browser compatibility table at the end of the page to see if it matches your requirements. There is an example here. I have used Mutation Observer (outside of a SAPUI5/openUI5 environment) earlier and found it very convenient(and performant) to listen to DOM insert events. In fact the sap.ui.dt package consists of MutationObserver.js

Testing modal dialogs with zombie.js

I have some input fields inside a modal dialog like so (that's jade):
.modal-body
.control-group
label.required(for="event-planner-email")= Email
.input
input#event-planner-email(name="email", type='text')
.control-group
label.required(for="event-planner-name")= Name
.input
input#event-planner-name(name="name", type='text')
And I would like to be able to fill them out in a test. I tried pressing the link that opens the modal and filling the fields using zombie.js browser object, code in coffee follows:
browser.clickLink 'a#open-planner', () ->
browser
.fill('event-planner-email', someEmail)
.fill('event-planner-name', someName)
.pressButton 'Create', () ->
do done
But I get an error saying: "No INPUT matching 'event-planner-email'". If anyone knows how to do this, help would be much appreciated. Thanks!
Maybe the modal has not come into view yet by the time your call back is firing. If there is a transition happening to show the modal, you'll have to wait for that transition to complete.
Maybe try adding a setTimeout in your call back of the clickLink:
browser.clickLink 'a#open-planner', ->
fillForm = ->
browser
.fill('event-planner-email', someEmail)
.fill('event-planner-name', someName)
.pressButton 'Create', ->
do done
setTimeout fillForm, 1000
From the Bootstrap docs
You need to run your zombie code after the modal loads, so you should use the "shown" event
$('#myModal').on('shown', function () {
// zombie
})
I'm not sure how to represent that in coffee
Thanks everyone, turns out I just didn't use the proper css selector for the input elements, so instead of
.fill('event-planner-email', someEmail)
should be
.fill('input#event-planner-email', someEmail)
Because in jade snippet above, 'event-planner-email' is the id of the input element. Wanted to delete my question, so that I don't expose my stupidity any further, but apparently it's too late.

jQuery event handler .on() not working

I want to attach a event to dynamically created element class.So i used live function but it was not triggered. So checked live function reference ,there i red below notes
As of jQuery 1.7, the .live() method is deprecated. Use .on() to
attach event handlers. Users of older versions of jQuery should use
.delegate() in preference to .live().
so decide to use on function,But it still not working.The text field is already attached with jquery ui datpicker.On another element select i disabled that field.
jQuery("#from").attr('disabled','disabled')
.removeClass('date_picker_bg')
.removeClass('hasDatepicker')
.addClass('date_picker_disabled');
after disabled if i click i want to show alert or tooltip.so i tried this,but not working
jQuery(".date_picker_disabled").on("click", function(event){
alert('hi');
});
What may be the problem
I am using jquery 1.7.1 ( jquery-1.7.1.min.js)
The problem is that jQuery(".date_picker_disabled") finds elements with that class and binds to them. If elements don't have the class at the time the binding is made, the events will not be handled.
The on function allows you to get round this by handling them on another element when the event "bubbles up to" a parent element. In this instance, we could say the body element – there may be a more specific common parent you could choose.
jQuery(document.body).on('click', '.date_picker_disabled', function(event) {
alert('hi');
});
The event handler is now bound to the document.body element. All clicks that happen anywhere in the body are tested to see if they originated from an element matching the selector. If so, the handler is fired.
This is explained on the documentation for the on function. It is the same behaviour as was present in previous versions of jQuery with live and delegate functions.
Having taken another look at your code, you have disabled="disabled" set on your input element. click events are not fired on disabled elements.
This is tricky.
When your code runs, your element does not have .date_picker_disabled class so your jQuery(".date_picker_disabled") returns nothing and .on() is not called.
Apply .on() on the outer element and use the selector parameter:
// you can also do $(document).on()
$(<outer element>).on('click', '.date_picker_disabled', function() {
// do something
});
This will delegate the event to the <outer element>. The handler will only be executed if an element with class .date_picker_disabled has been clicked (second param).
From the documentation of .live():
Rewriting the .live() method in terms of its successors is
straightforward; these are templates for equivalent calls for all
three event attachment methods:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
So in your case, you would do:
$(document).on('click', '.date_picker_disabled', function(event){
alert('hi');
});
I was using jQuery 1.7.2 and tried all proposed methods:
Didn't work:
$(document.body).on('click', '.collapsible-toggle' function() {
console.log('clicked');
});
Didn't work:
$(document).on('click', '.collapsible-toggle' function() {
console.log('clicked');
});
None of them worked until I tried the following:
----- Worked! ----
$('body .collapsible-toggle').on('click', function() {
console.log('clicked');
});
Maybe you should do:
jQuery("body").on("click",".date_picker_disabled", function(event){
alert('hi');
});
in this way you attach the event handler to the bosy and specify to fire that event only when that selector ".date_picker_disabled" is matched.
BTW this is exactly how live() worked
try :
$(document.body).on( "click", ".date_picker_disabled", function() {
alert('hi');
});
document.body helps for dynamic html too.
Just chekc it out: .on not working on dynamic html

How to call a function (non AJAX) after another function (non AJAX) finishes in Dojo?

This is not an AJAX request/response callback question...
I am building a grid using Dojo 1.5. I am trying to dojo.connect expand/contract buttons with a function. My problem is that the grid.startup() method seems to take a while after being called before the actual DOM nodes are created, so when I call dojo.query none of the DOM nodes I want to connect events and handlers to are present.
I have the grid being created inside an init() method, which is called by dojo.addOnLoad(). I have the connectExpandos() method connected to init() via dojo.connect("init", connectExpandos); This executes fine, but I need to setTimeout() within a while loop to wait for the grid.startup() to finish...
Anyone aware of a better way to do this? Perhaps a grid.startup() callback I can hook onto?
Another suggestion... it looks like the "startup" function, which is implemented in DataGrid's super class, _Grid (http://svn.dojotoolkit.org/src/dojox/trunk/grid/Grid.js), calls a function called render, which i believe is what actually render's the contents of the Grid. Subsequently, it looks like render calls a method "postrender" after it has finished rendering. Perhaps you could connect your method to the "postrender" method instead of "startup".
dojo.connect(grid, "postrender", function(){connectExpandos()})
I think the callback you were looking for was _onFetchComplete
dojo.connect(grid,'_onFetchComplete',function(event){
alert("hello data is loaded")
});
I think you can just connect an event to grid startup method
dojo.connect(grid, "startup", function(){connectExpandos()})
You could try creating the widget programatically (assuming you are not already), then just call your method after you call startup() (It seems odd to call startup() manually, but the example it shows in the source comments show calling grid.startup() manually).
<script type="text/javascript">
var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
... }, dojo.byId('gridDiv'));
grid.startup();
connectExpandos();
</script>

jQuery: attach .fancybox() to a new element passed by .load() function

When I get new elements from load() function can't find the way to attach the function .fancybox (a lightbox plugin) to elements.
I've tried with .live() and .delegate(), but think .fancybox() could not be considered as custom event. I probably miss something... :(
You must wait until the DOM has been updated after the load. Add a one-shot timer in the success function called by load(). That should do the trick.
You need to trigger your fancybox after your content has loaded. Use a callback function.
$('#result').load('your/content.html', function() {
// after load trigger your fancybox
alert('Load was performed.');
});
Further information: jQuery .load()