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?
Related
I have multiple text inputs that all share the same class name.
Assuming the code has been written so that only one of those text inputs can have value at any one time, is it possible to search for the value of those text inputs by class name and only return the value of the one that has data written in it by the user?
For the purpose of this question, how would I get that value to be returned in the alert box in the code below?
var input = document.getElementsByClassName("input").value;
alert("input");
If it isn't possible using class names, is there an alternative solution that would achieve the same effect?
I would rather avoid having to give each text input an id and write code for each one, hence wanting to use class names.
//find all the elements, filter out the ones without a value, get the value
$('.theClass').filter(function(){ return this.value.trim(); }).val()
var $inputs = $('.aClass');
$inputs.on('input', function(){
$inputs.not(this).prop('disabled', this.value.trim());
});
$('button').on('click', function(){
console.log(
$inputs.filter(function(){ return this.value.trim(); }).val()
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><input type="text" class="aClass"></div>
<div><input type="text" class="aClass"></div>
<div><input type="text" class="aClass"></div>
<div><input type="text" class="aClass"></div>
<div><button>Get Value</button></div>
Please try this below code,
var matches = document.getElementsByClassName('input');
for (var i=0; i<matches.length; i++) {
//do action
console.log(matches[i].value)
}
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/
I'm fiddling around with js / jquery .. I'm trying to create a preview based on data entered in a form. In one of the input fields a script adds new fields every time you press Tab (or in other words choose the next field). So from these dynamic fields I want to retrieve data from the first two fields and put them into the preview. What I've done is to run a function that adds a number on the end of the id to those fields, so they get the names contestant_1, contestant_2 etc. based on the number of fields that are opened.
I then want the data from contestant_1 and _2 to be entered in boxes in the preview.
What I then made is another function waiting for a keyup event of one of these input fields. BUT it is not able to react to them after they have gained _1 and _2. If I hard code in the first field named _1, then it comes up in the preview.
In the pictures you can see that I have entered Boks1 and Boks2 (Box1 and 2 i Norewegian) in the first two fields, but only Boks1 comes up.
Form
http://imgur.com/fmmYnBu
Preview
http://imgur.com/NcI4lN1
This code is executed when something happens in the field
$('#tname').keyup(update_tname);
$('#contestant_1').keyup(update_contestant_1);
$('#contestant_2').keyup(update_contestant_2);
This is the function that updates are well only the last two that have some importance on exactly this.
function update_contestant_1(){
console.log("Inne i update_contestant_1");
$('#preview').slideDown();
$('#pview_contestant_1').fadeIn();
// Values to preview
var contestant_1 = $('#contestant_1').val();
$('#display_contestant_1').html(contestant_1);
}
Input field looks like this
<lable for="contestant" class="col-md-2 control-label">Contestants:</lable>
<div class="input-group input-group-option col-md-4">
<input class="form-control" type="text" id="contestant_" name="option[]" placeholder="Write contestant here..." required></input>
<span class="input-group-addon input-group-addon-remove">
<span class="glyphicon glyphicon-remove"></span>
</span>
</div>
And this is the function that creates new fields, change id and delete them
$(function () {
// Variable for counting how many contestants fields that are open
var i=0;
$(document).on('focus', 'div.form-group-options div.input-group-option:last-child input', function () {
var sInputGroupHtml = $(this).parent().html();
// Uncomment comments below to inherit div classes from div on index page.
// This is not in use now, because we need a offset to line input fields below each other
// var sInputGroupClasses = $(this).parent().attr('class');
// $(this).parent().parent().append('<div class="' + sInputGroupClasses + '">' + sInputGroupHtml + '</div>');
$(this).parent().parent().append('<div class="input-group input-group-option col-md-4 col-md-offset-2">' + sInputGroupHtml + '</div>');
// Adds a number at the end of the ID
i++;
console.log(i);
var newID='contestant_'+i;
$(this).attr('id',newID);
});
$(document).on('click', 'div.form-group-options .input-group-addon-remove', function () {
$(this).parent().remove();
// Counts down so the next contestants field that opens, has the right number
i--;
console.log(i);
var newID='contestant_'+i;
$(this).attr('id',newID);
});
});
I will be greatfull for any help.
Also, hope I did this right, this is my first post here.
Am able to store one text box to local storage via a button. How would I go about allowing it to take in all the text boxes I have in my 'survey'? Create id's for each text box then listing them all out within the get/set of my js?
<label for="serveri"> Server: </label> <input type='text' name="server" id="saveServer"/> <button onclick="saveData()" type="button" value="Save" id="Save">Save</button>
var save_button = document.getElementById('Save')
save_button.onclick = saveData;
function saveData(){
var input = document.getElementById("saveServer");
localStorage.setItem("server", input.value);
var storedValue = localStorage.getItem("server");
}
To get a better understanding(all text boxes), here is the whole in JSfiddle:http://jsfiddle.net/BDutb/
If you use a library like jQuery you can get the elements and loop through the values very easily. If you want the localStorage variables names to make sense then assign the input fields names and you can do:
See my example here:
http://jsfiddle.net/spacebean/BDutb/11/
$('form').submit(function() {
$('input, select, textarea').each(function() {
var value = $(this).val(),
name = $(this).attr('name');
localStorage[name] = value;
});
});
I shortened the form for demo sake, but you should be able to take it from there.
Edit: updated fixed jsFiddle link.
I've read many blogs and posts on dynamically adding fieldsets, but they all give a very complicated answer. What I require is not that complicated.
My HTML Code:
<input type="text" name="member" value="">Number of members: (max. 10)<br />
Fill Details
So, a user will enter an integer value (I'm checking the validation using javascript) in the input field. And on clicking the Fill Details link, corresponding number of input fields will appear for him to enter. I want to achieve this using javascript.
I'm not a pro in javascript. I was thinking how can I retrieve the integer filled in by the user in input field through the link and displaying corresponding number of input fields.
You could use an onclick event handler in order to get the input value for the text field. Make sure you give the field an unique id attribute so you can refer to it safely through document.getElementById():
If you want to dynamically add elements, you should have a container where to place them. For instance, a <div id="container">. Create new elements by means of document.createElement(), and use appendChild() to append each of them to the container. You might be interested in outputting a meaningful name attribute (e.g. name="member"+i for each of the dynamically generated <input>s if they are to be submitted in a form.
Notice you could also create <br/> elements with document.createElement('br'). If you want to just output some text, you can use document.createTextNode() instead.
Also, if you want to clear the container every time it is about to be populated, you could use hasChildNodes() and removeChild() together.
<html>
<head>
<script type='text/javascript'>
function addFields(){
// Generate a dynamic number of inputs
var number = document.getElementById("member").value;
// Get the element where the inputs will be added to
var container = document.getElementById("container");
// Remove every children it had before
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
// Append a node with a random text
container.appendChild(document.createTextNode("Member " + (i+1)));
// Create an <input> element, set its type and name attributes
var input = document.createElement("input");
input.type = "text";
input.name = "member" + i;
container.appendChild(input);
// Append a line break
container.appendChild(document.createElement("br"));
}
}
</script>
</head>
<body>
<input type="text" id="member" name="member" value="">Number of members: (max. 10)<br />
Fill Details
<div id="container"/>
</body>
</html>
See a working sample in this JSFiddle.
Try this JQuery code to dynamically include form, field, and delete/remove behavior:
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".container1");
var add_button = $(".add_form_field");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) {
x++;
$(wrapper).append('<div><input type="text" name="mytext[]"/>Delete</div>'); //add input box
} else {
alert('You Reached the limits')
}
});
$(wrapper).on("click", ".delete", function(e) {
e.preventDefault();
$(this).parent('div').remove();
x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container1">
<button class="add_form_field">Add New Field
<span style="font-size:16px; font-weight:bold;">+ </span>
</button>
<div><input type="text" name="mytext[]"></div>
</div>