jQuery Mobile transitions and AJAX Polling on a MasterPage - asp.net-mvc-3

I am trying to use AJAX polling with jQuery to update a span element on a razor MasterPage in ASP.NET MVC3. The page uses the jQuery Mobile 1.0 framework that adorns simple view changes (like navigating from /home to /about) with some sort of "transition" animation.
This is the Javascript code that does the polling, while the "unreadBubble" span is located in the body - both are defined in the MasterPage!
<script type="text/javascript">
$(document).bind("pageinit", function poll() {
setTimeout(function () {
$.ajax({ url: "/Notification/GetUnreadNotificationsCount",
dataType: "json",
success: function (data) {
$('#unreadBubble').text(data.UnreadCount);
poll();
}
});
}, 1000);
});
So, imagine I have a HomeController and a NotificationController that both use the MasterPage and provide an Index view. The AJAX polling works on both views and updates the span every second as expected. As soon as I navigate from one view to another though, the span gets re-initialized with its default value from the MasterPage (empty) and doesn't update anymore. Interestingly the async GetUnreadNotificationsCount method is still called on the NotificationsController repeatedly - the span just doesn't update. I also tried to alert the span tag in JS and it wasn't null or something.
According to the documentation, jQuery Mobile also loads new pages with AJAX to insert this fancy "SWOOSH" transition animation. This seems to somehow disturb the JS/DOM initialization.
Do you have any idea how to resolve this? Should I bind to another event or can I somehow force the span tag to update?
Solution: It was a caching problem! The following did the trick:
Add class="command-no-cache" to your page div add the following JavaScript to the MasterPage:
$(":jqmData(role=page)").live('pagehide', function (event, ui) {
if ($(this).children("div[data-role*='content']").is(".command-no-cache"))
$(this).remove();
});

I would use the pagebeforeshow to actually bind the event, and pagehide to remove the event.
Did you try that instead of initializing only once in the pageinit event?
UPDATE: some code for example,
<script type="text/javascript">
var timer = null;
$(":jqmData(role=page)").bind("pagebeforeshow", function() {
timer = setTimeout(function() {
$.ajax({ url: "/Notification/GetUnreadNotificationsCount",
dataType: "json",
success: function (data) {
$('#unreadBubble').text(data.UnreadCount);
}
});
}, 1000);
});
$(":jqmData(role=page)").bind("pagehide", function() {
if (timer != null){
clearTimeout(timer);
timer = null;
}
});
</script>
Also corrected some other ""mistypes" along the way, have a look and compare to your code!
Hope this helps

Related

Jquery inside Ajax loaded page does not work

When I use
$('body').html(data1)
or
$('html').html(data1)
in AJAX, then any HTML tag or jQuery function does not work on the loaded page.
$.ajax({
type:"GET",
dataType: 'html',
url: 'hell.php',
success : function(data1) {
alert(data1);// will alert "ok"
$('body').html(data1);
},
});
The events you attached before $('body').html(data1) will not fire simply because the elements previously in the body will not exist anymore.
You have to re-attach the events or use .on() method and attach events directly to document.
better use jQuery live function, when attaching event handlers.
See: http://api.jquery.com/live/
First, define the functionality you want to attach to the loaded elements in a function, e.g.:
function attachEventsAfterAjax(){
$('.aLoadedElement').on('click', function(){
console.log('Yay!');
return false;
});
}
Then, after you've loaded your new content, call that function, e.g.:
$.ajax({
[...],
success: function(data){
// Don't replace the <body> HTML, that's not a good idea
// $('body').html(data);
$('#container').html(data);
// Now attach the functionality!
attachEventsAfterAjax();
}
});

reload page when clicking on current page link, using jQuery Address plugin

I am using jQuery Address plugin, and all my ajax navigation is based on it, and more precisely on internalChange or externalChange events like that
$(document).ready(function() {
initDeepLinking();
});
function linkClicked(e){
var request = $.ajax({
url: e.path,
data: e.queryString,
type: "GET",
dataType: "json",
});
request.done(handleResponse);
return false;
}
function handleResponse(response, textStatus, jqXHR){
$('#main').html(response.responseText);
};
function initDeepLinking(){
$.address.internalChange(function(event){
linkClicked(event);
});
$.address.externalChange(function(event){
linkClicked(event);
});
}
so when i click on a link leading to the current page, nothing happens.
I would like the page to reload when I do that. Any simple options ?
Thanks !
I am having troubles understanding what your question really is:
you don't know how to attach a handler to the link
you don't know what statement can be used to refresh the current page
In order to set a handler you can use some selector. For example, getting the element by class. More about jquery selectors here.
After you have the element, you can attach an event handler for the 'on click' event and do something like this:
window.location.reload(true);

Jquery load in Dialog is repeated exponentially

