Select Option not showing selected value sometimes - javascript

I have a group of select option and each are relational from top to bottom by ajax. This is works fine in insert mode. But in edit mode when i push data to perform ajax operation and set the selected value based on stored data, It sometime not setting the value though the data is loaded to DOM and sometime it's working.
Actually if any data would miss, all the next data won't be loaded. but here 3rd and 4th data missed but 5th data is loaded.
I can't figure it out what is the problem. Please help if possible.
This is one of the ajax function to load data to district section
function loadDistricts(division1, distidentifier) {
return $.ajax({
type: 'post',
url: 'GetDistricts',
data: {
get_option:division1
},
success: function(response) {
$(distidentifier).html(response);
}
});
}
This is the function to call the ajax function and select the proper value
function loadAdress(divi, diviselect, dist, distselect, upaz, upazselect, unio, unioselect, vill, villselect){ // Id of all address field and jquery selector pass here
$(diviselect).val(divi).trigger('change');
loadDistricts(divi, distselect).done(function() {
$(distselect).val(dist).prop('selected', 'selected').trigger('change');
loadUpazilla(dist, upazselect).done(function() {
$(upazselect).val(upaz).prop('selected', 'selected').trigger('change');
loadUnion(upaz, unioselect).done(function(){
$(unioselect).val(unio).prop('selected', true).trigger('change');
loadVillage(unio, villselect).done(function(){
$(villselect).val(vill).trigger('change');
});
});
});
});
}
And finally I called the function, with value and jqueryidentifire --
loadAdress(divipid, '#divisions', distpid, '#districts', upapid, '#upazila', unipid, '#allunions', villpid, '#villages');
Any suggestion is appreciated.

Related

Always show autocomplete list, even if search doesn't match

