jquery mobile trigger 'create' not working except the first time - javascript

I am using jQuery Mobile to create a site, in the index page I placed here a form for a search. I hooked submit event for ajax post. When ajax success get the resource
(html,<ul>...</ul>), placed in the target container, then trigger the create event for enhance the view. This work fine in the first time. When I click back to index page and search again I got a raw listview without enhance, who can tell me why? ps: I have tried many methods but there is more and more problem, the official document was so poor.
$(document).bind('pageinit',function(){
$("#search").submit(function(){
var searchdata = $("#search").serialize();
$.ajax({
'type':"POST",
'url':"/server/jnulib.php?action=search",
'data':searchdata,
'success':function(data){
$("#searchresultfield > ul").remove();
$("#searchresultfield").html(data).find('ul').trigger('create');
try{
$("#searchresultfield > ul").listview('refresh');
}catch(e){
}
$.mobile.changePage("#searchresult");
//$("div[data-role='header'] > a").
}
});
return false;
});
});
EDIT: Test Url: http://ijnu.sinaapp.com
Another problem: the second ajax request failed and the browser navigate to the ajax target straightly.

You could try changing:
$("#searchresultfield").html(data).find('ul').trigger('create');
to:
$("#searchresultfield").html(data).find('ul').listview().listview('refresh');
Anytime you append or remove elements you need to refresh, and if you remove the whole list, you need to reinitialize it.
Also I have had issues with listview('refresh') rendering improperly if it was not visible.
$(document).on('pageshow','div',function(event, ui){
if($("#searchresultfield > ul").is(":visible")) $("#searchresultfield > ul").listview('refresh');
});

For me, .trigger('create'); always works if applied to the element with data-role="page"
For example
HTML Code
<div data-role="page" id="somePage">
...
</div>
Javascript Code
$('#somePage').trigger('create');
Hope it helps

Try:
$("#searchresultfield > ul").empty();
instead of
$("#searchresultfield > ul").remove();

I think the problem is that jquery mobile loads all pages despite all being from different files into one big page and navigation is based off going to different points in this page, so that when you go onto it the first time the page you access is considered created however when clicking the back button and navigating away from the page that page is still considered created so the event well not fire again,
What I used was:
$('#oppList').live('pageshow',function(event){
getList();
});
Where #opplist is the id of the data-role="page" for the page I just load, this does not matter whether this happens the first time the page is loaded or after because the event is fired whenever the page is displayed.
See Here foe jquery mobile events
Also see here for jquery mobile navigation
Hope this helps !

Maybe you should try to unhook the submit event once it's been handled. And initiate it again once you go back to the page where you were before. Adding eventhandlers multiple times can cause a lot of problems.

Related

ready function triggers in every page

I have a rails app, if the user is not logged in, I am redirecting to a page, which has one br tag with a class. Like this
<br class="logged">
In the Javascript on ready of that function, I am triggering a modal as follows.
$(document).ready(function(){
$('.logged').ready(function(){
$('#open-login').click();
});
});
This is working fine, except this modal is getting triggered on every page of the app. I mean that br tag is there in only page of the app, how it is ready for every page is what I don't understand. If anyone can tell what went wrong with my approach, it would be of great help.
ps: It's rails application
You can try this:
$(document).ready(function(){
if ($('.logged').length > 0)
$('#open-login').click();
}
});
Into if condition you can declare an element of specific page and in only that page you can execute an action.
The jQuery .ready() method can only be called on a jQuery object matching the current document. Attaching it to a $('.logged') selector still makes its handler function get called when the document is ready - it doesn't care about the selector.
MarcoSantino's answer will work for your needs, although you may find it cleaner to add the logged-in class to the body tag instead of inserting a new br tag, and then use the following in your JavaScript:
$(document).ready(function(){
if ($(body).hasClass('logged-in')) {
$('#open-login').click();
}
})

Reload page asynchronously or setTimeout?

I'm a bit lost.
I have two pages; Results and Detail. Whenever user navigates from Detail to Results using the browser back button, Results page should refresh, this way I can show what product user just seen on Detail (like amazon does with recently viewed items)
I don't know if it is better to load page asynchronously,
or use setTimeout as seen here (the example below works, but page refreshes forever)
if(window.top==window) {
// you're not in a frame so you reload the site
window.setTimeout('location.reload()', 3000); //reloads after 3 seconds
} else {
//you're inside a frame, so you stop reloading
}
and when I try reloading just a div also doesn't work
$('#div-id').triggerevent(function(){
$('#div-id').html(newContent);
});
I've also came across a lot of examples leading to this but didn't managed to make it work.
Any suggestion is welcome.
Thank you
The onload event should be fired when the user hits the back button. Elements not created via JavaScript will retain their values. I suggest keeping a backup of the data used in dynamically created element within an INPUT TYPE="hidden" or TEXTAREA set to display:none then onload using the value of the textbox to rebuild the dynamic elements to the way they were.
If you don't care about rebuilding the page and want to actually reload it, then you could do:
<input type="hidden" id="refreshed" value="no">
<script type="text/javascript">
onload=function(){
var e=document.getElementById("refreshed");
if(e.value=="no")e.value="yes";
else{e.value="no";location.reload();}
}
</script>
I believe you should reload the page asynchronously.
Maybe attaching the event ready to the body will work.
$(function(){
$('body').ready(function(){
alert('worked');
//Code to reload the page or data
});
});