I have a really annoying issue with jQuery and/or the jQuery UI Dialog Box.
After clicking on a special link a modal dialog will pop up with some loaded content (ajax) and inside this loaded content are new links/buttons that load their url inside the same div Box, so the dialog still is loaded, but with new content then. The Problem is, that if you link on that link (inside a fresh loaded dialog box and on a recently reloaded website) it works as it should, but with the second click it loads the url twice, with the third it loads 4 times ... It growing exponentially with every new link loaded inside the dialog. I testet this with a counter stored inside $_SESSION.
This is the Javascript Code:
var somedialog = $('<div></div>').dialog({
autoOpen: false,
resizable: false,
modal: true,
/*show: 'fade',
hide: 'puff',*/
closeOnEscape: true,
close: function(){
}
});
function openInDialog(url, title, width, height)
{
somedialog.empty();
somedialog.dialog("option", "width", width);
somedialog.dialog("option", "height", height);
somedialog.dialog("option", "title", title);
somedialog.load(url,{},function (responseText, textStatus, XMLHttpRequest)
{
somedialog.dialog('open');
}
);
//somedialog.load(url,{},function (responseText, textStatus, XMLHttpRequest){
// dialogdiv.somedialog('open');
//});
}
$('a.ajaxBuyItemDialog').on('click',function(){
openInDialog(this.href, this.title, 400, 300);
//prevent the browser to follow the link
return false;
});
There seemed to bee other people with this issue, but that was not a very effective discussion: https://stackoverflow.com/questions/6471360/jquery-load-after-load-repeated-results-problem
Thanks for your help!
EDIT:
This is part of the code which is located in the loaded script:
$("#_BUYITEM_FORM").live('submit', function(){
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response){ // on success..
$("#_BUYITEM_CONTENT").html('<p class="AjaxLoaderImg"><span>Einen Moment bitte...</span></p>');
$("#_BUYITEM_CONTENT").html(response); // update the DIV
}
});
return false; // cancel original event to prevent form submitting
});
Without it I can't get it to refresh the dialog box with new content.
It seems that your javascript code is replicated in every $('a.ajaxBuyItemDialog') destination page clicked. Adding that script to the dialog again at every click causes event to be triggered more than once.
If you reload the script numerous times it will add a new submit handler to form each time since you are using live().
live() will delegate the handler to the document and thus should either only be called once or you need to call die() before script loads each time.
if you were to get rid of using live() you could move the submit handler to the success callback of load() and use submit() rather than live(). If the original form is replaced...the original submit() event handler will also be gone
"Dirty" solution
function watchBuyItemForm(){
$("#_BUYITEM_FORM").submit(function(){
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response){ // on success..
somedialog.html(ajaxLoader);
somedialog.html(response); // update the DIV
watchBuyItemForm();
}
});
return false; // cancel original event to prevent form submitting
});
}

Return false not working for jQuery live

Well this has me well and truly stumped. After searching for the last few hours I still cannot seem to work out where I am going wrong.
I am trying to append an AJAX response to a container when it gets clicked. That works fine but I don't want it to append another object when the elements from the AJAX response also gets clicked.... so:
<div id="container">
<!-- AJAX response to get inserted here, for example -->
<span id="ajaxResponse"></span>
</div>
Here is my script:
$('#container').click(function(e) {
var current_el = $(this).get(0);
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
}
});
return false;
});
So it works fine but for some reason the click event on #container also fires when I click on the AJAX response span!?
According to jQuery documentation:
To stop further handlers from
executing after one bound using
.live(), the handler must return
false. Calling .stopPropagation() will
not accomplish this.
But unless I am mistaken, I am calling false? :(
Anyone help me out on this?
UPDATED:
So the only way I can get it to work is by updating my code to this:
$('#container').live('click', function() {
var current_el = $(this).get(0);
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
}
});
});
$('#ajaxResponse').live('click', function(e) {
return false;
});
This seems a little messy though... anyone have a better solution?
Where is live part you mention in the title of the question ?
It is how the event model works.. If you click on element which does not handle the event, the event will travel up the DOM hierarchy until it finds an element that handles the click (and stops its propagation..). Otherwise you would not be able to put an image inside a <a> tag and click on it..
You can bind a canceling handler on the inner element assuming you have someway to target it..
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
// assuming the returned data from ajax are wrapped in tags
$(current_el).children().click(function(){ return false;});
}
});
I think the return false is referring to something else in this case...
you should try calling stopPropagation() - this should stop the "click" function from propagating down to the ajaxResponse span....
One option that you may want to try is switching over to using live(). Essentially, the click event you setup is calling bind(), and the solution you referenced is using live() which is a variation on bind().
For example:
$('#container').live("click", function(e) {
var current_el = $(this).get(0);
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
}
});
return false;
});
HTH

jquery ajax post - not being fired first time

I'm trying to do an ajax post after a button is clicked, and it works in firefox but not in IE the first time the page is loaded. It does work if I refresh the page and try again second time - but not first time and this is crucial.
I've scanned over various web pages - could it be anything to do with the listener? (I've just seen this mentioned mentiond somewhere) Is there something not set correctly to do with ajax and posting when page first loads?
$(document).ready(function() {
$('#btnCont').bind('click',function () {
var itm = $("#txtItm").val();
var qty = $("#txtQty").val();
var msg = $("#txtMessage").val();
var op_id = $("#txtOp_id").val();
//if i alert these values out they alert out no prob
alert(itm+'-'+qty+'-'+msg+'-'+op_id);
$.ajax({
type: "POST",
url: "do_request.php?msg="+msg+"&itm="+itm+"&qty="+qty+"&op_id="+op_id,
success: function (msg) {
document.getElementById('div_main').style.display='none';
document.getElementById('div_success').style.display='block';
var row_id = document.getElementById('txtRow').value;
document.getElementById('row'+row_id).style.backgroundColor='#b4e8aa';
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Error submitting request.');
}
});
});
I would start debugging the click event. I.e. if you try to put .bind into a a href tag, the tag itself has a click event that may act on an unwanted way. There exist a command that are named something like event.preventDefaults() that avoids the standard feature of click. After All, you try to manipulate the DOM last of all actions (document.load).
$('#btnCont').bind('click',function () { .. }
I would also try to debug the same functionality with adding onClientClick to the tag instead of adding bind to the document load.
I hope that bring some light.

Resources