I have an autocomplete field, and on type I go to the PHP/Database to retrieve the matching options.
Thing is, my suggestion list isn't exactly matches of the text. I explain:
Say I type "Jon". My list will bring from the database "John Doe", "Jonatan", etc. Only "Jonatan" will be visible as the suggestion to the input, but I do need them all, because it considers approximation (there's a soundex element on my backend search).
My JavaScript/Ajax code:
function prePatientsList(){
//I'm limiting search so it only starts on the second character
if (document.getElementById("name").value.length >= 2) {
try
{
listExecute.abort();
}catch(err) {
null;
}
var nome= $("#name").val();
var nomeList = "";
listExecute = $.ajax({
url: '/web/aconselhamento/Atendimento/PrePacientesAutocomplete',
type: "POST",
async: true,
datatype: 'json',
data: { nome: nome}
}).done(function(data){
source = JSON.parse(data);
});
$(function() {
$("input#nome").autocomplete({
source: source,
// I know I probably don't need this, but I have a similar component which has an URL as value, so when I select an option, it redirects me, and I'll apply you kind answer on both.
select: function( event, ui ) {
ui.item.label;
}
});
});
}
}
Thanks.
I think you'd have to set your remote endpoint directly as the autocomplete's source (e.g. similar to https://jqueryui.com/autocomplete/#remote) so that it's the backend which does all the filtering. Right now, the autocomplete effectively thinks you've fed it a static list of options from which further filtering should take place, and therefore it decides to handle the filtering itself.
Your code can be as simple as this I think, no need to have a separate handler or an ajax request outside the scope of the autocomplete.
$(function() {
$("input#nome").autocomplete({
minLength: 2, //limit to only firing when 2 characters or more are typed
source: function(request, response)
{
$.ajax({
url: '/web/aconselhamento/Atendimento/PrePacientesAutocomplete',
type: "POST",
dataType: 'json',
data: { nome: request.term } //request.term represents the value typed by the user, as detected by the autocomplete plugin
}).done(function(data){
response(data); //return the data to the autocomplete as the final list of suggestions
});
},
// I know I probably don't need this, but I have a similar component which has an URL as value, so when I select an option, it redirects me, and I'll apply you kind answer on both.
select: function( event, ui ) {
ui.item.label;
}
});
});
See http://api.jqueryui.com/autocomplete/#option-source for more info.

Jeditable and AJAX reload

I have a table that i load with AJAX and edit with Jeditable.
This is how i start my function:
function refresh_page() {
var tableElm = $('#refresh');
$.ajax({
url: 'assets/php/ritsys/my_table.php',
success: function(data) {
if (!($("*:focus").is("textarea, input, select, date, time")) ) {
tableElm.html(data)
}
$(function(){
$('.edit').editable('assets/php/ritsys/save.php', {
indicator : '<img src="assets/css/smoothness/images/ui-anim_basic_16x16.gif">'
});
});
setTimeout(refresh_page, 1500);
}
}); };
This works fine and i added the if (!($("*:focus").is("textarea, input, select, date, time")) ) { line because i had problems with the data refreshing while i was editing something in the table.
But after i added this everytime when i update a value in the table firstly it shows me the indicator image, then the old value and after that the new value.
Before it would briefly show the indicator and then the new value. Can somebody help me to cut out the step where it shows the old data?
It would be greatly appreciated!
Does the script assets/php/ritsys/save.php return the "new" value? You should return the "new" value, not the "old" value. The returned value will be shown when the request is complete.

Waiting for all AJAX call than show dialog box

I am working on a dynamic online form website. In the main form, I have multiple sub-forms which can be added and deleted dynamically.
<div class='subform'>
//form fields
<input ...>
...
<button class='subform_submit'>
</div>
For each subform, I bind an AJAX call on the subform's submit button like this:
$('#main').on('click', '.subform_submit', function(){
// Get this subform's user input
...
$.ajax({
url: ..,
type: ..,
data: /* this subform's data */
});
});
So in that page, I may have 0 to 10 subforms depending on the user's selection.
I also have a main submit button on the bottom of the page, which can submit those subforms and the main form's data together.
$('#main').on('click', '#submit', function(e){
$('.subform_submit').click(); // Submit each subform
bootbox.confirm({ });
})
Once main submit button is clicked, I want to show a loading picture and then show a dialog box (I use bootbox.confirm() here) until all AJAX calls have completed.
This dialog box is telling user that whole form including sub-forms has been submitted.
But the problem is that each AJAX call may take 2 seconds to complete and I don't know how may calls may be pending completion. How can I write this main submit button so that it will:
Show the loading image immediately, and
Hide the loading image and show the dialog box after all AJAX calls have completed?
Keep track of how many sub-forms there are;
$subFormsCount = $('.subform').length;
Keep track of how many forms have been submitted;
$submittedForms = 0;
Each time a form finishes submitting, add to the $submittedForms;
$.ajax({
..
..
done: function(){
$submittedForms++;
}
})
Create a global timer to see if the number of submitted forms matches the total number of subforms. If true, hide the dialog box;
setInterval(function(){
if($submittedForms == $subFormsCount){
$('.dialog').show();
}
}, 50ms)
Edit
You could skip the global timer (as this will probably be a few milliseconds out) - include the check in your ajax.done instead;
$.ajax({
..
..
done: function(){
$submittedForms++;
if($submittedForms == $subFormsCount){
$('.dialog').show();
}
}
})
You want to use .done() in order to specify code that should wait until the AJAX asynchronous function completes.
$.ajax({
url:..,
type: ..,
data: /* this subform's data*/ })
.done(function() {
//Put code here
});
Have you tried .ajaxStop() event handler ?
$(document).ajaxStop(function() {
// place code to be executed on completion of last outstanding ajax call here
});
also, check this answer
I assume you have 9 subform and 1 main form.
Code for 8 subform will be same.
I use here async:false : Means next ajax will not be call until 1st one is not completed.
Sample Code Format :
var id = 5;
$.ajax({
url: ,
type: 'POST',
data: {'id':id},
dataType: 'JSON',
async: false,
error : function(xhr, textStatus, errorThrown) {
alert('An error occurred!');
},
success : function(response){
}
});
Just set variable in your last sub form that is 9th subform.
success : function(response){
var counter = true;
}
if(counter){
/* Code to show dialog.*/
}
You can use $.when to wait for each request to complete. Something like this should get you close. You'd basically want to store all the ajax requests in an array and pass that to when as the arguments.
$('#main').on('click', '.subform_submit', function () {
var formRequests = $('.subform').map(function () {
var $form = $(this);
return $.ajax({
url: '',
data: $form.serialzeArray()
});
}).get();
$.when.apply(undefined, formRequests).done(function () {
console.log('All done!');
});
});
Here goes a very similar little demo I just made up: https://jsfiddle.net/g9a06y4t/

jquery Select2 prevent selecting in ajax response

I want to prevent from adding a category to the Select2 element if it fails creating the row first in my db. The action is not prevented when i call ev.preventDefault(); Nothing happens.. what is wrong?
$('#sel2').select2({
placeholder: 'Enter categories',
minimumInputLength: 3,
multiple: true,
ajax: {
url: 'async/get_categories.php',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
q: term,
};
},
results: function (data, page) {
return {
results: data.items
};
},
cache: true
},
formatResult: format,
formatSelection: format
}).on('select2-selecting', function(e) {
console.log(e);
if (e.val == 4) {
// if category id equals 4
// do not add this category to select 2
// e.preventDefault();
// the above works just fine and its just for testing
}
// Is something wrong here?
var ev = e;
$.ajax({
type: 'POST',
url: 'async/create_profile_category.php',
data: {
profile_id: '1',
category_id: ev.val
},
success: function(response) {
console.log(response);
if (response.error === false) {
// category assigned successfully
} else {
// failed to assign category
// so i want now to prevent from adding to select2
console.log('should not add this category');
ev.preventDefault();
// the above is not working
}
},
error: function() {
alert('Failed to assign category!');
}
});
});
The AJAX request is made asynchronusly, so by the time it has finished the element has already been added. Even though you are calling ev.preventDefault(), it is too late for it to make a difference. So this leaves you with two options:
Make the request synchronusly, which will allow preventDefault to make the difference.
Make the request asynchronusly, and manually remove the element if it fails.
Both options have their pros and cons, and it's up to you to decide which option you go with.
Making the request synchronusly
Pros
The value will never be added if the request fails.
Works well in cases where the element cannot be added quite often.
Cons
Blocks the UI - So the user is potentially left with an unresponsive page while the request is made.
Making the request asynchronusly
Pros
Does not block the UI.
Works well in cases where elements typically can be added.
Cons
The value will always show up for the user, even if it fails later.
You must manually unset the new option.
What's important to consider here is the user experience of both options. When making synchronus requests, it's not uncommon for the browser to stop relaying events - which gives the illusion that the UI has locked up and the page has gone unresponsive. This has the benefit of ensuring that the value never shows up if it isn't allowed. But if users typically can add the elements, it also has the downside of complicating the most common use case.
If users can usually add elements, then it is a better experience to add the element while the request is being made, and then notifying the user later (while removing the element) if there was an issue. This is very common is web applications, and you can see it being used in many places, such as the Twitter and Facebook like buttons (where requests usually work), as well as places on Stack Overflow.
There is a way to get around this with version4 of the select2 library.
on select2:selecting we cancel the preTrigger event. Which will stop the select2:select event. We do our ajax call. On success we then get out Select2 instance then call the trigger of the Observer that way it by passes overwritten trigger method on your select2 instance.
The call method needs your select2 instance as the context so that the existing listeners are available to call.
var sel = $('#sel');
sel.select2(config);
sel.on('select2:selecting', onSelecting);
function onSelecting(event)
{
$.ajax({
type: 'POST',
url: 'async/create_profile_category.php',
data: {
profile_id: '1',
category_id: event.params.args.data.id
},
success: function(event, response) {
console.log(response);
if (response.error === false) {
// category assigned successfully
// get select2 instance
var Select2 = $users.data('select2');
// remove prevented flag
delete event.params.args.prevented;
// Call trigger on the observer with select2 instance as context
Select2.constructor.__super__.trigger.call(Select2, 'select', event.params.args);
} else {
// failed to assign category
// so i want now to prevent from adding to select2
console.log('should not add this category');
}
}.bind(null, event),
error: function() {
alert('Failed to assign category!');
}
});
event.preventDefault();
return false;
}
here how I did it for yii2 Select2 integrated into Gridview:
'pluginEvents' => [
'select2:selecting' => "
function(event)
{
var select2 = $('#types-" . $model->id . "');
select2.select2('close');
$.post('update',{id: " . $model->id . ", type_id: event.params.args.data.id})
.done (function(response)
{
select2.val(event.params.args.data.id);
select2.trigger('change');
})
.fail(function(response)
{
krajeeDialog.alert('Error on update:'+response.responseText);
});
event.preventDefault();
return false;
}",
],
it allows to asynchoronous update data in the grid using select2 and ajax and return it to previous value if there was an error on updating.

Modifying html of dom element that was created after page loaded

I have two separate AJAX calls. One that gets a list of items from a txt file and creates an HTML table out of them and one that talks to a database to find how much each item costs and then lists this in the corresponding table cell for each item (I know this may sound like a strange approach, but it's a good option in our case...).
The issue is that the price is not getting written to the table since the table is created (or to be precise, the rows of the table are created) after the page loads. I'm not sure how to fix this.
$(document).ready(function() {
makeItemTable();
listPrices();
...
});
function makeItemTable() {
$.ajax({
url: 'products.php',
type: 'GET'
})
.done(function(response) {
$('.price-table > tbody').html(response);
})
}
function listPrices() {
.ajax({
url: 'prices.php',
type: 'GET'
})
.done(function(response) {
priceData = $.parseJSON(response);
$('.price-table tr').each(function() {
var item = $(this).find('td:nth-child(1)').text();
if (priceData[item]) {
var price = priceData[item];
$(this).find('td:nth-child(2)').text(price);
}
})
}
You can try
Using setTimeout to check request to 'products.php' execute callback done (inside callback for request to 'prices.php')
Another way
var jqxhr1 = $.ajax("products.php");
var jqxhr2 = $.ajax("prices.php");
$.when(jqxhr1, jqxhr2).done(function(jqxhr1, jqxhr2) {
// Handle both XHR objects
alert("all complete");
});
Call function listPrices() inside callback request to 'products.php'
Hope to help

Categories

Resources