AJAX call reload only works once - javascript

I am New to AJAX and have already asked a few question son this matter, but i have another, I use an AJAX call to auto save a value from a drop down list to database, this works great, however every time i change a value (Their are multiple drop downs with several values each can hold) I want the div to update to reflect the change in value. The AJAX I have is as follows:
<script>
$(document).ready(function(){
$('select').on('change',function () {
var statusVal = $(this).val();
var job_id = $(this).prop('id');
$.ajax({
type: "POST",
url: "saveStatus.php",
data: { statusType : statusVal, jobID: job_id },
success: function(data) {
$('#div1').load('jobs.php #div1', function() {});
}
})
});
});
</script>
So when I change a value in one drop down box (In div1) it refreshs the value, but if i was to change another value in the same or different drop down it no longer refreshs the div or saves the value to my DB, without the reload bit in my AJAX i can change the value in multple fields and it saves, but with the reload part it only happens once
-----EDIT-----
Ok further questioning, I have used
$('#div1').on( 'change', 'select', function( ) {
var statusVal = $(this).val();
var job_id = $(this).prop('id');
$.ajax({
type: "POST",
url: "saveStatus.php",
data: { statusType : statusVal, jobID: job_id },
success: function(data) {
$('#div1').load('jobs.php #div1', function() {});
}
})
});
});
and that works great even for multiple select changes. However what if I have a few selects in a few divs, EG div1, div2 and div3. How can I adapt this code to be able to refresh all divs on a change in any of the divs, or is a case of just having the code 3 times adapted for each div.
-----EDIT-----
Thankyou all, I am able to do this with
$('#div1, #div2').on( 'change', 'select', function( ) { //stuff
Ian

Your listener is bound to the select element, which I'm betting is being blown away and relaced with the load(). Check out event delegation. jQuery makes it easy. Try binding the listener on '#div1'
$('#div1').on( 'change', 'select', function( e ) { //stuff
It should then apply to the refreshed content as well.

Related

Mimic radio button push (PHP, JS)

I've tried to fix this problems for a week now without any success. I am a novice in this area so please bear with me.
I am using TastyIgniter, an online ordering system for food. Before you can add any items to your cart, you have to choose between Delivery or Collection. I have disabled the delivery feature as I only want people to order collection. I still have to press the 'Collection' button before I can do anything else. I need to get rid of this step.
// The buttons are basically radio buttons with a value of "1" and "2", where;
Delivery = 1
Collection = 2
After you press one of the buttons, you declare;
$order_type === '1' or $order_type === '2'
Unfortunately, order type 1 is preselected, not order type 2.
To make this easy for myself after trying to modify the model, controller and button, I am looking for a feature that mimics the push of the button so I then can hide it with CSS.
Button Inspection:
function() { if (typeof this.value !== 'undefined') {
var order_type = this.value;
$.ajax({
url: js_site_url('cart_module/cart_module/order_type'),
type: 'post',
data: 'order_type=' + order_type,
dataType: 'json',
success: function(json) {
if (json['redirect'] && json['order_type'] == order_type) {
window.location.href = json['redirect'];
}
}
});
I would appreciate any help, thank you!
Taken from http://api.jquery.com/trigger
$( "#foo" ).on( "click", function() {
alert( $( this ).text() );
});
$( "#foo" ).trigger( "click" );
Apply this to your code if you want to simulate a click.
The event is fired from a click on the label, so this should work:
$('input[name="order_type"][value="2"]').parents('label').trigger('click');

Pulling in specific elements with Ajax

I am building a Wordpress site. I am using Ajax to pull in content from another page to fill an empty div when a particular element is clicked. Each element has a different URL so I made the Url a variable. I need Ajax to only pull in a particular element from this URL. Instead it keep pulling in the entire page. I've tried using various methods to select the specific element, but I've hit a wall and need a little help.
(function($) {
function find_page_number( element ) {
return parseInt( element.html() );
}
$('.member-info').on('click', function (event) {
event.preventDefault();
page = find_page_number( $(this).clone() );
var memberSrc = $(this).attr('href');
$.ajax({
url: memberSrc,
type: 'get',
dataType:'html',
data: {
action: 'ajax_pagination',
query_vars: ajaxpagination.query_vars,
page: page
},
success: function( html ) {
$("#main").empty();
$('#main').append( html);
}
});
})
})(jQuery);
You can filter the answer with jQuery:
$('#main').append( $(html).find('#main').html() );

jQuery selectable() post via ajax issue where the selections loop their history before posting

I have a table that a user can select multiple rows. Selected rows have unique ID which is then aggregated into a string and POSTed to a php file. It all works fantastic except I have one problem. If the rows are selected, re-selected a number of times it does not POST the last status of the selection. So when I look into the log this is what I basically see:
14_629_2 view.php:541
14_629_15 view.php:541
14_629_2 view.php:541
14_629_15 view.php:541
14_629_2;14_629_15 view.php:541
14_629_15 view.php:541
This is two rows by the way. So the last state could be both rows selected 14_629_2;14_629_15 view.php:541 , but it would post the 14_629_15 view.php:541 instead, for some reason. It's as if it keeps cache or history of selections made and then loops and dumps everything in one spur.. and sometimes messes up.
I basically need it to keep track of only the current selection, no history.
Code I use:
<script>
$('#t1').selectable({
filter:'tbody tr',
stop: function(event, ui){
var map = $( this ).find( ".ui-selected" ).map(function() {return this.id;}).get().join(";");
// var result = $( "#plate" ).empty().html(map);
$('#batch_send').click(function (){
$(function() {
$.ajax({
url: 'batch_send.php',
type: 'POST',
data: 'variable='+map,
success: function(data) {
$('.display_div').html(map);
console.log(map);
}
});
});
});
}
});
</script>
I'm new to javascript so this must be some obvious mistake...
Solution:
The reason it looped was because the ajax request was in a function.
So I rewrote the code to make it a bit more simple
var map;
$("#t1").selectable({
filter:'tbody tr',
cancel: 'a, #slct_ignore, thead',
stop: function(event, ui) {
map = $(this).find( ".ui-selected" ).map(function() {return this.id;}).get().join(";");
}
});
$("#batch_send").click(function() {
$.ajax({
url: 'batch_send.php',
type: 'POST',
data: 'variable='+map,
success: function(data) {
$("#plate").html(map);
$(".display_div").html(map);
}
});
});

jQuery plugin bsmSelect doesn't update its values when it is called again and its select options have changed

I'm using bsmSelect jQuery plugin. Basically, what it does is changing the way a select-multiple is rendered to make easier to pick up the options. It hides the select element and shows a list instead.
So, first of all I'm applying the plugin function to my select-multiple element:
$(document).ready(function() {
...
$('#my_select_multiple').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
});
...
});
On the other way, I have another select element (this one is simple) which has an ajax request bind to its change event. This ajax request get new #my_select_multiple options depending on the select simple value. Ajax response is the new HTML for #my_select_multiple options. So I have:
function getNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/
}).responseText;
return r;
}
...
$(document).ready(function() {
...
$('#my_select_simple').change() {
$('#my_select_multiple').html(getNewOptions($(this).val()));
}
...
});
AJAX is working as expected. New options are got correctly and they are inserted into #my_select_multiple (which is hidden by bsmSelect plugin, but I can check it with Firebug). But bsmSelect didn't realize new changes and doesn't get updated.
So, I think what I want is to reapply $('#my_select_multiple').bsmSelect(); with its new options.
I've been looking around a little bit and here is what I have tried.
1. I've tried to call again the funcion with the success and complete (one at time) of the AJAX request. Didn't work:
function getNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/,
success: function() { $('#my_select_multiple').bsmSelect(); }
}).responseText;
return r;
}
2. I've tried to bind the function with the on jQuery function. Didn't work:
$('#my_select_simple').on('change', function() {
$('#my_select_multiple').bsmSelect();
});
3. I've tried 1 and 2 removing previosly the HTML generated by bsmSelect. Didn't work.
Thank you very much.
UPDATE: The exact code
First I have a global.js file which apply bsmSelect plugin to some select multiples (.quizzes):
$('.quizzes').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
});
And then, in the php file I define the updateQuizzes function and bind it to the select simple (project_id) change event:
<script type="text/javascript">
function updateQuizzes(project_id) {
var r = $.ajax({
type: 'GET',
url: '<?php echo url_for('event/updateQuizzes')?>'+'<?php echo ($form->getObject()->isNew()?'':'?id='.$form->getObject()->getId()).($form->getObject()->isNew()?'?project_id=':'&project_id=')?>'+project_id,
success: function() { $('.quizzes').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
}); }
}).responseText;
return r;
}
$('#project_id').change(function(){
$('.quizzes').html(updateQuizzes($(this).val()));
});
</script>
As I told, the AJAX request works without problems, but not the calling bsmSelect the second time...
Not sure if this is what the problem is, but you could try
$('#my_select_simple').change() {
$('#my_select_multiple').html(getNewOptions($(this).val())).trigger('change');
}
This triggers a change event on select_multiple, and might fire bsmSelect. I'm not sure what the problem here is exactly, but that's the best I can come up with.
I think you want to set your HTML in the success of the Ajax call, something like:
function loadNewOptions(val) {
$.ajax({
type: 'GET',
url: /*My URL*/,
success: function(data) {
$('#my_select_multiple').html(data).bsmSelect();
}
});
}
And then calling like:
$('#my_select_simple').change() {
loadNewOptions($(this).val());
}
$(document).ready(function() {
$('#my_select_simple').change() {
$('#my_select_multiple').load("your Url", function(){
$('#my_select_multiple').bsmSelect();
});
}
});
something like this should work.
.load will put whatever your url returns into #my_select_multiple
the first parameter is the url to load, and the 2nd is a function to call when it is done. which is where you need to set up your fancy selector.
Ok, I opened a ticket and bsmSelect developer has answered me in minutes. Great!
To let bsmSelect know about its select changes, you have to trigger a change event on the select. There is no need to call bsmSelect again.
So it can be that way:
function loadNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/,
success: function(data) {
$('#my_select_multiple').html(data).trigger('change');
}
}).responseText;
return r;
}
$('#my_select_simple').change(function() {
loadNewOptions($(this).val());
});

