not understanding event-delegation with jquery ui tabs - jquery-ui

I'm just not getting event delegation with jquery ui tabs, or at all!
I got the code for jquery ui tabs and loading the pages with ajax working perfectly. However I'm having trouble understanding event-delegation. I load 4 tabs with external content, depending on the tab which is opened. Inside those tabs I would like to attach the same widgets to the input buttons and links. So far my code looks like this
JS for rest of page already loaded
$("button, input:submit, a", ".create_button").button();
$("a.edit_button").button({
icons: {primary: 'ui-icon-pencil'}
});
$("a.delete_button").button({
icons: {primary: 'ui-icon-circle-close'}
});
$("a.active_button").button({
icons: {primary: 'ui-icon-lightbulb'}
});
JS For Tabs:
<script type="text/javascript">
$(document).ready(function() {
$("#tabs").tabs({
ajaxOptions: {error: function(xhr, status, index, anchor)
{$(anchor.hash).html("Could not load");}},
selected: 0})
});
</script>
HTML
<div id="tabs">
<ul>
<li>Pass Information</li>
<li>Entries</li>
<li>Event Administration</li>
<li>Profile</li>
</ul>
</div>
I've learned here on stack overflow that I have to attach a click event to my #tabs div with live(). Best guess anyway.
however I cannot find any examples that work for me and my limited understanding of event delegation.
Any help is appreciated.
Rick

Right now, you have "error" being handled, but nothing else. You need to handle "success" or "complete"... actually, why are you using AJAX at all? You don't appear to be requesting any data from off of the page?

It seems like the key to your question is this:
Inside those tabs I would like to attach the same widgets to the input buttons and links.
Sounds like you want to use the "show" method of the tabs widget:
$(document).ready(function() {
$("#tabs").tabs({
ajaxOptions: {error: function(xhr, status, index, anchor)
{$(anchor.hash).html("Could not load");}},
selected: 0,
show: function() {
$([selectors for buttons or jQuery UI widgets in your tabs]).button();
}
})
});
FWIW, this question is not really about event delegation. That article is useful in understanding the concept.

Turns out that .live() only works on events. So though I could bind something to the links, it would not actually take affect until the link has an event take place, i.e. click or hover.
A workaround would be to dynamically add events to the links with the loaded content, but that is quite tricky and adds a lot of overhead to the application. Instead I chose to style things within loaded content in a different way. In the process of learning about this, I did end up using live() for form submission and a reload of the content after the submission takes place.
Thanks guys for your help. RwL. You ended up not actually answering the question, but your prodding sent me in the right direction and I learned a lot. I was ultimately able to solve the problem myself. You know, give a man fish or teach him to fish, yadi yadi yadi...
Thanks!

Related

Jquery Multiple Dynamic Accordion Creation

I am creating multiple jquery ui accordions dynamically on a page.
The render of the page takes a realllly long time and it gets stuck on the creations of the accordions.
Is there a way to create multiple accordions on the same moment?
Thank you
EDIT
Think I have a few hundered h3 & divs on my screen and on load of the page i call this function:
function createAccordion(accordion) {
if (typeof accordion == 'undefined')
accordion = '.accordion';
$(accordion).accordion({
active: false,
collapsible: true,
animate:false,
heightStyle: 'content'
});
}
You could try using Html5 web workers. This is designed to free up the UI thread when doing large amounts of processing. See example on w3c schools
Alternatively you might want to look at setTimeout patterns. A good example here.

jquery-mobile: How do I not add a page to the history stack

