Here is the problem:
By default jQuery Mobile is using GET requests for all links in the application, so I got this small script to remove it from each link.
$('a').each(function () {
$(this).attr("data-ajax", "false");
});
But I have a pager in which I actually want to use AJAX. The pager link uses HttpPost request for a controller action. So I commented the above jQuery code so that I can actually use AJAX.
The problem is that when I click on the link there are two requests sent out, one is HttpGet - which is the jQuery Mobile AJAX default (which I don't want), and the second one is the HttpPost that I actually want to work. When I have the above jQuery code working, AJAX is turned off completely and it just goes to the URL and reloads the window.
I am using asp.net MVC 3. Thank you
Instead of disabling AJAX-linking, you can hijack clicks on the links and decide whether or not to use $.post():
$(document).delegate('a', 'click', function (event) {
//prevent the default click behavior from occuring
event.preventDefault();
//cache this link and it's href attribute
var $this = $(this),
href = $this.attr('href');
//check to see if this link has the `ajax-post` class
if ($this.hasClass('ajax-post')) {
//split the href attribute by the question mark to get just the query string, then iterate over all the key => value pairs and add them to an object to be added to the `$.post` request
var data = {};
if (href.indexOf('?') > -1) {
var tmp = href.split('?')[1].split('&'),
itmp = [];
for (var i = 0, len = tmp.length; i < len; i++) {
itmp = tmp[i].split('=');
data.[itmp[0]] = itmp[1];
}
}
//send POST request and show loading message
$.mobile.showPageLoadingMsg();
$.post(href, data, function (serverResponse) {
//append the server response to the `body` element (assuming your server-side script is outputting the proper HTML to append to the `body` element)
$('body').append(serverResponse);
//now change to the newly added page and remove the loading message
$.mobile.changePage($('#page-id'));
$.mobile.hidePageLoadingMsg();
});
} else {
$.mobile.changePage(href);
}
});
The above code expects you to add the ajax-post class to any link you want to use the $.post() method.
On a general note, event.preventDefault() is useful to stop any other handling of an event so you can do what you want with the event. If you use event.preventDefault() you must declare event as an argument for the function it's in.
Also .each() isn't necessary in your code:
$('a').attr("data-ajax", "false");
will work just fine.
You can also turn off AJAX-linking globally by binding to the mobileinit event like this:
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
Source: http://jquerymobile.com/demos/1.0/docs/api/globalconfig.html
Related
I have some content returned via ajax, and that content contains some links, but if I click them nothing happens (they don't respond to the JS written for them). Then, If i refresh the page, the first time I click, it works, and then it doesn't again.
How can I make it work normally?
This is basically my ajax call:
$('a.add').click(function() {
var data = {
action: 'ADD_PROD'
};
// make the request
$.get(ajax_object.ajax_url, data, function(response) {
// $('#vru_div').html(data);
$('div.left').html(response);
});
// $('div.left').html('<img src=712.gif>');
// alert('code');
return false;
});
The new links won't have any event handlers attached to them.
try using
$('.left').on('click','a',function(){
//your logic
});
On click of a #dtDelete button I am opening an ajax modal in bootstrap 3. I am also passing a parameter, selected, along with it and using $_GET on the php page to retrieve it.
As the value of selected may or may not be extremely large I think I should avoid passing the value this way / using $_GET.
How the heck can I pass values other than this method? Due to the nature of opening the modal (loading it then showing it) I am stuck on any other ways.
$('#dtDelete').on('click', function () {
//open the modal with selected parameter attached
$('#modal-ajax').load('/modals/m_keystroke_delete.php?selected='+selected);
$('#modal-ajax').modal('show');
});
Pass a data object as a second param to load for it to make a POST request.
$('#dtDelete').on('click', function () {
var data = { 'propertyA': 'extremely large data' };
//open the modal with selected parameter attached
$('#modal-ajax').load(
'/modals/m_keystroke_delete.php?selected=' + selected, // url
data, // data
function(responseText, textStatus, XMLHttpRequest) { } // complete callback
);
$('#modal-ajax').modal('show');
});
You can even pass your "selected" param through the POST request and use $_POST or even $_REQUEST to retrieve the data. Also notice that the modal now shows once the request has completed.
$('#dtDelete').on('click', function () {
var data = {
'selected': selected
'largeData': '...'
};
$('#modal-ajax').load(
'/modals/m_keystroke_delete.php',
data,
function() {
// Invoke the delete-function
deleteComp();
// Show the modal
$(this).modal('show');
}
);
});
i have problem with refreshing content in wrapper after it is loaded by ajax.
When i check with firebug - XHR is showing request and i can see elements loaded but it isn't showing on page.
This is what i am using for pullDown function to get ajax content
function pullDownAction () {
setTimeout(function () {
var el, li, i;
el = document.getElementById('thelist');
var http = new XMLHttpRequest();
var url = window.location;
http.open("GET",url,true);
http.send();
myScroll.destroy();
myScroll = null;
loaded();
}, 1000);
}
It looks like as content is stuck between showing on webpage and ajax request.
Any idea?
myScroll.refresh() (instead of .destroy() and recalling "loaded()") should do the trick!
If you're using IScroll4 you can try to use the checkDOMChanges:true option of iscroll.
If it still won't work - it could be a CSS issue caused by the scroll-wrapper (#scroller) not expanding with its content. (float,position:absolute; or something like that)
EDIT: it seems to me as you're not handling a responseText of the request at all!
According to this example you need an event handler for the onreadystatechange event:
http.open("GET",url,true);
http.onreadystatechange = function () {
if (http.readyState == 4) {
alert(http.responseText); //handle this response! (i.e. writing to an element's innerHTML)
}
};
http.send(null);
I am using RenderPartial to generate CListView and all the contents generated properly and good pagination is working fine too. But when I added my custom JS to elements generated by the CListview it works fine for the the fist page content but when i use pagination and click to page 2 then the JS binding fails.
Is there any other way to bind custom event to elements generated in YII CListview I had tried using live, and on nothing work for me here is my js file.
I think I have to call my function on every ajax load in but how can I achieve in yii
This is the script I am using to update ratings on server with button click and this the element for which these forms and buttons are defined are generated by CListview in yii
$(document).ready(function(){
$('form[id^="rating_formup_"]').each(function() {
$(this).live('click', function() {
alert("hi");
var profileid= $(this).find('#profile_id').attr('value');
var userid= $(this).find('#user_id').attr('value');
console.log(userid);
var data = new Object();
data.profile_id=profileid;
data.user_id=userid;
data.liked="Liked";
$.post('profile_rating_ajax.php', data, handleAjaxResponse);
return false;
});
});
});
You can also try CGridView.afterAjaxUpdate:
'afterAjaxUpdate' => 'js:applyEventHandlers'
The $.each method will loop only on existing elements, so the live binder will never see the ajax-generated content.
Why don't you try it like this:
$(document).ready(function(){
$('form[id^="rating_formup_"]').live('click', function() {
alert("hi");
var profileid= $(this).find('#profile_id').attr('value');
var userid= $(this).find('#user_id').attr('value');
console.log(userid);
var data = new Object();
data.profile_id=profileid;
data.user_id=userid;
data.liked="Liked";
$.post('profile_rating_ajax.php', data, handleAjaxResponse);
return false;
});
});
This problem can be solved by two ways:
Use 'onclick' html definitions for every item that is going to receive that event, and when generating the element, pass the id of the $data to the js function. For example, inside the 'view' page:
echo CHtml::htmlButton('click me', array('onclick'=>'myFunction('.$data->id.')');
Bind event handlers to 'body' as the framework does. They'll survive after ajax updates:
$('body').on('click','#myUniqueId',funcion(){...});
I don't think this is a Drupal-specific question, but more of a general jquery/ajax issue:
Basically, I'm trying to use javascript to add up form fields and display the result in a "subtotal" field within the same form. Everything is working fine until i click the option to add another field (via ajax), which then changes my "subtotal" field to zero, and won't work again until I remove the field.
Here is the function that adds up the fields:
function calculateInvoiceFields(){
var total = 0;
var rate = 0;
var quantity = 0;
var i = 0;
var $ = jQuery;
$("#field-aminvoice-data-values tr").each(function(){
// quantity field number
quantity = $("#edit-field-aminvoice-data-und-"+i+"-field-aminvoice-quantity-und-0-value").val();
// rate field as number
rate = $("#edit-field-aminvoice-data-und-"+i+"-field-aminvoice-rate-und-0-value").val();
if(!isNaN(quantity) && !isNaN(rate)){
total += quantity*rate;
}
i++;
});
return total;
}
And here are the functions that get fired for .ready and .live:
jQuery(document).ready(function(){
var $ = jQuery;
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
jQuery(function(){
var $ = jQuery;
$(".form-text").live('change', function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
});
Any ideas would be a big help. Thanks in advance!
I recommend using 'on' for any binding statement. and 'off' for unbinding.
The reason it doesn't work after an AJAX call, is because you need to be watching for that element to be added to the DOM, and an event attached to it after it gets loaded. If you load a new element in, and there is nothing watching for it, it won't add the event watch to that new DOM element.
As below:
function calculateInvoiceFields(){
/*..*/
return total;
}
$(document).ready(function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
$("body").on('change', ".form-text", function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
});
usually it stops working when an error has been thrown. did you check out your javascript console (firefox firebug, or built in for chrome) for any indication of an error?