jQuery - Allow user to add a maximum of 4 divs/user inputs - javascript

I'm trying to emulate this jsfiddle (code also shown below) and modify it to allow user to add a maximum of 4 fields
JS:
$(function() {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;
$('#addScnt').live('click', function() {
$('<p><label for="p_scnts"><input type="text" id="p_scnt" size="20" name="p_scnt_' + i +'" value="" placeholder="Input Value" /></label> Remove</p>').appendTo(scntDiv);
i++;
return false;
});
$('#remScnt').live('click', function() {
if( i > 2 ) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
HTML:
<h2>Add Another Input Box</h2>
<div id="p_scents">
<p>
<label for="p_scnts"><input type="text" id="p_scnt" size="20" name="p_scnt" value="" placeholder="Input Value" /></label>
</p>
</div>
Additionally, I tried reworking and updating code for the latest version of jQuery 1.11.0, updating function, .live() to .on() and .size() to .length() per jQuery documentation, but no luck...code didn't work that way.
Any help is much appreciated.

You have to use .on() to attach event handlers. Also, replace ID with class because there will be multiple input elements.
You can use the property .length to get the count of elements
In order to delete, you have to delegate the events since the remove anchor tag will be added dynamically to the DOM. Like this $('#p_scents').on('click','.remScnt', function(){ });
This works with jQuery 1.10.1
Overall, something like this should do.
$(function () {
var scntDiv = $('#p_scents');
var i = $('.p_scnt').length;
$('#addScnt').on('click', function () {
if (i >= 4) return;
$('<p><label for="p_scnts"><input type="text" class="p_scnt" size="20" name="p_scnt_' + i + '" value="" placeholder="Input Value" /></label> Remove</p>').appendTo(scntDiv);
i++;
});
$('#p_scents').on('click', '.remScnt', function () {
if (i > 0) {
$(this).closest('p').remove();
i--;
}
});
});
Here is a demo http://jsfiddle.net/dhirajbodicherla/tZPg4/13620/
Also you can improve the add functionality to something like for a cleaner code
$('#addScnt').on('click', function () {
if (i >= 4) return;
var newInput = $('<input type="text" size="20" name="p_scnt_' + i + '" placeholder="Input value" />');
var removeLink = $('Remove</p>');
var newEl = $('<p></p>').append(newInput).append(removeLink);
newEl.appendTo(scntDiv);
i++;
});

Related

How can I call a jquery function on selecting a dropdown option for dynamically created inputs?

So this is what the page looks like currently:
The first one is hardcoded in and then the rest are added/removed by the buttons. The first one can also be added and removed from the buttons. I want to call a jquery function when the dropdown is changed to change the type from textbox/radiobutton (and text)/checkbox (and text) etc.
Currently it only works on the first Question/Answer and only works if it is the original and not dynamically created. I'm not sure why that is.
Here is how the Q/A's are created and removed
$("#addButton").click(function () {
if (counter > max_fields) {
alert("Only " + max_fields + " Questions allowed");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<label>Question #' + counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="questionbox' + counter + '" value="" />' +
' <select id="choice'+ counter +'"><option>Type</option><option>Radio Button</option><option>Text Box</option><option>Check Box</option></select>' +
'<button id = "remove' + counter + '">Remove</button>' +
'<br/><label>Answer #' + counter + ' : </label>' +
'<div id="Answers' + counter + '">' +
'Option 1: <input type="text" id="answerbox' + counter +
'1" name="answerbox' + counter + '" value="" />' +
'<br/>Option 2: <input type="text" id="answerbox' + counter +
'2" name="answerbox' + counter + '" value="" />' +
'<br/>Option 3: <input type="text" id="answerbox' + counter +
'3" name="answerbox' + counter + '" value="" />' +
'<br/>Option 4: <input type="text" id="answerbox' + counter +
'4" name="answerbox' + counter + '" value="" /></div>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("#removeButton").click(function () {
if (counter == 1) {
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
This is how I tried to get it to change types
$('#choice1').change(function () {
var selected_item = $(this).val()
var searchEles = document.getElementById("Answers1").children;
alert(searchEles.length);
for(var i = 0; i < searchEles.length; i++) {
$('#answerbox1' + i).attr('type', selected_item);
//alert(searchEles.length);
}
});
The web page code is as follows
<input type='button' value='Add Question' id='addButton'/>
<input type='button' value='Remove Question' id='removeButton'/>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Question #1 : </label>
<input type='text' id='questionbox1'/>
<select id="choice1" onchange="$('#choice').val('id');"> //this on change was added and currently does nothing it seems.
<option value="">Type</option>
<option value="radio">Radio Button</option>
<option value="text">Text Box</option>
<option value="checkbox">Check Box</option>
</select>
<button id="remove1">Remove</button>
<br/><label>Answer #1 : </label>
<div id="Answers1">
Option 1: <input type="text" id='answerbox11' name='answerbox1' value="" />
<br/>Option 2: <input type="text" id='answerbox12' name='answerbox1' value="" />
<br/>Option 3: <input type="text" id='answerbox13' name='answerbox1' value="" />
<br/>Option 4: <input type="text" id='answerbox14' name='answerbox1' value="" />
</div>
</div>
</div>
I tried to do something like onchange and then get the ID and go from there but that didn't work. I know it doesn't match the back end jquery name.
TL;DR
I don't know how to dynamically write the jQuery function to work
for all of them.
I don't know why even if I hardcode it to #choice1 it will work
when its first created but not if i remove and add it even though it
has the same exact values. I think it might MAYBE have to do with
for loop, because the alert doesn't even trigger the second time
around.
You could try
$(document).on("change", ".selector", function(){
//do something
});
//Edit
Add to the select element class for example select-option and a tag that will hold the select's counter
//JS
...'<select id="choice'+counter+'" class="select-option" number="'+counter+'">'...
and then your on change function would look something like
$(document).on("change", ".select-option", function(){
//do something
var selected_type = $(this).attr('value');
var ans_number = $(this).attr('number');
$("#answerbox"+ans_number).children('input').attr('type', selected_type);
});
I hope this will help :)
For dynamically added elements use
$(selector).on("change", callback)
If element is dynamic then Jquery will not bind directly as
$('#choice1').change(function (){});
But for that you need to call same function with some static element.
For Ex:
$(".listingDiv").find('#choice1').change(function (){});
or
$(document).find('#choice1').change(function (){});
and it will work. try it.
When elements will be aded dynamically, best practice is to delegate the handler(s). Put your handler on the containing div or window/document
.
First
<select id="choice1" onchange="$('#choice').val('id');"> //this on change was added and currently does nothing it seems.
This is one reason your never be called. If you bind an event listener to an element, you should not write the actual JS code inside the element.
Second
Bind your listener like this:
$('#choice1').on("change", function () {
var selected_item = $(this).val()
var searchEles = document.getElementById("Answers1").children;
alert(searchEles.length);
for(var i = 0; i < searchEles.length; i++) {
$('#answerbox1' + i).attr('type', selected_item);
//alert(searchEles.length);
}
});

jQuery input number spinner

I have this code for jQuery spinner up-down number :
HTML:
<div class="container">
<div class="input-group spinner">
<input type="text" class="form-control" value="42">
<div class="input-group-btn-vertical">
<div class="btn btn-default"><i class="fa fa-caret-up"></i></div>
<div class="btn btn-default"><i class="fa fa-caret-down"></i></div>
</div>
</div>
</div>
JS:
(function ($) {
$('.spinner .btn:first-of-type').on('click', function() {
$('.spinner input').val( parseInt($('.spinner input').val(), 10) + 1);
});
$('.spinner .btn:last-of-type').on('click', function() {
$('.spinner input').val( parseInt($('.spinner input').val(), 10) - 1);
});
})(jQuery);
This Worked But I need to add two option:
prevent user add number to input
set Maximum and Minimum for number
How do add this option?!
DEMO FIDDLE
Change:
<input type="text" class="form-control" value="42">
To:
<input type="number" min="0" max="10" steps="1" class="form-control" value="5">
I didn't quite understand from your question if you wanted the user to be able to change the value or not, in the case that you don't want them to change the value, just add the readonly attribute to the input field, like this
<input type="number" min="0" max="10" steps="1" class="form-control" value="5" readonly>
To do this all with jQuery which i assume you want:
$(document).ready(function(){
//Stop people from typing
$('.spinner input').keydown(function(e){
e.preventDefault();
return false;
});
var minNumber = 1;
var maxNumber = 10;
$('.spinner .btn:first-of-type').on('click', function() {
if($('.spinner input').val() == maxNumber){
return false;
}else{
$('.spinner input').val( parseInt($('.spinner input').val(), 10) + 1);
}
});
$('.spinner .btn:last-of-type').on('click', function() {
if($('.spinner input').val() == minNumber){
return false;
}else{
$('.spinner input').val( parseInt($('.spinner input').val(), 10) - 1);
}
});
});
I haven't check but should be pretty accurate
Working Fiddle: http://jsfiddle.net/7jtLa3py/3/
Better Ways :
bootstrap spinner DEMO
jQuery Spinner
jQueryUI spinner
bootstrap snipper worked easy:
HTML
<input type="text" class="aSpinEdit" />
Javascript
$('.aSpinEdit').spinedit({
minimum: -10,
maximum: 50,
step: 1
});
Assuming you have to send that data back to the server, setting the input readonly attribute and adding some limits to the input value its fairly easy.
Here's the demo
http://jsbin.com/yebawihune/7/
With this you can dynamically add as many spinners as you want that are cross browser compatible (even IE). Of course you have to have included the needed js and css files for jquery.
First you have to create your input. Keep note of the id as you will use that later. I always just put the same value for the id and name parameters in the input.
<input id="elementName" name="elementName">
Then put this in your head section.
function createSpinner(elemName, elemVal, elemMin, elemMax, elemStep){
var mySpinner = $( '#' + elemName ).spinner({
min: elemMin,
max: elemMax,
step: elemStep,
change: function( event, ui ) {
var typedVal = $( '#' + elemName ).spinner( 'value' );
if (typedVal < elemMin || typedVal > elemMax) {
alert('Value must be between ' + elemMin + ' and ' + elemMax);
$('#' + elemName).spinner('value', elemVal);
}
}
});
$('#' + elemName).spinner('value', elemVal);
};
Then you just call the function, passing the needed parameters (the first parameter will be the value of the ID of your input).
createSpinner('elementName','0','0','10000','1');

jQuery Autocomplete on Dynamically new rows

Issue: The (jQuery) auto-complete works only for the first input (displayed by default). It doesn't work for additional row/s which are added using the add row function.
I have read other posts and understood that I have to use class and not id. But it still doesn't work.
I am using jquery autocomplete and some javascript to add and delete rows for a specific id.
Here is the headers:
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
Here is the jquery code:
jQuery(document).ready(function ($) {
/* availableTags = [
"Demo",
"Senna",
"Adam",
"Eva",
];*/
$('.autofill').autocomplete({
source:'suggest.php', minLength:2
});
});
Here is the HTML code:
<div class="content-left">
Add rows
<div id="p_scents">
<p>
<label style="margin-bottom:10px;" for="p_scnts">
<input class="autofill" type="text" id="p_scnt" size="20" name="p_scnt[]"
value="" placeholder="Enter text" />
</label>
</p>
</div>
</div>
**Here is the Javascript to add rows:**
$(function () {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;
$('#addScnt').on('click', function () {
$('<p><label style="margin-bottom:10px;" for="p_scnts"><input class="autofill" type="text" name="p_scnt[]" size="20" id="p_scnt_' + i + '" value="" placeholder="Add text" /></label for="remScnt"> <label style="padding-left:400px;">Remove</label></p>').appendTo(scntDiv);
//i++;
//return false;
//Added the 5 lines below
$(function ($) {
$('#p_scnt_' + i).autocomplete({
source:'suggest.php', minLength:2
});
});
i++;
return false;
});
$('#remScnt').on('click', function () {
if (i > 2) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
So the above code is working fine. Cheers all for your help ;)
For your latest code, you've made two mistakes:
Increase the counter i before apply autocomplete to text field
Stopped the script by return false
Also, it's recommended to use .on() to replace .live() as it's deprecated in version 1.7 .
Demo: http://jsfiddle.net/indream/f8mt4/
$('#addScnt').on('click', function () {
$(...).appendTo(scntDiv);
//i++; Should not be done here
//return false; Stopped the script
//Added the 5 lines below
$(function ($) {
$('#p_scnt_' + i).autocomplete({
source: window.availableTags,
minLength: 1
});
});
i++; // should increase counter here
return false;
});
p.s. I've changed availableTags to global variable in order to make the demo works,
but I think you would use query to retrieve the tags.
$('#addScnt').live('click', function() {
.........................
$('#p_scnt_'+i).autocomplete({
source:'suggest_fill.php',
minLength:1
});
return false;
..................
});
I think it's the sequence of js file load problem.
Try to put your second file above the 1st file.
Hope it helps you.
the second $(function(){is too much. it should look like this
<script>
$(function() {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;
$('#addScnt').live('click', function() {
$('<p><label style="margin-bottom:10px;" for="p_scnts"><input class="autofill" type="text" name="p_scnt[]" size="20" id="p_scnt_' + i +'" value="" placeholder="Add text" /></label for="remScnt"> <label style="padding-left:400px;"><img src="../../img/remove.jpg" width="" height="" class="img" alt="" title=""/></label></p>').appendTo(scntDiv);
i++;
//Added the 5 lines below
$('#p_scnt_'+i).autocomplete({
source:'suggest_fill.php',
minLength:1
});
return false;
});
$('#remScnt').live('click', function() {
if( i > 2 ) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
</script>

Dynamically created DOM manipulation button not firing event

I have a function to add and remove a field but the remove function doesnt work somehow.
HTML:
<div id="parts">
Part
<input type="text" id="auto_part" name="auto_part" />
<br />
Description
<input type="text" id="auto_description" name="auto_description" />
<br />
</div>
Add another part
jQuery:
$(function() {
var scntDiv = $('#parts');
var i = $('#parts input').size();
$('#addField').on('click', function() {
$('<br /><div id="parts"><span>Part</span> <input type="text" id="auto_part'+i+'" name="auto_part'+i+'" /><br />').appendTo(scntDiv);
$('<span>Description</span> <input type="text" id="auto_description'+i+'" name="auto_description'+i+'" /> <br />').appendTo(scntDiv);
$('<input type="hidden" id="row_count" name="row_count" value="" />').appendTo(scntDiv);
$('Remove</div>').appendTo(scntDiv);
i++;
return false;
});
$('#removefield').on('click', function() {
if( i > 2 ) {
$(this).parents('div').remove();
i--;
}
return false;
});
});
The problem must have to do with this line:
$('#removefield').on('click', function() {
It doesnt pass that condition.
When I click on Remove it doesnt do anything at all it just scrolls to the top.
You are binding the click handler to the elements that are present in the DOM. But, your #removefield element is being dynamically added. So, the event handler is not attached to it.
You can use .on() to use event delegation and handle also future elements. Also, you may want to use classnames instead of and id attributes. id attributes need to be unique, but you can set the classname to as many elements as you want.
Remove
$("#parts").on("click", ".removefield", function() {
/* ... */
});
The reason why your "Remove" link doesn't work is because you are adding the dynamic <div> element by parts hence making it invalid markup. You should be adding it all together at once. For example,
$('#addField').on('click', function () {
var part = '<div id="parts' + i + '"><span>Part</span> <input type="text" id="auto_part' + i + '" name="auto_part' + i + '" /><br/>' +
'<span>Description</span> <input type="text" id="auto_description' + i + '" name="auto_description' + i + '" /> <br />' +
'<input type="hidden" id="row_count' + i + '" name="row_count' + i + '" value="" />' +
'Remove</div>';
scntDiv.after(part);
i++;
return false;
});
$(document).on("click", ".removefield", function() {
if( i > 2 ) {
$(this).parent('div').remove();
i--;
}
return false;
});
You can see it here.
try
$('#removefield').live("click", function() {

IE performance slow with jquery and memory leak

Hi I have the following code.
<input id="input1" type="text">
<input id="input2" type="text">
<input id="input3" type="text">
// ... so on up to 12.
my code
var $j = jQuery.noConflict();
$j(document).ready(function ($) {
var i, id;
for (i = 1; i != 13; ++i) {
id = "input" + i;
$(myFunc).on("change", function() {
this.value += " tab";
});
}
);
I am getting memory leak on input1, input2 ... according to drip.
How can i solve this.
If you are only trying to run this 12 times, I would do (notice the less than vs not-equal operation):
for (i = 1; i < 13; ++i) {
Also, where is myFunc defined? Maybe you're trying to do:
$(id).on("change", function() {
this.value += " tab";
});
One other thing, and I don't know if this is still an issue, in some browsers, jQuery use to have a problem setting a value on an input where there was no value attribute define.
<input id="input1" type="text" value="" />
What are you trying to do? doing a loop to set id to input1-12, but your on.('change') eventlistener doesn't even use the 'id' variable?
Are you trying to listen for change on any of your inputs and add " tab" to it when it changes? If so
$('input').on('change', function() {
$(this).attr('value') += " tab";
});
will suffice.

Categories