Problem selecting an item after building the select options with AJAX - javascript

I use this javascript to select a specific option (the option value being specified within a hidden element):
$("select").each(function() {
var id = $(this).attr('id');
var source = 'input:hidden[name=select_'+id+']';
if ($(source).length) {
var selected = $(source).val();
$(this).val(selected).change();
}
});
This works fine when the options are hard coded in the HTML source.
I now need to populate the options with an AJAX call, I use the below method:
select : function(ctrl,id) {
var call = '/'+ctrl+'/'+$("#auth input[name=verify]").val();
$.getJSON(call, function(result) {
$.each(result, function() {
$('#'+id).append($("<option />").val(this.id).text(this.title));
});
});
},
I process the select method (AJAX) on page load, and the options populate fine. But when I then try to select the desired option, the browser defaults to the first option.
I have tested what is happening by sticking some alerts around the code as thus:
alert($(this).val(selected)); // A
alert($(this).val()); // B
$(this).val(selected).change();
alert($(this).val()); // C
When the options are hard coded I get A=3, B=null, C=3 i.e. it works
When the options are populated via AJAX I get A=3, B=null, C=null i.e. it fails
I am guessing that I need to trigger some kind of change() event after populating the option list with AJAX. I have tried (a bit overkill I know):
$('#'+id).append($("<option />").val(this.id).text(this.title).change());
&
$('#'+id).append($("<option />").val(this.id).text(this.title)).change();
Any ideas? Thx

