I am attempting to send the value of a select element as a parameter to an ajax request. However it will always send the initial value of the element on page load as opposed to the value of the current selection.
I have tried updating the variable by resetting it when the select box changes, but that didn't have any effect on the ajax request.
<select id="id_location">
<option value="1">...</option>
<option value="2">...</option>
<option value="3">...</option>
</select>
<script>
var list = $("#id_location").val();
$(document).ready(function() {
$("#id_location").change(function(){
list = $("#id_location").val();
})
$('#id_part_number').autocomplete({
serviceUrl: '/lookup',
width: 500,
params: {location: list}, // <-------- This variable is not updating
onSelect: function (suggestion) {
var request = $.ajax({
url: "/lookup",
type: "GET",
data: {"query": suggestion.data,
},
dataType: "json"
});
request.done(function(msg) {
$("#id_number").val(msg.number);
$("#id_desc").val(msg.description);
$("#id_par").val(msg.par);
})
}
});
})
</script>
I am a complete novice when it comes to javascript/jquery and haven't been able to come up with anything from googling. Any insight into solving this would be much appreciated.
Edit: The autocomplete function above is part of the external library jquery-autocomplete. It's purpose is to send the ajax request every time the element it is attached to, in my case an input field, is updated. I would like to send the current value of the #id_location element with the parameters in the request. Right now I have only been able to get it send the original value of the element when the page loaded and can't get it to update.
Found the answer.
params:{location: function(){ return $('#id_location').val()}},
Related
I have two HTML elements: 1). the div element is a multiple select (it is a predefined widget that automatically creates the multiple select element) and 2). a button that triggers onclick event.
On the JS side, there is the global variable 'prev_selection' which is set to empty array for now. The idea of prev_selection is to remember the array of values in the multiple select div element before user clicks the button. I want to remember the value before and after a click to see what selections have been added/removed.
When the button is clicked, 'sendData()' is called. It gets the selected data from the div element. Then, it performs some operations using the prev_selection to know what the newly selected values are (in the beginning everything is newly selected in the div).
I want to find out the additions/deletions in the selected values between user clicks. For that, I update the prev_selection with 'selected_data' that I get from the div element jut after the click.
But this does not work as expected. There is something happening with the asynchronous Ajax call and I am not able to find a better solution for this. Everytime a click happens you had expect that 'prev_selection' remembers the value before the click but instead when I print it using console.log() (as shown in the code) it already gets updated to the latest selections even before reaching the success function (where it is supposed to get updated).
Thanks in advance! And please let me know if further explanation is required.
<!-- multiple select/deselect div -->
<div id="someSelectionID"></div>
<button id="updateButtonID" onclick="sendData()">Click to send</button>
// at first, no data is selected
var prev_selection = [];
function sendData() {
// get the selected data from the div element "someSelectionID"
let selected_data = $('#someSelectionID').val();
// perform some operations on the selected data
// this operation involves the use of prev_selection
// printing prev_selection already has value of updated click
console.log(prev_selection );
$.ajax({
type: "POST",
url: "<some url>",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify( < some data > ),
success: function(result) {
console.log(result);
/* once the request is successfully done update the
previous selection to what the current selected data is */
prev_selection = selected_data;
}
});
}
Try this
$.ajax({
type: "POST",
url: "<some url>",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify( < some data > ),
}
}).then(function(response){
if (response.status === 200){
console.log('succeed');
} else {
console.log('failed')
}
});
So it worked by changing this line
prev_selection = selected_data;
to:
prev_selection = Array.from(selected_data);
Because the prev_selection variable kept changing without me updating, it lead me to believe that it was some kind of reference to value instead of value itself. So just using Array.from to do a shallow copy actually worked.
I have a form that loads some of its Data dynamically via Ajax, where, apart of a lot of other stuff, I fill a dropdown list. When selecting an item it will load the corresponding data into a table.
That all works fine, but now I want to be able to, by default, load the data of the first element once the page loads.
But since the dropdown populates over Ajax, it is filled slightly after $(document).ready(), so that doesn't work.
One way it might work would be to just wait for a second or two, since then it should all be loaded, but that really isn't something I fancy doing.
Any idea how I could achieve that?
I already tried it with onloadeddata="loadData($(this)[0].selectedOptions[0].value)" on the select tag, but that doesn't seem to do anything.
EDIT:
And I don't want to execute this in the ajax success function as data might also be loaded in other ways. It should really be the dropdown field or something that watches the dropdown, that executes this.
JQuery Ajax provides a callback for successful request.
$.ajax({
url : 'stackoverflow.com/api',
type: 'GET',
success : successMethod
})
function successMethod(){
// foo
}
Once the request receives a response successMethod will be called.
jquery ajax have a success function in which you can do such kind of functionality. To do so you can try:
success: function(response) {
// fill the form value with 'response'
$('#dropdown_id').val('any_value'); // this will set the dropdown to specific value
}
$.ajax({
url: "test.html",
...
}).done(function(data) {
// do something with your data in here
});
I have a large number of inputs on a page, each input is disabled (and hidden) by default unless a checkbox is checked. Checking a related checkbox enables the input for a user to type an amount - that works fine.
After I've typed an amount into a given box and I shift my blur focus to something else (indicating I'm done with this input), I'm looping through every visible input to check if it has an amount in it and then sending an ajax request to update the back-end (this also works but maybe approach is wrong?).
What doesn't work is when I loop through more than 5-10 checkboxes, it seems to be extremely slow or simply doesn't send the ajax requests.
Code the listens for an enabled/visible amount box to change:
$(document).on("blur", ".dollar-amount", function(){
MainPage.amountInputListener('add');
});
Here is the foreach loop, which updates each associated user's backend data with the amount in the visible field:
var MainPage = {
amountInputListener: function (type) {
$(".dollar-amount:visible").each(function () {
//Get the employee being updated
var empID = $(this).data('empid');
//get the amount
var amount = $(this).val();
//Send update request to backend
$.ajax({
type: "POST",
url: "update/amount?empid=" + empID + "&amt=" + amount + '&type=' + type,
dataType: "html"
});
});
},
}
The HTML for the input:
<input type="text" name="dollar_hour_amountX" value="0" class="form-control dollar-amount disabled" data-empid="1" tabindex="-1" disabled>
Note: dollar_hour_amountX, X is a dynamic number related to the row's employee ID. data-empid is the same dynamic number, also used in the for loop.
Things I've tried to ensure the loop works properly:
Adding async: false. This allows it to work 100% of the time, but it's extremely slow the more inputs that are added.
Adding a timeout of 100-1000ms around the entire function, this simply delays the round-trip time of the Ajax call.
I'm open to Vanilla JS suggestions if it aids in making the calls to my back-end much faster and consistent.
// capture the passed in event
$(document).on("blur", ".dollar-amount", function(e){
// give the element to the method
MainPage.amountInputListener(e.target, 'add');
});
var MainPage = {
// accept the element on the arguments
amountInputListener: function (element, type) {
// use the element in place of `this`
//Get the employee being updated
var empID = $(element).data('empid');
//get the amount
var amount = $(element).val();
//Send update request to backend
$.ajax({
type: "POST",
url: "update/amount?empid=" + empID + "&amt=" + amount + '&type=' + type,
dataType: "html"
});
},
}
Does not make sense to update everything, just update what changes.
$('.dollar-amount').on("change", function () {
console.log(this.value, $(this).data('empid'))
// make the one Ajax request
})
Or change your backend to be able to handle multiple things being sent up at once so you are not hammering the backend with a bunch of calls.
"I'm looping through every visible input to check if it has an amount in it and then sending an ajax request to update the back-end (this also works but maybe approach is wrong?)."
I would strongly recommend you change this approach. I suspect it will fix your issues. Don't loop through all of these each time. There is no need. Simply, on blur, just check if this specific input has changed, and then send an ajax call ONLY if that specific one was edited.
Just pass "this" into the amountInputListener as an argument, and then get rid of the above "each" function. The rest would be the same. Instead of $(this), just pass the argument value that represents "this" from the event.
The first and foremost thing is using a get http verb request for update should be avoided.
This is not per standard, usually get requests are used to retrieve data.
And the next thing is instead of making an ajax call for each element with callname .dollar-amount and visible, it is better to declare a global variable above the foreach block of type array of objects and then add each item in the block to that global variable and then finally make an ajax request after the for block execution is done
amountInputListener: function (type) {
var objList = [];
$(".dollar-amount:visible").each(function () {
//Get the employee being updated
var empID = $(this).data('empid');
//get the amount
var amount = $(this).val();
//Send update request to backend
objList.push({
'empId':empId,
'amt':amount,
'type': type
});
});
$.ajax({
type: "post",
url: "update/amount"
dataType: "application/json",
data:{'data':objList}
});
},
}
This way you can send all data in one shot to server and it really helps in the performance.
Note: code is just to give you an idea.
I have very basic JS skills, so please excuse me if I'm trying to fix something what doesn't need fixing.
I use select2 dropdown. When user selects any option, it gets posted to remote file, which returns possible options (in JSON format) to be displayed in 2nd (dependent) dropdown.
1st select looks following:
<select name="restaurant_id" id="restaurant_id">my_options_go_here</select>
2nd (dependent) select looks:
<select name="division_ids_array[]" id="division_ids_array" multiple="multiple"></select>
And here's JS code:
$(function () {
function ajax_post_data_get_divisions(parameters) {
$.ajax({
method: "POST",
url: "ajax.php",
cache: false,
data: parameters,
success: function(data) {
var dropdown_options=$('#division_ids_array');
dropdown_options.empty();
var dropdown_options="";
$.each(data, function(key, val) {
dropdown_options+='<option value="'+val.division_id+'" '+val.selected+'>'+val.division_name+'</option>';
});
$(dropdown_options).appendTo("#division_ids_array");
}
});
}
$('#restaurant_id').on("change", function(e) {
parameters=$("#my_form_id").serialize();
ajax_post_data_get_divisions(parameters);
});
});
Everything works fine, but I somehow believe these lines are excessive:
var dropdown_options=$('#division_ids_array');
dropdown_options.empty();
var dropdown_options="";
Please excuse my ignorance, but it looks variable dropdown_options gets created first, then it gets set to empty, and then the same variable is created again?
Unfortunately, if I remove at least one line, nothing works. For example, if I try to simply code to:
var dropdown_options=$('#division_ids_array');
dropdown_options.empty();
dependent dropdown remains empty. Is it an error in my code?
Im running into a problem where i have an ajax driven page that is drawn when a user selects something from a simple drop down:
<select id = "selectdepartment">
<option id = "default">Select an option...</option>
....
</select>
and the remainder of the page is drawn using the jquery .change() :
$('#selectdepartment').change(function(){
});
Which then runs some ajax to php script. everything works great, the problem is when i submit a form that was drawn with ajax (using $_SERVER['PHP_SELF'];), the data gets submited, the page reloads, and the page is cleared but the select box is still left where it was. The user has to move to a different option then back to the one the selected originally to re-fire the .change(). that sucks.
I could fix this by passing a php variable in all of my forms, then checking to see the variable set on every page load and if it is draw the page parts then, but this would lead to pretty messy code and it's less than desirable.
There has to be a way to do this with the jquery library, though my knowledge of the javascript language in general is not what i would like it to be. If anyone has any helpful hints please share, dont do it for me though, i wont learn that way :)
edit: code with .trigger
$('#selectdepartment').change(function(){
var department = $('#selectdepartment').val();
var day = $('#data').data('day');
var month = $('#data').data('month');
var year = $('#data').data('year');
//alert (department);
if(department === "Select an option..."){
$('.hiddenuntildepartmentisselected').css({"display":"none"});
}
else{
$('.hiddenuntildepartmentisselected').css({"display":"block"});
}
showpoints(department);
drawpointstable(department, day, month, year);
displaytheuseresforselecteddepartment(department, '');
$('#sendthedepartment').val(''+department+'');
$('#hiddendepartmentidforaddinganewpoint').val(''+department+'');
}).trigger('change');//end run functions
You can use the .trigger() function to immediately trigger the change event handler when the page has loaded:
$('#selectdepartment').change(function() {
// code here
}).trigger('change');
Or if you need to call it elsewhere via JavaScript/jQuery:
$('#selectdepartment').trigger('change'); // or just .change() as a shorthand
Updated
Your button for the form could make use of the onClick attribute, which would invoke a method to parse the form fields and post the data to your php script via .ajax().
In the success event method you then check any flags you need to and modify the element as you desire if needed.
Basic example:
Inside of .ajax():
...
url: 'xxx.xxx.xxx',
async: true,
type: 'POST',
dataType: 'html',
data: JSON.stringify( form_fields ),
beforeSend: function()
{
// Pre send stuff, like starting a loading gif
},
success: function( data, textStatus, xhr )
{
// Be sure you load the page with the content first
$( '#containing-div' ).html( data );
// Do your check here, and modify your element if needed here
if( flagtocheck === 'xxx' )
{
// Modify the element in question...
}
// I call a custom method termed `.ctrls()` here that makes any
// adjustments to the DOM once its loaded/updated.
},
error: function( xhr, textStatus, errorThrown )
{
}
Of course, you'll want to set flagtocheck appropriately in your case.
Hope that helps!
Note regarding edit
This post was edited to be a little more descriptive and more easily understood. Since the person asking the question is already using the .ajax() method, the success event method is the ideal place for doing what the person asking the question is requesting. It is 1 less method invocation to directly modify the element there than using it to call .trigger() or .change() which then also directly modifies the element.