I'm working on a simple Jquery Mobile application that does a search, presents results, and then allows you to click on a result to go to a dynamic detail page. On the detail page there is a collapsible list which uses an ajax call to get its content.
It appears to be working fine on the surface, but when I inspect it with Firebug I notice that every time you go to a detail page and expand the collapsible list, the ajax fires multiple times.
So, for instance, I do a search, go to the detail page, expand the collapsible list, the ajax fires once. I go back to the results page, click on another result, go to the detail page, expand the collapsible list, and the ajax fires twice, etc. Each time I expand the collapsible list, the ajax fires one more time...so if I look at 10 results, the ajax fires 10 times.
It would appear that the dynamic pages are accumulating in the DOM, and each time I click on the collapsible list, it's firing on all the selectors that have built up in the DOM (at least that's my theory).
How do I make sure that my ajax only fires once rather than multiple times?
I'm using Jquery Mobile 1.0.1 with Jquery 1.6.4. I'm using php to get the data.
Here's my code for the search page:
$('form#searchCompanies').submit(function(event) {
getSearchResultsCompanies();
return false;
});
function getSearchResultsCompanies() {
$.ajax({
type: "POST",
url: baseURL + 'server/searchCompanies.php',
data: $("form#searchCompanies").serialize(),
dataType: 'json',
success: function(results){
$('#companyList li').remove();
for ( var i=0; i < results.length; i++) {
$('#companyList').append('<li>' + results[i].CompanyName + '</li>');
}
$('#companyList').listview('refresh');
}
});
return false;
}
$('.companyDetail').live('click', function(event) {
//save companyid so that we can reference it on detail page
var companyid = $(this).attr('data-uid');
localStorage.setItem('thisCompanyId', companyid);
});
Here's the code for the detail page:
$('#companyDetailPage').live('pageshow', function(event) {
var companyid = localStorage.getItem('thisCompanyId');
$.ajax({
type: "POST",
url: baseURL + 'server/getCompanyDetail.php?companyid=' + companyid,
data: {companyid: companyid},
dataType: 'json',
success: function(company) {
$.each(company, function(index, company) {
$('#companyName').html(company.CompanyName);
//etc...pulls in more data to populate the page
});
}
});
//this is the call that fires multiple times
$('#companyContacts').live('expand', function(event) {
$('#companyContactList li').remove();
$.ajax({
type: "POST",
url: baseURL + 'server/getCompanyContacts.php?companyid=' + companyid,
dataType: 'json',
success: function(results){
for ( var i=0; i < results.length; i++) {
$('#companyContactList').append('<li>' + results[i].LastName + 'etc...more data</li>');
}
$('#companyContactList').listview('refresh');
}
});
return false;
});
});
The html div that gets populated looks like this:
<div data-role="collapsible" data-collapsed="true" id="companyContacts" class="cmdCompanyContacts">
<h3>Contacts (<span id="totalContacts"></span>)</h3>
<ul id="companyContactList" data-role="listview"><li></li></ul>
</div>
I've searched high and low for a resolution, and tried reworking my code from various angles, but I'm not able to solve this problem. Any help would be deeply appreciated. Thanks.
I had this problem too. I tried the suggestion found here, but still had the multiple event triggering problem after trying this. Here is what else I had to do. I changed it from this:
$(‘#myPage’).bind(‘pageinit’, function (event) {
$(‘#myButton’).live(‘click’, function (event, ui) {
to this:
$(‘#myPage’).bind(‘pageinit’, function (event) {
$(‘#myButton’).click(function (event, ui) {
Rather than using jquery live i would like to suggest you to use javascript function call when you click for the page change.Write your ajax call in that function so that its been called only once.Hope this helps
Related
I'm loading in a report and displaying it with jquery-ui in tab format. The report is returned by an ajax call in json, and a function is formatting it into HTML. Example code below:
<div id="reportdiv">
</div>
<script>
function displayreport(objectid)
{
$( "#reportdiv" ).hide();
$( "#reportdiv" ).html("");
$.ajax({
type: "GET",
headers: { 'authtoken': getToken() },
url:'/reportservice/v1/report/'+objectid.id,
success: function(data){
if(data == null)
{
alert("That report does not exist.");
}
else
{
var retHTML = dataToTabHTML(data.config);
$("#reportdiv").html(retHTML).fadeIn(500);
$(function() {
tabs = $( "#reportdiv" ).tabs();
tabs.find( ".ui-tabs-nav" ).sortable({
axis: "x",
stop: function() {
tabs.tabs( "refresh" );
}
});
});
}
}
});
}
</script>
This works fine the first time displayreport is called. However, if the user enters another value and runs displayreport again, the "tabs" format is completely lost (the tabs are displayed as links above my sections, and clicking on a link takes you to that section further down the page).
I figured completely re-setting the reportdiv html at the beginning of the function would bring me back to original state and allow it to work normally every time. Any suggestions?
After more testing, found that destroy was the way to go. If I've set up tabs already, run the destroy, otherwise, skip the destroy (http://jsfiddle.net/scmxyras/1/) :
if(tabs!=undefined)$( "#reportdiv" ).tabs("destroy");
Its my first time using the tooltip and have done a lot research on it. I used the jquery website to get most of the information. I intend my tooltip to show dynamic data when a mouse clicks the hyperlink. I added the title to my link and have this code below:
var t = 1000;
$(document).tooltip({
content: '... waiting on ajax ...',
open: function(evt, ui) {
var elem = $(this);
$.ajax({ type: "POST",url:'/GetTooltip/', data: 80140}).always(function() {
elem.tooltip('option', 'content', 'Ajax call complete');
});
setTimeout(function(){
$(ui.tooltip).hide('destroy');
}, t);},
position: {
my: "center bottom-20",
at: "center top",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
});
I am not fully knowledgeable with the syntax of the ajax call in reference to the always function and how to get the data to show on my tooltip. the GetTooltip returns JSON data, I just want to post to the GetTooltip script and the returned data to show on my tooltip. At the moment my ajax is posting nothing.
Regarding your statement that you are not fully knowledgeable with
always function: the always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { }); is always executed after the ajax request was executed. For more see the documentation deferred.always() Please look also at jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { })
get the returned data to show on the tooltip - see the example in the fiddle
You can find many other answers on stackoverflow. Take a look at this fiddle and let me know if you need more help.
Updated fiddle 2
If have updated the fiddle. You can pass values from the parameters that are returned from the ajax callback. This is a simple wrapper around the ajax call:
function callAjax(elem){
$.ajax({ url: '/echo/json/',
type: 'POST',
contentType:"application/json; charset=utf-8",
dataType:"json",
data: { json: JSON.stringify({ text: 'some text'})}
}).always(
function(data,textStatus, errorThrown)
{
elem.tooltip('option', 'content'
, 'Ajax call complete. Result:' + data.text);
});
}
I am using JSON.stringify(...) above to create a Json-String. This function may be not present in all browsers. So if you run into troubles please use a current chrome / chromium browser to test it.
So you can use the wrapper function inside the tooltip():
$('#tippy').tooltip({
content: '... waiting on ajax ...',
open: function(evt, ui) {
var elem = $(this);
callAjax(elem);
} // open
});
Above you can see that the always method calls an anonymous function with 3 parameters (data, textStatus, errorThrown). To pass the reply from the ajax call you can use data. Above i am only passing a simple object with the propert text. To access it you can use data.text
I have a view showform.phtml that is loaded into a div via jquery dialog. In the view I am loading a javascript with a $(form).submit() listener. The problem is, the javascript is never loaded. I have tried a couple of different methods, including $this->headScript()->appendScript(script), $this->headScript()->appendScript(file). I even tried just including the script in the layout and index view so that it was sure to be available... but the popup never fires it.
I suspect it has something to do with the fact that I am using setTerminal(true) on the form view... but I don't know what the alternative is.
Anyone have any advice on troubleshooting? Or any experience with this issue?
thanks
EDIT :
This is sample javasctipt that loads in the index.phtml view
$(function()
{
$("form#News").submit(function()
{
$.ajax(
{
type: 'POST',
url: '/main/manage/validateajax',
data: $('form#News').serialize(),
success: 'success'
});
return false;
});
});
The body of the view is a div that showform.phtml loads into
showform creates a form called #News.
When I insert the js code into the body of showform, it works. When I append this to the headScript, it does not work.
Maybe it's a solution for you.
Requirement: scripts of your modal view have to be already loaded (for example inside the application.js)
$("#loadModalBtn").click(function(e){
e.preventDefault();
var url = $(this).attr("href");
$("#modalContainer").load(url, function(){ // that's the point
var urlForm = $("form#News").attr("action");
$("form#News").submit(function(){
$.ajax({
type: 'POST',
url: urlForm,
data: $('form#News').serialize(),
success: 'success'
});
return false;
});
}).dialog({
height: 140,
modal: true
});
});
Hello!
i have a very nice Filter plugin i made with Jquery UI Slider, Here is the Full code And working Example:
http://jsbin.com/epikam/1/edit
Its working great, The Only problem is That After Ajax call it does not Change the Items..
Here is the Ajax call:
$.ajax({
url: "search.php",
dataType: 'json',
type: 'GET',
data: "q="+value+"&category="+cat+"&country="+country+"&page="+page,
success: function(data){
globalRequest = 0;
resultContainer.fadeOut('fast', function() {
resultContainer.html('');
for (var x in data) {
var html = '<li class="item" data-type="league2" data-id="id-'+x+'" style="position: relative;">';
html += '<label class="title">'+data[x].Title+'</label>';
html += '<img src="'+data[x].img+'">';
html += '<label class="price">New Price: '+data[x].newprice+'</label>';
html += '</li>';
resultContainer.append(html);
}
resultContainer.fadeIn('fast');
});
}
});
I tried to Use .live and .delegate With no success (Im not sure how\where to use it)
Any suggestions??
Thank you very much!!!
Eran.
Two things:
First, check that the success function is being called with something like console.log(data); in the success: callback and that there are not errors stopping the Ajax call from completing successfully. In the JavaScript console, check that the variable data has been correctly populated and contains the data you expect it to contain.
Secondly, use JQuery selectors instead of global variables within the ajax success call. E.g. use $("#resultContainer") (assuming the div has an id resultContainer) instead of the variable resultContainer.
Friends I have a problem
We need to make a user control that has the ability to delete itself, I made it but we did not clear the mechanism for removal, it should be tied to a nice picture. Code that is attached to the frame is given below, but not
$('#delete').bind('click', function () {
alert('test');
var urlA = '<%=Url.Action("DeleteMessage","Ticket")%>';
$.ajax({
url: urlA,
type: 'POST',
data: { idMessage:$(this).parents("div:first").find("input[name='MessageID']").val(),idticket:$('#TicketID').val() },
success: function (data) {
alert(data);
}
});
});
But when I write this, but to throw me to the homepage what's wrong
$('#delete').live('click', function ()
$("#delete").live("click", function(){
//code
$(this).remove(); //delete itself
});
If your image is declared as input type="image" then it will behave like a submit button and submit your page. You should prevent the default behavior of submitting the page by adding an event.preventDefault() or equivalent to your javascript function.