Jquery ui autocomplete incorrectly detects change on page load - javascript

I have a set of fields that are autocomplete fields. Each one is set up to detect when a change is made and if the final value does not match any suggestions, it puts the field in an error state and asks the user to select an existing item. Here is the code:
$.each($(".autocomplete"), function () {
$(this).autocomplete({
source: $(this).attr("autocomplete-url"),
autoFocus: true, //Just press enter to select top item
minLength: 0,
response: function (event, ui) {
if (ui.content.length == 1) {
$(this).val(ui.content[0].value);
$(this).removeClass("is-invalid").next("span").remove(); //valid value, remove error
}
},
change: function (event, ui) { //if detects a string that was not suggested (meaning does not exist in DB), clear value and show not valid
if (!(ui.item)) { //don't close the dropdown - causes ui.item to be undefined
$(this).val("");
$(this).addClass("is-invalid").after("<span class='invalid-feedback'><strong>Please choose an existing " + $(this).attr('name') + ".</strong></span>");
}
}
});
});
This works fine except in one case - if there is an error elsewhere in the form and the page reloads with the other form errors (No error in the autocomplete field), the originally selected item in the autocomplete shows for a split second, then the change event runs removing the value and putting the field in a state of error with the message "Please choose an existing item."
Is there a way to tell the autocomplete that the value it contains on page reload is in fact valid and has not changed - it's the same value that was valid before page reload? Or, does anyone have another suggestion like maybe suppressing the autocomplete change even when the page reloads and then enabling it again in case the user selects another item?

Related

Validation works but does not keep the selected div open

Having a Save call this JavaScript
submit('formName',null,{Method:'Post'}); - Basically null should contain the divname when validation fails, it should point to that div
The above is working, but when the validation fails it moves to the first tab, i want it to stay in the open tab by passing the divname to this submit form
i have this code to validate and get the divname of the failed validation form field
function AClick(ic) {
if($("#divSubFeature_" + ic).is(':visible')) {
alert("aa");
//$("#divSubFeature_" + ic).css('display','block');
}
}
so not sure how i pass the divname to the submit function so it keeps that tab open
any idea?

Simulate Mouse Click on dropdown

My Wordpress theme interacts with WooCommerce so that when a user selects a specific product variable from a drop-down a particular price is shown for their region.
This works fine when a user manually selects the drop-down, however, I'm trying to speed up the process by pre-selecting the appropriate option for the user based on a browser cookie (or lack of one).
For instance, if the user hasn't entered their region their browser will not have a cookie I've named "pc-entered" and the following jQuery script will run:
$(function() {
$('ul li.product').each( function() {
/*If no region set by cookie*/
if( document.cookie.indexOf("pc-entered=") < 0) {
/*Set downdown to generic*/
$(this).find("#pa_region").val('generic');
}
});
});
This works, successfully pre-selecting the correct 'generic' dropdown option automatically.
Unfortunately, and this is where I'm stuck - although the dropdown is correct the price isn't auto-populating like it does when a user manually selects their region.
E.g.
1) When auto-populated using my script:
2) When user selected:
I've tried replacing this in my script:
$(this).find("#pa_region").val('generic');
With the options listed on this thread, however, they don't seem to work in this case. I've also tried firing the script after all other scripts on the page and even delaying the script running with a timeout function but nothing seems to be working.
My test site is here.
TLDR - Why is my jQuery script not populating the price?
With $(this).find("#pa_region").val('generic'); you are only changing the HTML value (text) of dropdown.
You need to attach the event handler which will trigger the change to the function where you change the value.
function changeValue(){
$("#pa_region").val('generic');
$("#pa_region").trigger('change');
}
$( "#pa_region" ).change(function() {
console.log( "Handler for .change() called." );
});
This is the way on how to solve it.
I also made a JSFiddle so you can test it.

Navigate to element in Different tab of same page using focus() function

