Jquery Autocomplete not working correctly - javascript

I'm using jquery autocomplete.In my case I have multiple autocomplete textbox and hidden field on my page.
e.g
<input class='myclass' type='text'> </input>
<input class='.emp_num_hidden' type='hidden'> </input>
<input class='myclass' type='text'> </input>
<input class='.emp_num_hidden' type='hidden'> </input>
and so on...
so when I fire change event on hidden field then it is raised multiple time
below is my code:
$(".myclass").each(function() {
var $empName= $(this);
var $empNumber = $empName.next('input:hidden');
//things to do
//Setting variable e.g url...
$empName.autocomplete(url,{
//code...
}).result(function(event,data,formatted)
{
$empNumber.val(formatted).change();
});
});
In above code $empNumber holds the hidden field which is used to store autocomplete value i.e in this case when
we select any text from autocomplete then that selected employees number will get store in hidden field.
Based on this hidden field value I want to do ajax call which will return full details of the employee based on his
employee number.
So I have written hanldler to change event of the hidden field as below.
$(.emp_num_hidden).on('change',function (
)};
here 'emp_num_hidden' is the class of the hidden field.
Please suggest how can I prevent multiple event on hidden field change.

This is done using the $(this) object. Since the change event has a target, it will only be effecting one element. The callback function is being executed on this element, this. For example:
$(".emp_num_hidden").on('change', function (e){
alert($(this).val());
});
What will happen is that an alert window will be shown when the hidden field is changed, containing the employee number from only that hidden field. You will also notices there are a few fixes to your code.
Personally, I would make use of both id and class attributes on your objects. This gives you wide scope and narrow scope to your selectors.
Example:
HTML
<input class='myclass' type='text' id='entry-txt-1' />
<input class='emp_num_hidden' type='hidden' id='hide-txt-1' />
<input class='myclass' type='text' id='entry-txt-2' />
<input class='emp_num_hidden' type='hidden' id='hide-txt-2' />
jQuery
$(function(){
var $empName, $empNumber;
$(".myclass").each(function(key, el) {
$empName= $(el);
$empNumber = $empName.next("input[type='hidden']");
// things to do
// Setting variable e.g url...
$empName.autocomplete(url, {
//code...
}).result(function(e, d, f){
$empNumber.val(f).change();
});
});
$(".emp_num_hidden").on('change', function(e){
var empId = $(this).attr("id");
var $employeeNumberField = $("#" + empId);
// Do the needful...
});
});
Taking this a bit further, you may want to consider making use of data attributes. You may also want to look at select event for Autocomplete. Something like:
$(function(){
$(".myclass").autocomplete({
source: url,
select: function(e, ui){
$(this).val(ui.item.label);
$(this).data("emp-number", ui.item.value);
$.post("employeedata.php", { n: ui.item.value }, function(data){
$("#empData").html(data);
});
return false;
}
});
});
This assumes that url returns an array objects with label and value properties. This would add the Employee Number as a data-emp-number attribute to the field that the user was making a selection from. The label being their Employee Name, and the value being their Employee Number. You could also use this callback to show all the other employee data based on Employee Number.
A working example: https://jsfiddle.net/Twisty/zmevd0r0/

Related

Setting values of dynamically added input fields changing all input fields