I have an application which includes a series of forms, each on their own page.
I do not want some of these pages to be added to the history stack. So that when the user presses back, it skips them.
Jquery-mobile does this with dialogs. You can configure this to happen with ALL pages (or any other data-role) but not with just some pages.
Does anyone know how to do this? Alternatively, would it be possible to create a new data-role that extends "page". If that was possible, then I could disable history for all of those pages.
in this case, you can call $.mobile.changePage() by yourself:
$.mobile.changePage( "url", {
changeHash: false //do not track it in history
});
http://jquerymobile.com/demos/1.2.0/docs/pages/page-navmodel.html
http://jquerymobile.com/demos/1.2.0/docs/api/methods.html
I was facing the same issue and I was going berserk!!! Finally, I was able to do it with the following code that does just that!
The code below automatically prevents storing the changed locations for all pages in the current document.
Please note that it has been tested with jqm 1.4.2
<script>
$(document).on("pagebeforetransition",function(event, ui){
ui.options.changeHash = false;
}) ;
</script>
Hope it helps
Checkout this question, pretty much the same as what you are trying to do.
How to modify jQuery mobile history Back Button behavior
Thanks,
Alex.

Can you define tooltips in Dojo wijit template?

I've been trying to get a Dojo (1.6) dijit.Tooltip to work when defined in a wijit template.
So, if I have wijit template that includes the following:
<a data-dojo-attach-point="tooltipMe" href="" onclick="return false;">
Show a Tooltip
</a>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'tooltipMe'">
Got to love hovering over links. Sometimes you a get a free tooltip
</div>
I can see the link of course, but nothing happens when I hover. Scouting round the newsgroups it seems there might be a problem with defining tooltips in wijit templates, but it's not mentioned in the Dojo docs.
Is it possible to define tooltips inline like this? Or am I just doing something wrong, it seems like the obvious place to do it.
If not, is there an accepted approach for creating and linking tooltips to DOM nodes defined in wijit templates?
Tooltips connectId property has to be the id of a DOM node. data-dojo-attach-point is not an id, it just creates a reference in the instantiated widget.
So in your case you need to assign an id to the a-node and use the same id in connectId. To avoid id clashes when creating multiple instances of your widget you can use the ${id} variable substitution to ensure that all ids are unique:
Your code should look something like this:
<a id="${id}_link" data-dojo-attach-point="tooltipMe" href="" onclick="return false;">
Show a Tooltip
</a>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'${id}_link'">
Got to love hovering over links. Sometimes you a get a free tooltip
</div>
I've had problems doing it this way before. I used script to create them on my page after I had done some other work, maybe something like this will help you out if you use it in the template postCreate method.
var span = dojo.query('.hasEntry span').forEach(function(node, index, nodelist)
{
new dijit.Tooltip({
connectId:node,
position:"above",
label: toolTipLabel
});
});
Responding to an old thread here, but just wanted to share a solution for people looking to use tooltips without IDs on their custom widget elements. It's not as pretty as just using tooltip, but it works. It uses the "dijit/popup" and "dijit/TooltipDialog" modules.
this.editTooltipDialog = new TooltipDialog({
content: "<p>I love tooltips</p>",
onMouseLeave: function(){
popup.close(this.editTooltipDialog);
}
});
on(this.targetDiv, 'mouseover', lang.hitch(this, function(){
popup.open({
popup: this.editTooltipDialog,
around: this.targetDiv
});
}));
I tried to replicate the issue in jsFiddle: http://jsfiddle.net/phusick/EcLLb/.
I found out that dijit.Tooltip widget from the template is instantized, but it does not connect mouse events, presumably because DOM node it attempts to connect to does not exist yet (i.e. has not been added to document DOM tree).
To prove the aforementioned I tried to connect the tooltip in widget's postCreate method, when all DOM building is done and it worked:
postCreate: function() {
this.inherited(arguments);
this.tooltip1.set("connectId", this.tooltipMe); // w/o this the tooltip won't show
}
So you can instantize tooltips via a template markup and then just connect then to DOM nodes in postCreate method.

jQuery Mobile Page refresh mechanism