Problem solved.
Although I was triggering the code in the correct order (in theory), because of javascripts event driven behaviour the AJAX call was not completing until after my select initialisation had finished. So I moved the code to set the selected option into the AJAX call and voila.
select : function(ctrl,id) {
var call = '/'+ctrl+'/'+$("#auth input[name=verify]").val();
$.getJSON(call, function(result) {
$.each(result, function() {
$('#'+id).append($("<option />").val(this.id).text(this.title));
});
var source = 'input:hidden[name=select_'+id+']';
if ($(source).length) {
var selected = $(source).val();
$('#'+id).val(selected).change();
}
});

Related

How to multi select results using Select2.js with data returned from Ajax call?

I have a two dropdowns that use Select2.js.
The second dropdown will initiate an ajax call base on the value from the first dropdown.
Assuming that I have already the result that I needed from Ajax call, and I already know what will be the result and that is the value 1276 and 1277.
What I want is when I click either one of the results all the results will be selected.
As what I read in Neelu's answer this will supposed to do the trick:
//this code block is outside the ajax call of select2.js
$('.select-2').on('select2:select', function() {
$('.select-2').val([1276,1277]);
$('.select-2').trigger("change");
});
The result doesn't reflect in the Select2 element but when I check the value using .val(), I get the result 1276 and 1277.
What I noticed if I trigger a different event e.g. button click to get the value of the Select2. That's the time it will work, but when I trigger another Select2 ajax call it doesn't work again.
I found the solution:
This is because during ajax call if there are no selected options,
and there are no option tag generated yet, thus
Select2.js can't reflect the changes in the display even though
.trigger('change') was already set.
So the trick is, during ajax call, once you received the response create an option tag (which is in my case I already knew that the response will be two value and I also want to select both of them either which I selected) thus I create two option tag after ajax call:
//..Ajax code response....
var selectElement = $(this)[0].$element[0];
processResults: function (data) {
$.each(data, function( k, v ) {
selectElement.innerHTML += '<option value="'+v.id+'">'+v.text+'</option>';
});
}
Then outside your ajax code:
$('.select-2').on('select2:select', function() {
$('.select-2').val([1276,1277]).trigger("change");
});
If you want to remove both selections if you either unselect one of them, this is the trick:
$('.select-2').on('select2:unselect', function() {
$('.select-2').val('').trigger("change");
//then destroy the option tag pre-created during ajax call
$('.select-2').empty();
});

jQuery AJAX call from multiple input fields within the 1 script

I'm working on my first HTML form that performs an AJAX HTTP POST using jQuery. When a user makes a change to an input text field and tabs out of the field it triggers the AJAX script which in turn calls a PHP script which performs a database update.
I've got this working successfully for my first input field - I would now like to extend this to a 2nd, 3rd etc input fields but want to try and avoid having multiple scripts that perform very similar functions. I'm new to jQuery and AJAX so learning the syntax as I go.
Here's my input fields:
Manager
Phone
Here's my Javascript that is working on the storeManager input field:
<script type="text/javascript">
$(document).ready(function() {
$("#storeManager").change(function(){
var storeManager = $("#storeManager").val();
$.post('editProject.php', { storeManager: storeManager, id: '1E1DDA14-D2C6-4FC8-BA5F-DBCCC7ABAF7F' }, function(data) {
$("#managerRow").addClass("success");
}).fail(function () {
// no data available in this context
$("#managerRow").addClass("danger");
$("#ajaxAlert").addClass("alert alert-danger");
});
});
});
</script>
I essentially need to branch and pass an additional POST parameter to the editProject.php script so it knows which database field to update, and then conditionally add a class to the appropriate row.
Everything I've tried breaks the script when I try and get it to branch or pass a parameter based on the input field that is being edited. I haven't been able to find any examples that show the correct syntax to have the one script that is called by different input fields - I'm presuming this is possible instead of having multiple versions of the same script acting on different fields.
This works for multiple fields. Just call the same function from different input fields. I just broke your code into two parts.
1. onChange function of each individual field, and
2. function call by passing the field parameters.
<script type="text/javascript">
$(document).ready(function() {
$("#storeManager").change(function(){ yourFunction(this) }):
$("#worker").change(function(){ yourFunction(this) }):
$("#someX").change(function(){ yourFunction(this) }):
yourFunction(field)
{
var value = $(field).val();
var inputId=field.id;
$.post('editProject.php', { inputValue: value, id: inputId }, function(data) {
$('#'+inputId+'Row').addClass("success"); // (this looks like: *#storeManagerRow* ) you can change your Row id's accordingly to make your work easier. Eg: for **#storeManager** make this id as **storeManagerRow**
}).fail(function () {
// no data available in this context
$('#'+inputId+'Row').addClass("danger");
$("#ajaxAlert").addClass("alert alert-danger");
});
});
</script>
You just try to post a value. for example type. Which should contain some value for identify the ajax call.
If it is for login, then add type = 'login'. Then check the value of $_POST['type'] and write php according to it
sample.php
if(isset($_POST['type']))
{
if($_POST['type'] == 'login')
{
//your code goes here
}
}
you can use this kind of code :
$("#storeManager, #Manager, #Phone").change(function(){
You could do something like this using :input or a class that they all have
$(":input").on("change", function(){
var text = $(this).val();
var idOfInput = $(this).attr("id");
//your post to php function using the above variables
});
From this you could post the id of the input to your php script using the idOfInput variable which you could then on the php side use a case switch to do a different query depending on which id is sent to the php
Here is a jsfiddle showing how it works

Appending new results to an open jQuery autocomplete menu

I have an app in which I have multiple search sources. Previously, the users had to choose in what source to search in before searching. If they did not choose, the app would default to one of the options.
However, now they want to search in all the sources at the same time. This is fine enough, but the problem is that when one of the searches returns, it overwrites the previous search result. Pretty much expected behavior. What I basically want is to append the new results to the already open autocomplete menu, instead of overwriting the old results. Naturally, the autocomplete menu would have to empty when it closes.
I guess that this is possible to do, but what approach is the best? I could just have an array I guess, which I append results to and then overwrite _renderMenu to use this array instead of the items one that is passed to the function. Then empty said array at the close event.
Is this the best way to go though? Or is there a more elegant solution?
Some code:
Ok, so searchAction is called by jquery autocomplete eventually. In collection.search I do the ajax call, here the URL is created based in the this parameter, then respondWhithData is called and maps the search result to a proper format (ie value and label for the autocomplete menu). After reponse is called from respondWithData, jquery automagically renders the resultsmenu. Thus, I probably have to overwrite the reponse event function as well as the _renderMenu and possibly _renderItem, yes?
searchAction: function(searchTerm, collection, response){
var self = this;
$.when(collection.search(searchTerm, this)).then(function(data) {
self.respondWithData(data, response);
});
},
respondWithData : function(data, response) {
if (data.length > 0) {
var responseVal = _.map(data, this.mapData);
this.checkResponseCount(responseVal);
response(responseVal);
}
else {
response(this.emptyResult());
}
},
To be clear, the problem is not the multiple search itself, but rendering the asynchronos results. I want to render the first results that come back, and then appends the rest as soon as they are returned from the server.
Edit 2:
Just tried to edit ui.content in the autocompleteresponse event, but any edit does not take once it renders for some reason...
Edit 3: Ah, ui.content can only be modified directly, not changed. If I push every single change instead of concating two arrays ui.content shows what I want.
It works I guess, but its not perfect.
I can figure how looks your scenario but I'm guessing:
You should have like:
function search1() {
$.ajax({ ...
success: function(data) {
$('#myResultsDiv").html(data)
}
});
}
etc
Instead of overwritting the #myResultsDiv you need to Append the results like:
function search1() {
$.ajax({ ...
success: function(data) {
$('#myResultsDiv").append(data)
}
});
}
Edit: You can also do something like this:
var resultsArray = [];
var searchDone = 0;
var totalSearchs = 5; //assuming 5 searches
function search1() {
function search1() {
$.ajax({ ...
success: function(data) {
//APPEND data to resultsArray
searchDone++;
if(searchDone==totalSearch) //syncronize the 5 searchs before render
renderSearchs(resultsArray);
}
});
}

jQuery Wait for select to populate from database

I have ddl(drop down list) which populates from database after change event of another ddl but I want to change the value of this ddl after it populated from database.
Example:
// This work very well
$("#ddlGroups").on('change',function(){
// Load data from database and populate ddlUsers
// response is loaded from database with $.ajax
// Query Example: SELECT User_ID, Username FROM tblUsers WHERE Group_ID = [Group_ID] (Just for undrestanding the question)
var Records = response.d;
$("#ddlUsers").empty();
$.each(Records, function(){
var _Key = this.User_ID;
_Value = this.Username;
$("#ddlUsers").append($("<option />").val(_Key).text(_Value));
});
});
// When button clicked then trigger ddlGroups change event and assign select option from ddlUsers
var _UserID = User_ID_From_Database; // Loaded from Database when button clicked
$("#ddlGroups").trigger('change'); // Users are loaded from database based on group ID
$("#ddlUsers").val(_UserID); // But this dosn't change
How do I check if ddlUsers is loaded or not, I tried while loop but it never stops.
With jquery there are two main ways (really the same underlying) to connect a ajax response from the database to a event or UI result. The first is promises and the second is a callback. Both these have 1 million examples and jquery documentation is quite robust.
In your case rather than "trigger", you callback calls the right function. The below is just junk code to show.
No: $("#ddlGroups").tigger('change');
Yes:
//Your code
$("#ddlGroups").on('change', updateDDL);
//I have just externalized this function to a scope/place where both the ajax and on change line of code can reference it.
function updateDDL(){
var Records = response.d;
$("#ddlUsers").empty();
$.each(Records, function(){
var _Key = this.User_ID;
_Value = this.Username;
$("#ddlUsers").append($("<option />").val(_Key).text(_Value));
}
};
$.ajax(...., function (data) {
// Update ddl, the existing function you have.
// You should already have something like this.
updateDDL(); //Like this
});
BTW: You could pass the data into the updateDDL directly use $(this) in the updateDDL to improve it etc but that is not key to your question/issue. It seems that you are new to jquery and some of the Javascript features it uses. Take a little time to learn about them and you will be WELL rewarded. I would start by reading examples around ajax/jquery and watch how then update the DOM.

My AJAX is only firing once,

I ahave some ajax that is fired when a checkbox is clicked, it essentially sends a query string to a PHP script and then returns the relevant HTML, however, if I select a select it works fine if I then slect another checkbox as well as the previous I get no activity what so ever, not even any errors in firebug, it is very curious, does anyone have any ideas?
//Location AJAX
//var dataObject = new Object();
var selected = new Array();
//alert(selected);
$('#areas input.radio').change(function(){ // will trigger when the checked status changes
var checked = $(this).attr("checked"); // will return "checked" or false I think.
// Do whatever request you like with the checked status
if(checked == true) {
//selected.join('&');
selected = $('input:checked').map(function() {
return $(this).attr('name')+"="+$(this).val();
}).get();
getQuery = selected.join('&')+"&location_submit=Next";
alert(getQuery);
$.ajax({
type:"POST",
url:"/search/location",
data: getQuery,
success:function(data){
//alert(getQuery);
//console.log(data);
$('body.secEmp').html(data);
}
});
} else {
//do something to remove the content here
alert($(this).attr('name'));
}
});
I see you are using the variable checked = $(this).attr("checked"); I think this might be a problem because checked is a standard JS attribute native to JS. You can compare checked normally on an element and see if it is true or false. I would start by changing the name of your variable and move on from there.
The other thing that could be happening is you might be losing your listener which might be caused by your variable selected. You do not need to declare selected outside your listener. Just declare it inside when you set it.
And if THAT doesn't help, providing some markup would help debug this issue because it seems like there is a lot going on here.
Good luck.
I turned out that because my ajax loads in a new page on success the actions were not being put on the elements as they were only being loaded once on DOM ready, I moved the all the script into a function and call that on DOM Ready now and it works great.

Categories