Adding an extra button in facebook post using google chrome extension

I was successful to track all "uiStreamSource" that holds the link associated with each facebook post (status, image, etc) to add one extra button next to the date to do some other tasks using google chrome extensions. This button does a predefined job which not important to mention in this context.
I wrote this content script:
contentscript.js
var nodeslist=document.getElementsByClassName("uiStreamSource");
alert(nodeslist.length);
Each time a facebook page is loaded, the alert shows me 10 detected classes (i.e., 10 posts). But when I scroll down, new posts show up and this code fails to detect them. Since I need to update all uiStreamSource nodes in all posts, how can I solve this?
UPDATE
I tried this code in contentscript.js:
load();
document.addEventListener("DOMNodeInsertedIntoDocument", load, false);
function load(){
var nodeslist=document.getElementsByClassName("uiStreamSource");
alert(nodeslist.length);
}
The first time it runs, I get the correct number of the current nodes (current facebook posts) but once I scroll down and more posts are fetched, the alert shows up indicating that load function is called but the number of nodes printed is 0. Why is that?
Thanks on advance.
You can add a DOMNodeInserted event and check if the element that is going to be inserted is a post by checking its classes.
Or an easy solution is to use the jcade plugin. It can call a callback function when an element with specified selector is inserted.
Listen to the scroll event and add any new posts to nodeslist. You could use setInterval as well to catch any posts that are added when the user is not scrolling.

replacing content on pages that use ajax

I'm working on a extension for a fb game that adds some extra info to popup boxes, hides some useless information and run some timers so you can see how long till you have to do something even if you are not on the game page.
My problem is that a while back they went over to using ajax to change between pages and I am wondering if I am using the right approach to handle this.
I run a setInterval that checks if I am on a page where i want to add/remove soemting and i havent done it yet, if this is true I do my stuff, the code looks something like this:
function myFunction() {
if($(selector for some element I am looking for).length > 0 && $(selector for some item I add).length == 0) {
//do some stuff
}
}
setInterval("myFunction()",1000);
Is this the right way of handling ajax page change from an content script in an extension?
If so is there a better way to see if I am on the right page or if i have added to this page already other than doing a selection?
You can use livequery jquery plugin to catch when new element is created on a page:
$("#ajax-element").livequery(function({
//ajax-element is created
});
You can also listen to DOMSubtreeModified event which fires when DOM changes:
document.addEventListener("DOMSubtreeModified", function(event){
//something has changed, possibly ajax-element was added
});
There are also more specific DOMNodeInsertedIntoDocument and DOMNodeRemovedFromDocument events.

jQuery code repeating problem

I have a piece of code in jQuery that I use to get the contents of an iFrame after you click a link and once the content is completed loading. It works, but I have a problem with it repeating - at least I think that is what it is doing, but I can't figure out why or how.
jQuery JS:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
$("#fileuploadframe").load(function(){
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{action:"savePage",html:response, id: theID},
function(data){
alert(data);
});
});
});
HTML Links ( one of many ):
<a href="templates/1000/files/index.php?pg=0&preview=false"
target="fileuploadframe" class="pageSaveButton" rel="0">Home</a>
So when you click the link, the page that is linked to is opened into the iframe, then the JS fires and waits for the content to finish loading and then grabs the iframe's content and sends it to a PHP script to save to a file. I have a problem where when you click multiple links in a row to save multiple files, the content of all the previous files are overwritten with the current file you have clicked on. I have checked my PHP and am pretty positive the fault is with the JS.
I have noticed that - since I have the PHP's return value alerted - that I get multiple alert boxes. If it is the first link you have clicked on since the main page loaded - then it is fine, but when you click on a second link you get the alert for each of the previous pages you clicked on in addition to the expected alert for the current page.
I hope I have explained well, please let me know if I need to explain better - I really need help resolving this. :) (and if you think the php script is relevant, I can post it - but it only prints out the $_POST variables to let me know what page info is being sent for debugging purposes.)
Thanks ahead of time,
Key
From jQuery .load() documentation I think you need to change your script to:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
var lnk = $(this).attr("href");//LINK TO LOAD
$("#fileuploadframe").load(lnk,
function(){
//EXECUTE AFTER LOAD IS COMPLETE
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{
action:"savePage",
html:response,
id: theID
},
function(data){alert(data);}
);
});
});
As for the multiple responses, you can use something like blockui to disable any further clicks till the .post call returns.
This is because the line
$("#fileuploadframe").load(function(){
Gets executed every time you press a link. Only add the loadhandler to the iframe on document.ready.
If a user has the ability via your UI to click multiple links that trigger this function, then you are going to run into this problem no matter what since you use the single iframe. I would suggest creating an iframe per save process, that why the rendering of one will not affect the other.

Categories

Resources