I'm having a lot of pain understanding how jQuery Mobile handles pages refresh after an ajax update.
I'm having a two pages - unique file site: a search engine.
First page is a search field. Submit triggers a JSON call and parser which updates the second page: results.
for now i'm using: $.mobile.changePage( $('#result') ); which does the job great from search field to result page.
However:
If I reuse it from result page for next/prev pages ( new json call, new parse, new added nodes in the DOM );
Jquery Mobile just don't "paint" the newly added nodes.
can anyone explain, please the use and distinction of
1- $.mobile.page()
2- $.mobile.changePage()
3- $.mobile.refresh()
or give me a hint on how I should handle page changes.
thanks!
function refreshPage()
{
jQuery.mobile.changePage(window.location.href, {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true
});
}
Taken from here http://scottwb.com/blog/2012/06/29/reload-the-same-page-without-blinking-on-jquery-mobile/ also tested on jQuery Mobile 1.2.0
Please take a good look here: http://jquerymobile.com/test/docs/api/methods.html
$.mobile.changePage() is to change from one page to another, and the parameter can be a url or a page object. ( only #result will also work )
$.mobile.page() isn't recommended anymore, please use .trigger( "create"), see also: JQuery Mobile .page() function causes infinite loop?
Important:
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.
$.mobile.refresh() doesn't exist i guess
So what are you using for your results? A listview? Then you can update it by doing:
$('ul').listview('refresh');
Example:
http://operationmobile.com/dont-forget-to-call-refresh-when-adding-items-to-your-jquery-mobile-list/
Otherwise you can do:
$('#result').live("pageinit", function(){ // or pageshow
// your dom manipulations here
});
I posted that in jQuery forums (I hope it can help):
Diving into the jQM code i've found this solution. I hope it can help other people:
To refresh a dynamically modified page:
function refreshPage(page){
// Page refresh
page.trigger('pagecreate');
page.listview('refresh');
}
It works even if you create new headers, navbars or footers. I've tested it with jQM 1.0.1.
I found this thread looking to create an ajax page refresh button with jQuery Mobile.
#sgissinger had the closest answer to what I was looking for, but it was outdated.
I updated for jQuery Mobile 1.4
function refreshPage() {
jQuery.mobile.pageContainer.pagecontainer('change', window.location.href, {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true
// 'reload' parameter not working yet: //github.com/jquery/jquery-mobile/issues/7406
});
}
// Run it with .on
$(document).on( "click", '#refresh', function() {
refreshPage();
});
I solved this problem by using the the data-cache="false" attribute in the page div on the pages I wanted refreshed.
<div data-role="page" data-cache="false">
/*content goes here*/
</div>
In my case it was my shopping cart. If a customer added an item to their cart and then continued shopping and then added another item to their cart the cart page would not show the new item. Unless they refreshed the page. Setting data-cache to false instructs JQM not to cache that page as far as I understand.
Hope this helps others in the future.
This answer did the trick for me http://view.jquerymobile.com/master/demos/faq/injected-content-is-not-enhanced.php.
In the context of a multi-pages template, I modify the content of a <div id="foo">...</div> in a Javascript 'pagebeforeshow' handler and trigger a refresh at the end of the script:
$(document).bind("pagebeforeshow", function(event,pdata) {
var parsedUrl = $.mobile.path.parseUrl( location.href );
switch ( parsedUrl.hash ) {
case "#p_02":
... some modifications of the content of the <div> here ...
$("#foo").trigger("create");
break;
}
});

JqueryMobile page initialization function

I am using a master page on a JQuery-Mobile app that have few controller , and I want to set up a Javascript call to an initialize function on every page even when it loads through Ajax,
Iam sure there are few ways to do that, but whats the best approach and what would be the alternative to $(document).ready when the page is called through ajax instead of being directly loaded without that.
takepara's answer is correct, but...
If you want to modify the content of the page you will have to bind earlier.
Take a look at beforepagecreate event.
If your handler for this event returns false, then no JQM widgets and styles will be applied and you can work with it manually.
jQuery Mobile Docs - Events
$('div').live('pageshow',function(event, ui){
alert('This page was just hidden: '+ ui.prevPage);
});
or
$(document).bind("pageshow".function(){
// initialize code here
});

Resources