AJAX jQuery UI modal dialog - jquery-ui

Edited to add the solution suggested by #alistair-laing.)
After reading this post reply by #jek, I could make multiple links on my page that would pass an id variable through the URL so that the content of the dialog could be loaded in on the fly. However, I really want this to be a modal dialog:
(edited to include the fix; nb: the original script was in the post linked to above, all I did was break it)
$(function (){
$('a.ajax').click(function() {
var url = this.href;
var dialog = $('<div style="display:none"></div>')
.appendTo('body')
// load remote content
dialog.load(
url,
{},
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog({
modal: true,
width: 500
});
}
);
//prevent the browser to follow the link
return false;
});
});

quiet a few things. Try move the content from your first .dialog into your second .dialog which you call as part of the the .load callback. What youare doing is creating dialog then injecting content into it only to call it again. You could also remove the the autoOpen so that the dialog opens with the content.

Related

JQuery mobile persistent navbar (outside page div)

I've got a navbar outside the page div in a footer (it is on every page) I tried to do a simple fix for the persistent active state of the navbar It worked for the tabs on one of the pages but does not seem to work for this.
Actually, everything works except for some reason ui-btn-active does not get added
Here is the code
$(document).one( "pageinit", function() {
$('div[data-role="footer"] [data-role="navbar"] a').click(function(e) {
$(this).html("abc");
$('div[data-role="footer"] [data-role="navbar"] .ui-btn-active').removeClass('ui-btn-active ui-state-persist');
$(this).addClass('ui-btn-active ui-state-persist');
});
});
The html of the anchor changes, ui-state-persist gets added on the last line but ui-btn-active just does not get added for some reason...
Ok it seems jquery mobile automatically removes ui-btn-active on page transition, even if your navbar is out of page div (which I find kind of lame...) It seems it does this on or after pagebeforeshow, because this did not work with that event... so I just used pageshow instead.
Here is the working code:
var navbar;
$(document).on("pageshow", function() {
if(navbar) {
$(navbar).addClass('ui-btn-active')
}
});
$(document).one( "pageinit", function() {
$('div[data-role="footer"] [data-role="navbar"] a').click(function() {
navbar = $(this);
});
});

How to stop jQuery Mobile calling $.mobile.loading('hide') during changePage?

I'm trying to stop jQuery Mobile hiding the loading spinner when changePage is called.
The program flow goes like this, starting with clicking a link, which has its click event defined like this:
$('body').delegate('.library-link', 'click', function() {
$.mobile.loading( 'show' );
$.mobile.changePage($('#page-library'));
return false;
});
Upon clicking the link, the pagebeforeshow event is fired, which triggers a function to populate the page from the local storage, or else make an ajax call to get the data.
$(document).on('pagebeforeshow', '#page-library', function(event){
ui.populate_data();
});
In ui.populate_data() we get the data from local storage or make an ajax call.
ui.populate_data = function() {
if (localdata) {
// populate some ui on the page
$.mobile.loading( 'hide' );
} else {
// make an ajax call
}
};
If the data is there, we load the data into the container and hide the loading spinner. If not it makes the ajax call, which on complete saves the data in local storage, and calls ui.populate_data()
The problem is, after the pagebeforeshow event is finished, changePage is calling $.mobile.loading( 'hide' ), even though the data might not be there yet. I can't find any way to prevent changePage from hiding the spinner, other than by temporarily redefining $.mobile.loading, which feels pretty wrong:
$('body').delegate('.library-link', 'click', function() {
$.mobile.loading( 'show' );
loading_fn = $.mobile.loading;
$.mobile.loading = function() { return; };
$.mobile.changePage($('#page-library'), {showLoadMsg: false});
return false;
});
and before hiding the spinner in my ui function:
ui.populate_data = function() {
if (localdata) {
// populate some ui on the page
if (typeof loading_fn === 'function') {
$.mobile.loading = loading_fn;
}
$.mobile.loading( 'hide' );
} else {
// make an ajax call
}
};
Surely there must be a way to get complete control over the showing and hiding of the loading widget, but I can't find it. I tried passing {showLoadMsg: false} to changePage, but as suggested by the docs it only does things when loading pages over ajax, which I'm not doing.
Maybe it's too much for many, but I found a solution other than the written in the comments (which didn't work for me).
I use the jquery mobile router and in the 'show' event of a page, I do $.mobile.loading("show");, so when the page appears it does with the loading spinner showing.
Though to hide the spinner, I had to use $('.ui-loader').hide();, which is weird, I know...
I use Jquery Mobile Router for a lot more, but it solved this issue.
(Maybe just listening to the proper event and triggering the spinner would also work, as this is what JQMR does...)
I'm using JQM 1.4.2...

jQuery $(document).ready() issue - jQuery 1.7.2