I am doing validation of entire form which is spread into different section where each section is a nav-tab , when i fill the entire form and cursor is in the last section, on clicking the save button if there is a validation mismatch of textbox in first section(first nav-tab) and if i want the user to be focused to the failed textbox document.getElementById(ID).focus()
is not navigating to the element where validation has failed.
How to achieve the above functionality??
function validate()
{
var valid = true;
var alphaFilter = /^[A-z]{0,}$/;
if (!(alphaFilter.test($('#fieldId').val()))
{
if(valid){$('#fieldId').focus();}
$('#fieldId').css("border-color", "#e84e40");
valid = false ;
}
--- each field has its own if condition
return valid;
}
validate function is called inside the submit function for further processing and valid variable is used to focus first invalid entry in the form.
I would make a param to take in selectors to make this more usable.
Something like this..
function switchtab (){
$("#tab1").removeClass("active");
$("#tab2").addClass("active");
$("#tabpanel1").removeClass("active");
$("#tabpanel2").addClass("active");
//should be good to focus now
$(selector).focus();
}

How do I stop the page reload after selecting an autocomplete suggestion

I made an autocomplete for a form input field that allows a user to add tags to a list of them. If the user selects any of the suggestions, I want the page to use add the new tag to a section of tags that already exist without the page reloading.
I want this to happen with 3 scenarios:
The user types in the tag, ignores the autocomplete suggestions and presses enter.
After typing in any part of a query, the user selects one of the autocomplete suggestions with the arrow keys and presses enter.
After typing in any part of a query, the user clicks on one of the autocomplete suggestions with the mouse.
I have been able to make scenario 1 work flawlessly. However, scenarios 1 and 2 make the page reload and still doesn't even add the tag to the list.
Scenarios 1 and 2 are both called by the same function:
$j("#addTag").autocomplete({
serviceUrl:'/ac',
onSelect: function(val, data){
addTag(data);
}
});
And here is the code for addTag():
function addTag(tag){
var url = '/addTag/' + tag;
//Call the server to add the tag/
$j.ajax({
async: true,
type: 'GET',
url: url,
success:function(data){
//Add the tag to the displayed list of already added tags
reloadTagBox(data);
},
dataType: "json"
});
//Hide the messages that have been displayed to the user
hideMessageBox();
}
Scenario 1 code:
function addTagByLookup(e, tag){
if(e && e.keyCode == 13)
{
/*This stops the page from reloading (when the page thinks
the form is submitted I assume).
*/
e.preventDefault();
//If a message is currently being displayed to the user, hide it
if ($j("#messageBox").is(":visible") && $j("#okayButton").is(":visible")){
hideMessageBox();
}
else{
//Give a message to the user that their tag is being loaded
showMessageBox("Adding the tag <strong>"+tag+"</strong> to your station...",'load');
//Check if the tag is valid
setTimeout(function(){
var url = '/checkTag/' + tag;
var isTagValid = checkTag(tag);
//If the tag is not vaid, tell the user.
if (isTagValid == false){
var message = "<strong>"+tag+"</strong>"+
" was not recognized as a valid tag or artist. Try something else.";
//Prompt the user for a different tag
showMessageBox(message, 'okay');
}
//If the tag is valid
else{
addTag(tag);
}
}, 1000);
}
}
}
I know I used the e.preventDefault functionality for a normal form submit in scenario 1, but I can't seem to make it work with the other scenarios and I'm not even sure that is the real problem.
I am using pylons as the MVC and using this tutorial for the autocomplete.
So in case anyone wants to know, my problem was had an easy solution that I should have never had in the first place.
My input tag was embedded in a form which submitted every time the input tag was activated.
I had stopped this problem in scenario 1 by preventing the default event from occurring when the user pressed enter. But since I didn't have access to this event in the jQuery event .autocomplete(), I couldn't prevent it.

jQuery UI Autocomplete: Clear Previous Search Term

On the keydown event of the jQuery UI Autocomplete widget the default case statement has the following code:
default:
// keypress is triggered before the input value is changed
clearTimeout( self.searching );
self.searching = setTimeout(function() {
// only search if the value has changed
if ( self.term != self.element.val() ) {
self.selectedItem = null;
self.search( null, event );
}
}, self.options.delay );
break;
From what I can see the sixth line of the above code prevents execution if the user types in the same value twice. This makes sense most of the time but in my scenario it is causing a problem.
I am building an ajax application that has a fixed header with a search input at the top. The user can type in anything they want into the search box and a div will pop up with the search results matching their query. If the user types in 'abc' and clicks on a result, it loads the corresponding page via ajax and clears the search box. The problem is that if they user types in 'abc' again, the search method is not fired as what they typed in matches what they last searched for.
Is there a way to clear the self.term value stored within the widget when the user clicks on a search result? Or is there another way to resolve my problem without having to cook up my own version of the Autocomplete widget?
Thanks
Doing the following resets the previous search term:
$('#AutocompleteElementID').data().autocomplete.term = null;
If you do the following when an item is selected, it will clear the previous search term and make the widget perform a search if they type in the same value again.
Unfortunately,
$(this).data().autocomplete.term = null;
does not clear the input field. To do so, the following works:
close: function(event, ui) {
// Close event fires when selection options closes
$('input')[0].value = ""; // Clear the input field
}
if the autocomplete function returns self, for your autocomplete element you should just be able to call
$yourAutoCompleteElement.term = null;
when you want to clear it.
close: function(event, ui)
{
// Close event fires when selection options closes
$(this).data().autocomplete.term = null; // Clear the cached search term, make every search new
},
This DID NOT work for me:
$(this).data().autocomplete.term = null;
However this DID work for me in jQuery UI - v1.10.2:
$(this).data().term = null;
You should try :
$("#AutocompleteElementID").autocomplete("instance").term = null;
Let me know if it works for you
The APIs have changed in the latest versions of jQuery/jQuery UI.
The correct way of accessing the property on the widget instance now is:
$("#AutocompleteElementID").autocomplete("instance").term = null;
Code example: http://jsfiddle.net/altano/sdpL17z5/
Verified working with jQuery UI 1.11.4 and jQuery 2.2.3
After Clearing the text field you can reset the previous search by invoking the jquery ui autocomplete "search" method with an empty string.
$('#AutocompleteElementID').autocomplete( "search", "" );
By default there is a minimum search length that has to be met before any items show up, so it effectively clears the search without displaying all the results.
http://api.jqueryui.com/autocomplete/#method-search
This should be a stable way to handle this situation as the search method hasn't changed over time.

Categories