jQuery: Referencing the calling object(this) when the bind/click event is for a class

Thanks for reading this.
I am dynamically generating some data which includes a select drop-down with a text box next to it. If the user clicks the select, I am dynamically populating it (code below). I have a class on the select and I was hoping the following code would work. I tested it with an ID on the select and putting the ONE on the ID I got it to work. However, in changing the code to reference a class (since there will be multiple data groups that include a select with a text box next to it) and $(this), I could not get it to work. Any ideas would be helpful. Thanks
The relevance of the text box next to the select is the second part of the code...to update the text box when an option is selected in the select
.one is so the select is updated only once, then the .bind allows any options selected to be placed in the adjacent text box.
$('.classSelect').one("click",
function() {
$.ajax({
type: "post",
url: myURL ,
dataType: "text",
data: {
'_service' : myService,
'_program' : myProgram ,
'param' : myParams
},
success:
function(request) {
$(this).html(request); // populate select box
} // End success
}); // End ajax method
$(this).bind("click",
function() {
$(this).next().val($(this).val());
}); // End BIND
}); // End One
<select id="mySelect" class="classSelect"></select>
<input type="text">
$(this) is only relevant within the scope of the function. outside of the function though, it loses that reference:
$('.classSelect').one("click", function() {
$(this); // refers to $('.classSelect')
$.ajax({
// content
$(this); // does not refer to $('.classSelect')
});
});
a better way to handle this may be:
$('.classSelect').one("click", function() {
var e = $(this);
$.ajax({
...
success : function(request) {
e.html(request);
}
}); // end ajax
$(this).bind('click', function() {
// bind stuff
}); // end bind
}); // end one
by the way, are you familiar with the load() method? i find it easier for basic ajax (as it acts on the wrapped set, instead of it being a standalone function like $.ajax(). here's how i would rewrite this using load():
$('.classSelect').one('click', function() {
var options = {
type : 'post',
dataType : 'text',
data : {
'_service' : myService,
'_program' : myProgram ,
'param' : myParams
}
} // end options
// load() will automatically load your .classSelect with the results
$(this).load(myUrl, options);
$(this).click(function() {
// etc...
}); // end click
}); // end one
I believe that this is because the function attached to the success event doesn't know what 'this' is as it is run independently of the object you're calling it within. (I'm not explaining it very well, but I think it's to do with closures.)
I think if you added the following line before the $.ajax call:
var _this = this;
and then in the success function used that variable:
success:
function(request) {
_this.html(request); // populate select box
}
it may well work
That is matching one select. You need to match multiple elements so you want
$("select[class='classSelect']") ...
The success() function does not know about this, as any other event callback (they are run outside the object scope).
You need to close the variable in the scope of the success function, but what you really need is not "this", but $(this)
So:
var that = $(this);
... some code ...
success: function(request) {
that.html(request)
}
Thanks Owen. Although there may be a better to write the code (with chaining)....my problem with this code was $(this) was not available in the .ajax and .bind calls..so storing it in a var and using that var was the solution.
Thanks again.
$('.classSelect').one("click",
function() {
var e = $(this) ;
$.ajax({
type: "post",
url: myURL ,
dataType: "text",
data: {
'_service' : myService,
'_program' : myProgram ,
'param' : myParams
},
success:
function(request) {
$(e).html(request); // populate select box
} // End success
}); // End ajax method
$(e).one("click",
function() {
$(e).next().val($(e).val());
}); // End BIND
}); // End One

Categories