I have a page on which I am loading a select tag with options that I am getting from an ajax call to a service. It is working just fine and loading the select tag correctly. I only want this loading to happen once when the user first arrives at the page so I put the call to the function that does this inside the $(document).ready(function call. The problem that I am seeing is that when the user selects one of the options and then clicks a button under certain circumstances I pop a dialog (jQuery UI) telling them they need to take a certain action. The first time this happen and only the first time the selected option is getting reset somehow to the first option in the list. I ran in debug many times and discovered that if this is the first time on the page the selector is loaded on arrival at the page as is expected but if the dialog gets popped it is loaded again - only the first time - after that if the dialog gets popped the reload does not occur and all is well. The abbreviated code:
$(document).ready(function () {
$.fn.LoadStuff();
});
jQuery.fn.LoadStuff = function () {
//load up the select tag with options
};
LoadStuff does not get called anywhere else. selOffers is the select tag and dvConflict is the dialog. They are not sharing a common parent div.
<select id="selOffers"></select>
<div id="dvConflict"><div id="dvConflictMsg" /></div>
jQuery for the dialog:
var optSave = {
width: 400,
modal: true,
resizable: false,
draggable: false,
closeOnEscape: true,
zIndex: 1320,
buttons: [
{
text: 'Ok',
click: function () {
$(this).dialog('close');
}
}
]
}
$(".ui-dialog-titlebar").hide(); //Hides the title
$('#dvConflict').css('background', 'none'); //Takes out our custom background
$('#dvConflict').dialog(optSave);
EDIT: Two things
Use $.LoadStuff = function () { } instead of $.fn.LoadStuff = function () {...}. The first is to be called at any context via $.LoadStuff();. The latter is to be used on an element-selection, like $("div.to-load").LoadStuff();.
$(document).ready is fired every time the DOM finishes loading. In some AJAX calls, you could be reloading parts of your DOM, or an internal frame (I don't know, though I don't have your code).
The following code sample will help you bypass the problem:
var first = true;
$(document).ready(function () {
if (first) $.LoadStufF();
...
first = false;
}
When opening a dialog, make sure there are no <script> tags inside the dialog-wrapped element. Say you have the code line:
$('#dialoged').dialog({ ... });
So a bad practice is to have:
<div id="dialoged">
<script>
var first = true;
$(document).ready(function () {
if (first) $.LoadStufF();
...
first = false;
}
</script>
</div>

Get the referred link id on pagebeforeshow

In jqm I have something like this
<li>cats</li>
<li>dogs</li>
Page1 is a dynamic page and should load it's contents based on which link button I pressed and I use
$(document).on('pagebeforeshow', '#page1', function(event, data){
do something here with either cats or dogs
});
Now how do I determine here what link what used?
I could use sessionStorage or perhaps a
$('.loadPage').click(function(){
$(this).attr('id').blablabla
})
but it doesn't seem right to me. I'm sure the answer is there right in front of me, but I can't seem to get around it.
Any ideas?
You could store the id in #page1's data attribute on click of loadPage:
$(document).on("pageinit", "#page0", function () {
$(this).on("click", ".loadPage", function (e) {
e.preventDefault();
$("#page1").data("id", this.id);
});
});
Then, after jQM redirects you to #page1, check for the stored data :
$(document).on("pagebeforeshow", "#page1", function () {
alert($(this).data("id"));
// you can do anything with this id
});
Demo : http://jsfiddle.net/hungerpain/wN2L9/
compare the id:
if(this.id==='cats')
{
//do something here
}
On a side note you can use $(this).attr('id') also, but its better you use pure JavaScript whenever possible.

jquery mobile: how to create dynamic content only once, at page startup?

Here's what I want to do:
load basket using Ajax
show "wait" message
once loaded, refresh basket.
When I try to use pageinit function:
$(document).bind('pageinit', function(evt) {
console.log(evt);
}
Console log show it's called 29 times!
Everything is on one HTML page, and I'm using $.mobile.changePage() to change pages. So I tried this hack:
$(document).bind('pagebeforeshow', function(evt, pg) {
if (pg.prevPage.length==0) {
/* first page = code executed once */
var pg = $('#page-basket'),
footer = pg.children( ":jqmData(role=footer)" );
footer.hide().trigger('updatelayout');
AjaxGetBasket( function(data) { console.log('ajax basket ok'); });
}
});
But the layout is never updated.
How shall I do to modify page but only once at the beginning?
Try delegating the pageinit event handler so it only runs when #page-basket is initialized:
$(document).on("pageinit", "#page-basket", function() {
$(this).children(":jqmData(role=footer)").hide().trigger("updatelayout");
AjaxGetBasket(function(data) {
console.log("ajax basket ok");
});
});
I do not understand if your problem is solved, but i am in the same situation explained in the question and i have solved the problem binding a function to pagecreate event:
$(document).bind("pagecreate", function(e){
// call ajax and update the DOM of first 'page'
});
and that's all.

Resources