I have a form where users can create recipes. I start them off with one ingredient field (among others) and then use .append() to add as many more as they want to the div container that holds the first ingredient. The first input field has an id of IngredientName1 and dynamically added input fields are IngredientName2, IngredientName3, etc.
When they start typing in the input field, I pop a list of available ingredients filtered by the value they key into IngredientNameX. When they click on an ingredient in the list, it sets the value of the IngredientNameX field to the text from the div - like a search & click to complete thing. This all works very well; however, when you add IngredientName2 (or any beyond the one I started them with initially) clicking on an available ingredient sets the values of every single IngredientNameX field. No matter how many there are.
I hope this is enough context without being overly verbose, here's my code (I've removed a lot that is not relevant for the purpose of posting, hoping I didn't remove too much):
<div id="ingredientsContainer">
<input type="hidden" id="ingredientCounter" value="1">
<div class="ingredientsRowContainer">
<div class="ingredientsInputContainer"><input class="effect-1 ingredientsInput" type="text" name="IngredientName1" placeholder="Ingredient" id="IngredientName1" data-ingID="1"><span class="focus-border"></span></div>
</div>
<input type="hidden" name="Ingredient1ID" id="Ingredient1ID">
</div>
<script>
$(document).ready(function(){
$(document).on('keyup', "[id^=IngredientName]",function () {
var value = $(this).val().toLowerCase();
var searchValue = $(this).val();
var valueLength = value.length;
if(valueLength>1){
var theIngredient = $(this).attr("data-ingID");
$("#Ingredients").removeClass("hidden")
var $results = $('#Ingredients').children().filter(function() {
return $(this).text() === searchValue;
});
//user selected an ingredient from the list
$(".ingredientsValues").click(function(){
console.log("theIngredient: "+theIngredient);//LOGS THE CORRECT NUMBER
var selectedIngredientID = $(this).attr("id");
var selectedIngredientText = $(this).text();
$("#IngredientName"+String(theIngredient)).val(selectedIngredientText);//THIS IS WHAT SETS EVERYTHING WITH AN ID OF IngredientNameX
$("#Ingredient"+String(theIngredient)+"ID").val(selectedIngredientID);
$("#Ingredients").addClass("hidden");
});
$("#Ingredients *").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
} else {
$("#Ingredients").addClass("hidden")
}
});
$("#AddIngredient").click(function(){
var ingredientCounter = $("#ingredientCounter").val();
ingredientCounter++;
$("#ingredientCounter").val(ingredientCounter);
$('#ingredientsContainer').append('\
<div class="ingredientsRowContainer">\
<div class="ingredientsInputContainer"><input class="effect-1 ingredientsInput" type="text" name="IngredientName'+ingredientCounter+'" placeholder="Ingredient" id="IngredientName'+ingredientCounter+'" data-ingID="'+ingredientCounter+'"><span class="focus-border"></span></div>\
</div>\
<input type="hidden" name="Ingredient'+ingredientCounter+'ID" id="Ingredient'+ingredientCounter+'ID">\
');
});
});
</script>
[UPDATE] I realized the problem is happening because the function is running multiple times. I assume this happening because I'm calling a function on keyup of a field whose id starts with IngredientName so when one has a key up event, all existing fields run the function. How do i modify my:
$(document).on('keyup', "[id^=IngredientName]",function () {
to only run on the field with focus?

Get current array of hidden html element value on the click of array of buttons

I have html elements as:
<input type=hidden class=txtCustomerId value=".parent::current()." />";
<input type=button class=printToTextarea value='Get to box' />
and jquery:
$(".printToTextarea").on("click", function () {
var array = $('.txtCustomerId').map(function() {
return this.value;
}).get();
loadxmldoc(array);
});
It passing all elements as array from hidden field with class name txtCustomerId while I need only current element when button click. Button is also array and both should have same index.
The following code using eq() and index() meet the requirement at much extent.
$(".printToTextarea").on("click", function () {
var i = $('.printToTextarea').index(this);
var custid=$('.txtCustomerId').eq(i).val();
loadxmldoc(custid);
$("#textInput").focus();
});
Change:
$('.txtCustomerId')
to:
$(this).prev('.txtCustomerId')
Well you are selecting all of the elements. So you need to select the one that is related. With your example, you would use prev() to get a reference to the element.
$(".printToTextarea").on("click", function () {
var button = $(this);
var inputValue = button.prev(".txtCustomerId").val();
console.log(inputValue);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type=hidden class=txtCustomerId value="hello" />
<input type=button class=printToTextarea value='Get to box' />
But how you get the input really depends on your HTML. So if the structure is different than the two elements beside each other, than the way to select it would change.

Clear multiple input[type=text] default values on button click before sending

I have a form with a lot of fields and want to clear all the default values (unchanged ones) for the input[type=text] when I click the button preferably using jQuery. I am using the button rather than submit because I am will be using the same button to then submit the form to a local script and then on to a third part for processing. But my script doesn't seem to be working.
A simplified version of the form:
<form name="cpdonate" id="cpdonate" method="post" action="" >
<input type="text" value="First Name" id="BillingFirstName" name="BillingFirstName" onFocus="clearField(this)" onBlur="setField(this)" />
<input type="text" value="Last Name" id="BillingLastName" name="BillingLastName" onFocus="clearField(this)" onBlur="setField(this)" />
<input type="hidden" name="Submit" value="Submit" />
<button id="cpbutton">Submit</button>
</form>
and the script I'm using:
<script type="text/javascript">
$(document).ready(function(){
// default values will live here
var defaults = {};
// Set the default value of each input
$('input[type=text]').each(function(){
defaults[$(this).attr('value')] = $(this).text();
});
// Functions to perform on click
$('#cpbutton').click(function(){
// clear unchanged values
$('input[type=text]').each(function(){
if (defaults[$(this).attr('value')] === $(this).text())
$(this).text('');
});
});
});
</script>
input doesn't have text, it has value and you can't rely on the attribute once user changes it, need to get it from the value property. Also, your defaults object won't locate the value if it is changed.
Am going to store each value on the elements itself using data()
Use val()
$(document).ready(function(){
// Set the default value of each input
$('input[type=text]').each(function(){
$(this).data('val', $(this).val());
});
// Functions to perform on click
$('#cpbutton').click(function(){
// clear unchanged values
$('input[type=text]').each(function(){
if ($(this).data('val') === $(this).val())
$(this).val('');
});
});
});
You should use defaults[$(this).attr('name')] instead of defaults[$(this).attr('value')] because when user changes value then attribute "values" value also changes
You may try this (Example)
// clear unchanged values
$('input[type=text]').each(function(){
if ($(this).val() == this.defaultValue) $(this).val('');
});
An input type=text has .val() jQuery method, not text() and use this.defaultValue to check the initial default value.

Passing jQuery objects to a function

Here is the working demo of what I want to achieve. Just enter some value in input and you might get what I want to achieve. (Yes, I got it working but stay on..)
But it fails when multiple keys are pressed together.
What I am trying :
I have screen which contains few enabled and few disabled input elements. Whenever user updates any value in editable input element, I want to update disabled input which had same value with user updated value.
HTML :
<input value="foo" /> // When User updates this
<br/>
<input value="bar">
<br/>
<input value="Hello">
<br/>
<input value="World">
<br/>
<input value="foo" disabled> // this should be updated
<br/>
<input value="bar" disabled>
<br/>
<input value="foo" disabled> // and this also
<br/>
<input value="bar" disabled>
<br/>
<input value="Happy Ending!">
<br/>
I tried this which I think will save me from multiple_clicks_at_a_time
JS:
$(":input:not(:disabled)").keyup(function () {
// Get user entered value
var val = this.value;
// Find associated inputs which should be updated with new value
siblings = $(this).data("siblings");
$(siblings).each(function () {
// Update each input with new value
this.value = val;
});
});
$(function () {
$(":input:not(:disabled)").each(function () {
// Find inputs which should be updated with this change in this input
siblings = $(":input:disabled[value=" + this.value + "]");
// add them to data attribute
$(this).data("siblings", siblings);
});
});
But I am not able to pass the selectors to keyup function and invoke .each on it.
PS:
My previous completely different try, working with single_click_at_a_time but I felt that I am unnecessarily traversing the DOM again and again so dropped this
$(":input").keypress(function () {
$(this).data("oldVal", this.value);
});
$(":input").keyup(function () {
var oldVal = $(this).data("oldVal");
$(this).data("newVal", this.value);
var newVal = $(this).data("newVal");
$("input:disabled").each(function () {
if (this.value == oldVal) this.value = newVal;
});
});
I would group those inputs first and bind a handler for enabled elements to apply to the group. See below,
var grpInp = {};
$(":input").each(function () {
if (grpInp.hasOwnProperty(this.value)) {
grpInp[this.value] = grpInp[this.value].add($(this));
} else {
grpInp[this.value] = $(this);
}
});
$.each(grpInp, function (i, el) {
el.filter(':enabled').keyup(function () {
el.val(this.value);
});
});
DEMO: http://jsfiddle.net/fjtFA/9/
The above approach basically groups input element with same value, then filters them based on :enabled and bind a handler to apply it to the group.
// Find associated inputs which should be updated with new value
siblings = $(this).data("siblings", siblings);
No. The .data method called with two arguments does not get, but set the data (and returns the current selection). Also, you should make your variables local:
var siblings = $(this).data("siblings");
Working demo

Persisting textbox value using jQuery

I'd like to save the newly entered values, so I could reuse them. However, when I try to do the following, it does not work:
// el is a textbox on which .change() was triggered
$(el).attr("value", $(el).val());
When the line executes, no errors are generated, yet Firebug doesn't show that the value attribute of el has changed. I tried the following as well, but no luck:
$(el).val($(el).val());
The reason I'm trying to do this is to preserve the values in the text boxes when I append new content to a container using jTemplates. The old content is saved in a variable and then prepended to the container. However, all the values that were entered into the text boxes get lost
var des_cntr = $("#pnlDesignations");
old = des_cntr.html();
des_cntr.setTemplate( $("#tplDesignations").html() );
des_cntr.processTemplate({
Code: code,
Value: val,
DivisionCode: div,
Amount: 0.00
});
des_cntr.prepend(old);
This is the template:
<div id="pnlDesignations">
<script type="text/html" id="tplDesignations">
<div>
<label>{$T.Value} $</label>
<input type="text" value="{$T.Amount}" />
<button>Remove</button>
<input type="hidden" name="code" value="{$T.Code}" />
<input type="hidden" name="div" value="{$T.DivisionCode}" />
</div>
</script>
</div>
You want to save the previous value and use in the next change event?
This example uses .data to save the previous value. See on jsFiddle.
$("input").change(function(){
var $this = $(this);
var prev = $this.data("prev"); // first time is undefined
alert("Prev: " + prev + "\nNow: " + $this.val());
$this.data("prev", $this.val()); // save current value
});
jQuery .data
If you want old/Initial text box value, you can use single line code as follows.
var current_amount_initial_value = $("#form_id").find("input[type='text']id*='current_amount']").prop("defaultValue");
If you want current value in the text box, you can use following code
$("#form_id").find("input[type='text']id*='current_amount']").val();

Categories