Add / remove inputs in a form - javascript

I coded this, but the remove button doesn't work. And I don't have any error in console..
var counter = 0;
var dataList = document.getElementById('materials');
var jsonOptions = [{
"product": "11111",
"description": "description 1"
}, {
"product": "22222",
"description": "description 2"
}, {
"product": "33333",
"description": "description 3"
}, {
"product": "44444",
"description": "description 4"
}, {
"product": "55555",
"description": "description 5"
}];
jsonOptions.forEach(function(item) {
var option = document.createElement('option');
option.value = item.description;
option.text = item.description;
option.setAttribute('data-product', item.product);
dataList.appendChild(option);
});
$('#bookForm')
// Add button click handler
.on('change', 'input[id^="ajax"]', function() {
var description = $(this).val();
var product = $('#dataList > option[value="' + description + '"]').data('product');
$('input[name=product-'+ $(this).attr("name").replace("description-", "") + ']').val(product);
});
$('#bookForm')
// Add button click handler
.on('click', '.addButton', function() {
counter++;
var $template = $('#bookTemplate'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.attr('data-book-index', counter)
.insertBefore($template);
// Update the name attributes
$clone
.find('[name="description"]').attr('name', 'description-' + counter).end()
.find('[name="product"]').attr('name', 'product-' + counter).end();
})
// Remove button click handler
.on('click', '.removeButton', function() {
var $row = $(this).parents('.form-group'),
index = $row.attr('data-book-index');
// Remove element containing the fields
$row.remove();
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div id="bookForm" class="form-group">
<label for="inputName" class="col-md-2 col-sm-2 control-label">Υλικό / Ποσότητα</label>
<div class="col-md-3 col-sm-3">
<input type="text" id="ajax2" list="materials" class="form-control" placeholder="Υλικό" name="description-0">
<datalist id="materials"></datalist>
</div>
<div class="col-md-3 col-sm-3">
<input type="number" class="form-control" name="product-0" placeholder="Ποσότητα" required="">
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default addButton"><i class="fa fa-plus"></i></button>
</div>
</div>
<div id="bookTemplate" class="form-group hide">
<div class="col-md-3 col-sm-3 col-md-offset-2 col-sm-offset-2">
<input type="text" id="ajax2" list="materials" class="form-control" placeholder="Υλικό" name="description">
<datalist id="materials"></datalist>
</div>
<div class="col-md-3 col-sm-3">
<input type="number" class="form-control" name="product" placeholder="Ποσότητα" required="">
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default removeButton"><i class="fa fa-minus"></i></button>
</div>
</div>
</div>
</div>

the probelm is that you what to select .removeButton class inside #bookForm, but in reality the .removeButton is out side of #bookForm
jsFiddle
$('#bookForm')
// Add button click handler
.on('click', '.addButton', function() {
counter++;
var $template = $('#bookTemplate'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.attr('data-book-index', counter)
.insertBefore($template);
// Update the name attributes
$clone
.find('[name="description"]').attr('name', 'description-' + counter).end()
.find('[name="product"]').attr('name', 'product-' + counter).end();
});
// Remove button click handler
$("#bookForm").parent().on('click', '.removeButton', function() {
var $row = $(this).parents('.form-group'),
index = $row.attr('data-book-index');
// Remove element containing the fields
$row.remove();
});

You need to define a listener for all removeButton;
function removeButtonListener(){
$('.removeButton').on('click', function() {
var $row = $(this).parents('.form-group'),
index = $row.attr('data-book-index');
// Remove element containing the fields
$row.remove();
});
}
And you need to call it when you add new row;
$('#bookForm').on('click', '.addButton', function() {
counter++;
var $template = $('#bookTemplate'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.attr('data-book-index', counter)
.insertBefore($template);
// Update the name attributes
$clone
.find('[name="description"]').attr('name', 'description-' + counter).end()
.find('[name="product"]').attr('name', 'product-' + counter).end();
removeButtonListener(); //call remove listener
});

var counter = 0;
var dataList = document.getElementById('materials');
var jsonOptions = [{
"product": "11111",
"description": "description 1"
}, {
"product": "22222",
"description": "description 2"
}, {
"product": "33333",
"description": "description 3"
}, {
"product": "44444",
"description": "description 4"
}, {
"product": "55555",
"description": "description 5"
}];
jsonOptions.forEach(function(item) {
var option = document.createElement('option');
option.value = item.description;
option.text = item.description;
option.setAttribute('data-product', item.product);
dataList.appendChild(option);
});
$('#bookForm')
// Add button click handler
.on('change', 'input[id^="ajax"]', function() {
var description = $(this).val();
var product = $('#dataList > option[value="' + description + '"]').data('product');
$('input[name=product-'+ $(this).attr("name").replace("description-", "") + ']').val(product);
});
$('#bookForm')
// Add button click handler
.on('click', '.addButton', function() {
counter++;
var $template = $('#bookTemplate'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.attr('data-book-index', counter)
.insertBefore($template);
// Update the name attributes
$clone
.find('[name="description"]').attr('name', 'description-' + counter).end()
.find('[name="product"]').attr('name', 'product-' + counter).end();
});
$(document).on('click', '.removeButton', function() {
var $row = $(this).parents('.form-group'),
index = $row.attr('data-book-index');
// Remove element containing the fields
$row.remove();
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div id="bookForm" class="form-group">
<label for="inputName" class="col-md-2 col-sm-2 control-label">Υλικό / Ποσότητα</label>
<div class="col-md-3 col-sm-3">
<input type="text" id="ajax2" list="materials" class="form-control" placeholder="Υλικό" name="description-0">
<datalist id="materials"></datalist>
</div>
<div class="col-md-3 col-sm-3">
<input type="number" class="form-control" name="product-0" placeholder="Ποσότητα" required="">
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default addButton"><i class="fa fa-plus"></i></button>
</div>
</div>
<div id="bookTemplate" class="form-group hide">
<div class="col-md-3 col-sm-3 col-md-offset-2 col-sm-offset-2">
<input type="text" id="ajax2" list="materials" class="form-control" placeholder="Υλικό" name="description">
<datalist id="materials"></datalist>
</div>
<div class="col-md-3 col-sm-3">
<input type="number" class="form-control" name="product" placeholder="Ποσότητα" required="">
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default removeButton"><i class="fa fa-minus"></i></button>
</div>
</div>
</div>
</div>

Related

Html form calculation with javascript

I am trying to make HTML form with javascript but I could not make one part.
If a visitor selects from the dropdown menu "Service 1", the price will be multiplied with 1,5. If he selects "Service 2", the price multiplied with 2 and then with "adet" input value. I want to make multiplier values in script part like this;
var service_prices = new Array();
service_prices["service1"]=1.5;
service_prices["service2"]=2;
I need this calculation Paket(Dropdown)*Adet(Input) Could you help me?
These are my HTML codes;
<script>
$(function(){
//Adet
var val = $('#adet').val();
output = $('#output');
output.html(val);
$('#adet').on('change', function () {
output.html(this.value);
});
$('#Paket').change(function () {
if (this.value == "80") {
$('#adet').prop({
'min': 20,
});
}
if (this.value == "81") {
$('#adet').prop({
'min': 100,
});
}
$('#adet').val();
output.html('');
});
});
</script>
<form method="post" action="process.php"></br>
<label class="control-label col-sm-3" for="inputSuccess3">Paket</label>
<div class="col-sm-9">
<select class="form-control" id="Paket" name="paket">
<option value="80">Service 1 x1.5</option>
<option value="81">Service 2 x2</option>
</select>
</div>
<br>
<label class="control-label col-sm-3" for="inputSuccess3">Adet</label>
<div class="col-sm-9">
<input class="form-control" type="number" id="adet" name="adet" min="20" max="250" value="10" required>
</div>
<label class="control-label col-sm-3" for="inputSuccess3">Link</label>
<div class="col-sm-9">
<input class="form-control" type="text" name="link" required>
</div>
<div class="col-sm-offset-4 col-sm-8">
Fee: <span id="output"></span> Credi
</div>
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-primary">Order</button>
</div>
</form>
You can store the values in an array like this:
var service_prices = [{
"name": "Service 1",
"value": 80,
"multiplier": 1.5
}, {
"name": "Service 2",
"value": 81,
"multiplier": 2
}
];
You can store the multiplier value in a data-attribute in every option of the Paket dropdown.
See this example:
(function() {
var service_prices = [{
"name": "Service 1",
"value": 80,
"multiplier": 1.5
}, {
"name": "Service 2",
"value": 81,
"multiplier": 2
}];
var Paket = document.getElementById("Paket");
var adet = document.getElementById("adet");
var output = document.getElementById("output");
adet.onchange = function() {
output.innerHTML = adet.value;
if (Paket.value.length > 0) {
var multiplier = Paket.options[Paket.selectedIndex].getAttribute("data-multiplier") * 1;
output.innerHTML = adet.value * (Paket.value * 1) * multiplier;
} else {
output.innerHTML = "";
}
};
Paket.onchange = function() {
if (this.value.length > 0) {
var multiplier = this.options[this.selectedIndex].getAttribute("data-multiplier") * 1;
if (this.value === "80") {
adet.setAttribute("min", "20");
}
if (this.value === "81") {
adet.setAttribute("min", "100");
}
adet.value = 10;
output.innerHTML = adet.value * (this.value * 1) * multiplier;
} else {
output.innerHTML = "";
}
};
function fillServices(data) {
var html = "", i, len = data.length, obj;
html += "<option value=\"\">[SELECT]</option>";
for (i = 0; i < len; i++) {
obj = data[i];
html += "<option data-multiplier=\"";
html += obj.multiplier;
html += "\" value=\"";
html += obj.value;
html += "\">";
html += obj.name;
html += "</option>";
}
return html;
}
Paket.innerHTML = fillServices(service_prices);
})();
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<form method="post" action="process.php">
<label class="control-label col-sm-3" for="inputSuccess3">Paket</label>
<div class="col-sm-9">
<select class="form-control" id="Paket" name="paket">
</select>
</div>
<br>
<label class="control-label col-sm-3" for="inputSuccess3">Adet</label>
<div class="col-sm-9">
<input class="form-control" type="number" id="adet" name="adet" min="20" max="250" value="10" required>
</div>
<label class="control-label col-sm-3" for="inputSuccess3">Link</label>
<div class="col-sm-9">
<input class="form-control" type="text" name="link" required>
</div>
<div class="col-sm-offset-4 col-sm-8">
Fee: <span id="output"></span> Credi
</div>
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-primary">Order</button>
</div>
</form>

Increment name attribute when adding new form inputs fails

In a form there is an add button which adds form inputs. At the new form inputs I tried to increment the attribute name e.g name="description-1", name="description-2" etc. However, all the new inputs have the same name="description-1". What I miss?
var dataList = $('.products');
var jsonOptions = [{
"product": "11111",
"description": "description 1"
}, {
"product": "22222",
"description": "description 2"
}, {
"product": "33333",
"description": "description 3"
}];
jsonOptions.forEach(function(item) {
var option = '<option value="' + item.product + '">' + item.description + '</option>';
dataList.append(option);
});
$(function() {
$('body').on('input', '.product,.products', function() {
var i = this.value;
var description = "";
var productsInBox = 0;
jsonOptions.forEach(function(a) {
if (a.product == i) {
description = a.description;
}
});
$(this).closest('.form-group').find('.description').val(description);
});
});
counter = 0;
$('#form1').on('click', '.addButtonDED', function() {
counter++;
var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
.find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
.find('[name="description-0"]').attr('name', 'description-' + counter).end()
.find('i').removeClass('fa-plus').addClass('fa-minus').end();
$template.insertAfter('.form-group:last');
})
// Remove button click handler
.on('click', '.removeButtonDED', function() {
counter--;
var $row = $(this).closest('.form-group');
$row.remove();
});
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" method="post" class="form-horizontal" role="form">
<fieldset>
<div class="form-group">
<div class="col-xs-2">
<input type="text" list="products" class="form-control product" name="product" />
<datalist id="products" class="products"></datalist>
</div>
<div class="col-xs-4">
<input id="" type="text" class="form-control description" name="description-0" />
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default addButtonDED"><i class="fa fa-plus"></i></button>
</div>
</div>
<div class="col-xs-10 ">
<button type="submit" name="formAction" value="next" class="btn btn-primary">sUBMIT</button>
</div>
</fieldset>
</form>
You are accesing always to '[name="description-0"]' so when you change their name to description-1, that selector won't select them anymore.
You should select them with this selector '[name^="description-"]'.
The ^= operator means to select every element that starts with the stated value, so it will select all your description-0, description-1 and description-whatever.
You can read more here: https://www.w3schools.com/jquery/sel_attribute_beginning_value.asp
You can fix it by simple change [name="description-0"] to [name="description-'+ (counter-1) +'"]
The problem is that you close the previous object, and then the decription-0 will not be 0 anymore after the first object.
var dataList = $('.products');
var jsonOptions = [{
"product": "11111",
"description": "description 1"
}, {
"product": "22222",
"description": "description 2"
}, {
"product": "33333",
"description": "description 3"
}];
jsonOptions.forEach(function(item) {
var option = '<option value="' + item.product + '">' + item.description + '</option>';
dataList.append(option);
});
$(function() {
$('body').on('input', '.product,.products', function() {
var i = this.value;
var description = "";
var productsInBox = 0;
jsonOptions.forEach(function(a) {
if (a.product == i) {
description = a.description;
}
});
$(this).closest('.form-group').find('.description').val(description);
});
});
counter = 0;
$('#form1').on('click', '.addButtonDED', function() {
counter++;
var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
.find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
.find('[name="description-'+ (counter-1) +'"]').attr('name', 'description-' + counter).end()
.find('i').removeClass('fa-plus').addClass('fa-minus').end();
$template.insertAfter('.form-group:last');
})
// Remove button click handler
.on('click', '.removeButtonDED', function() {
counter--;
var $row = $(this).closest('.form-group');
$row.remove();
});
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" method="post" class="form-horizontal" role="form">
<fieldset>
<div class="form-group">
<div class="col-xs-2">
<input type="text" list="products" class="form-control product" name="product" />
<datalist id="products" class="products"></datalist>
</div>
<div class="col-xs-4">
<input id="" type="text" class="form-control description" name="description-0" />
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default addButtonDED"><i class="fa fa-plus"></i></button>
</div>
</div>
<div class="col-xs-10 ">
<button type="submit" name="formAction" value="next" class="btn btn-primary">sUBMIT</button>
</div>
</fieldset>
</form>
Your actual issue is var $template = $('.form-group:last').clone(true, true) , specifically the :last bit which means that its going to grab the one on the bottom of the group therefore .find('[name="description-0"]') only matches the first time. After that, the element would have name="description-1" and that call wont find it.
Instead, always grab the first element:
var $template = $('.form-group').eq(0).clone(true, true)
Working jsFiddle
However,
Why are you incrementing your name attributes at all?
Are you sending this data to some server side processing like php? if so, why not use the array syntax like:
<input id="" type="text" class="form-control description" name="description[]" />
See HTML Element Array, name="something[]" or name="something"?
You can use .find('.description').attr('name', 'description-' + counter).end()
Fiddle link
$('#form1').on('click', '.addButtonDED', function() {
counter++;
var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
.find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
.find('.description').attr('name', 'description-' + counter).end()
.find('i').removeClass('fa-plus').addClass('fa-minus').end();
$template.insertAfter('.form-group:last');
alert(counter)
})

Adding lines in a form an autocomplete function breaks

In a form I have 2 inputs. In the 1st input I use a datalist which I load it through JSON and the 2nd input is autocomplete it when the 1st input is changed.
Till here all works!
Then I added an add button where I add the same lines. The problem is that because I use id to select the input, when I add the new line I have the same id.. So the autocomplete doesn't work..
How can I solve this? Here the jssFiddle.
counter = 0;
var dataList = document.getElementById('products');
var jsonOptions = [{
"product": "11111",
"description": "description 1"
}, {
"product": "22222",
"description": "description 2"
}, {
"product": "33333",
"description": "description 3"
}];
jsonOptions.forEach(function(item) {
var option = document.createElement('option');
option.value = item.product;
option.text = item.description;
dataList.appendChild(option);
$(function() {
$('#product').on('change keyup', function() {
var i = this.value;
var description = "";
var productsInBox = 0;
jsonOptions.forEach(function(a) {
if (a.product == i) {
description = a.description;
productsInBox = a.productsInBox;
}
});
$('#description').val(description);
});
});
});
$('#form1')
// Add button click handler
.on('click', '.addButtonDED', function() {
counter++;
var $template = $('#addLineInDed'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.attr('data-index', counter)
.insertBefore($template);
// Update the name attributes
$clone
.find('[name="product"]').attr('name', 'product-' + counter).end()
.find('[name="description"]').attr('name', 'description-' + counter).end()
})
// Remove button click handler
.on('click', '.removeButtonDED', function() {
var $row = $(this).parents('.form-group'),
index = $row.attr('data-index');
counter--;
// Remove element containing the fields
$row.remove();
});
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" method="post" class="form-horizontal" role="form">
<fieldset>
<div class="form-group">
<div class="col-xs-2">
<input type="text" id="product" list="products" class="form-control" name="product-0" />
<datalist id="products"></datalist>
</div>
<div class="col-xs-4">
<input id="description" type="text" class="form-control" name="description-0" />
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default addButtonDED"><i class="fa fa-plus"></i></button>
</div>
</div>
<div id="addLineInDed" class="form-group hide">
<div class="form-group">
<div class="col-xs-2">
<input type="text" id="product" list="products" class="form-control" name="product-0" />
<datalist id="products"></datalist>
</div>
<div class="col-xs-4">
<input id="description" type="text" class="form-control" name="description-0" />
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-default removeButtonDED"><i class="fa fa-minus"></i></button>
</div>
</div>
</div>
<div class="col-md-10 ">
<button type="submit" name="formAction" value="next" class="btn btn-primary">Submit</button>
</div>
</fieldset>
</form>
Use classes, rename your selecs to array values:
counter = 0;
var dataList = $('.products');
var jsonOptions = [{
"product": "11111",
"description": "description 1"
}, {
"product": "22222",
"description": "description 2"
}, {
"product": "33333",
"description": "description 3"
}];
jsonOptions.forEach(function(item) {
var option = '<option value="' + item.product + '">' + item.description + '</option>';
dataList.append(option);
});
$(function() {
$('body').on('input', '.product,.products', function() {
var i = this.value;
var description = "";
var productsInBox = 0;
jsonOptions.forEach(function(a) {
if (a.product == i) {
description = a.description;
productsInBox = a.productsInBox;
}
});
$(this).closest('.form-group').find('.description').val(description);
});
});
$('#form1').on('click', '.addButtonDED', function() {
var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
.find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
.find('i').removeClass('fa-plus').addClass('fa-minus').end();
$template.insertAfter('.form-group:last');
})
// Remove button click handler
.on('click', '.removeButtonDED', function() {
var $row = $(this).closest('.form-group');
$row.remove();
});
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" method="post" class="form-horizontal" role="form">
<fieldset>
<div class="form-group">
<div class="col-md-2">
<input type="text" list="products" class="form-control product" name="product[]" />
<datalist id="products" class="products"></datalist>
</div>
<div class="col-md-4">
<input id="" type="text" class="form-control description" name=" description[]" />
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default addButtonDED"><i class="fa fa-plus"></i></button>
</div>
</div>
<div class="col-md-10 ">
<button type="submit" name="formAction" value="next" class="btn btn-primary">sUBMIT</button>
</div>
</fieldset>
</form>
</fieldset>
</form>
to read the values do a loop:
foreach($_POST['product'] as $product) {
//do stuf
}
Seeing as you said you've tried to use classes,
How about encapsulating your code so that you'll have a function like so:
function FilldatalistOptions(element,options)
You can then have the 2 datalists with different id's (products1 and products2 perhaps).
And just call the function like so:
var dataList1 = document.getElementById('products1');
var dataList2 = document.getElementById('products2');
FilldatalistOptions(datalist1, jsonOptions);
FilldatalistOptions(datalist2, jsonOptions);

JavaScript - Dynamic field with color adding too much fields

I created dynamic adding fields to form but I have problem with color input:
Standard inputs are added normally but input with color on first click is not adding and on next click 'Add field' is adding next fields with color to all inputs/.
Here is my code:
HTML:
<div class="form-group" id="propositionsFields">
<label class="col-md-4 control-label">Options</label>
<div class="row">
<div class="col-8">
<input class="form-control propositionField" name="proposition[]" type="text" />
</div>
<div class="col-2">
<input type="text" class="form-control jscolor {onFineChange:'updateColor(this)'}" />
<input type="hidden" class="color-picker" value="" />
</div>
<div class="col-2">
<button class="add-proposition-field propositionManage">Add field</button>
</div>
</div>
</div>
JS:
$(document).ready(function() {
var addField = $(".add-proposition-field");
var removeField = $('.remove-proposition-field');
addField.click(function(e) {
var rodzic = $('.colorInput');
e.preventDefault();
var i = $('.propositionField').size();
var color = 'FF0000';
var input = document.createElement("input");
input.className = "form-control";
input.setAttribute("value", color);
input.setAttribute("type", 'text');
var picker = new jscolor(input);
var newField = '<div class="row"><div class="col-8"><input autocomplete="off" class="form-control" name="proposition[]" type="text" placeholder="Field No."/></div><div class="col-2 colorInput"></div><div class="col-2"><button class="remove-proposition-field propositionManage">Usuń pole</button></div></div>';
i++;
rodzic.append(input);
$(" #propositionsFields ").append(newField);
});
$('body').on('click', '.remove-proposition-field', function() {
$(this).parent('div').parent('div').remove();
});
});
Demo: https://jsfiddle.net/k95detc8/
The issue if because you add the element before is exist. And the colorInput content is added to all colorInput class. I have remove your first element and add last parameter for add only in the last element
$(document).ready(function() {
var addField = $(".add-proposition-field");
var removeField = $('.remove-proposition-field');
addField.click(function(e) {
e.preventDefault();
var i = $('.propositionField').size();
var color = getRandomColor();
var input = document.createElement("input");
input.className = "form-control";
input.setAttribute("value", color);
input.setAttribute("type", 'text');
var picker = new jscolor(input);
var newField = '<div class="row"><div class="col-8"><input autocomplete="off" class="form-control" name="proposition[]" type="text" placeholder="Field No."/></div><div class="col-2 colorInput"></div><div class="col-2"><button class="remove-proposition-field propositionManage">Usuń pole</button></div></div>';
i++;
$(" #propositionsFields ").append(newField);
$('.colorInput:last').append(input);
});
$('body').on('click', '.remove-proposition-field', function() {
$(this).parent('div').parent('div').remove();
});
});
function updateColor(jscolor) {
$('.color-picker').val(jscolor);
$(this).val(jscolor);
}
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
div{
width:100% !important
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link href="http://beta.leonardo.pl/afrisoexpert/public/css/fluidable.css" rel="stylesheet"/>
<div class="form-group" id="propositionsFields" >
<label class="col-md-4 control-label">Options</label>
<div class="row">
<div class="col-8">
<input class="form-control propositionField" name="proposition[]" type="text" />
</div>
<div class="col-2">
<input type="text" class="form-control jscolor {onFineChange:'updateColor(this)'}" />
<input type="hidden" class="color-picker" value="" />
</div>
<!-- /.col-2 -->
<div class="col-2">
<button class="add-proposition-field propositionManage">Add field</button>
</div>
<!-- /.col-2 -->
</div>
<!-- /.row -->
</div>
<!-- /.form-group -->

Repopulate form input after delete another field

Good day, i have this section of javascript that's causing me trouble
https://jsfiddle.net/o5x8qgvt/2/
When i add a new field the position gets incremented when i delete a field the position is repopulated but on product name it doesn't repopulate the fields it gives me blank even if i added data in each of them. Can you please help me out?
Javascript:
// setup an "add a tag" link
var $addTagLink = $('<button href="#" class="btn btn-info add_tag_link">Adauga Produs</button>');
$('.form-buttons > .btn-group').prepend($addTagLink);
var $newLinkLi = $('.append-me');
jQuery(document).ready(function() {
// Get the ul that holds the collection of product-group
var $collectionHolder = $('#products-group');
// add the "add a tag" anchor and li to the product-group ul
$collectionHolder.append($newLinkLi);
// count the current form inputs we have (e.g. 2), use that as the new
// index when inserting a new item (e.g. 2)
$collectionHolder.data('index', $collectionHolder.find(':input').length);
$addTagLink.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new tag form (see code block below)
addTagForm($collectionHolder, $newLinkLi);
typeInitialize();
});
});
function regenerateTagList() {
var vals = $('.product-group > .product-counter > input').toArray().map(function(v, i) {return v.value;});
var products = $('.product-group > .product-name > span > input:last').toArray().map(function(v, i) {return v.value;});
console.log(products);
$('.product-group').remove();
$('#products-group').data('index', 1);
for (var i = 0; i < vals.length; i++) {
if (vals[i] !== i + 1) {
vals[i] = i + 1;
}
addTagForm($('#products-group'), $newLinkLi);
typeInitialize();
$('.product-group > .product-counter > input:last').val(vals[i]);
$('.product-group > .product-name > span > input:last').val(products[i]);
}
}
function addTagForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
if (index === 0) {
index = 1;
}
// Replace '$$name$$' in the prototype's HTML to
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
// Display the form in the page in an li, before the "Add a tag" link li
var $newFormLi = $('<tr class="product-group"></tr>').append(newForm);
// also add a remove button, just for this example
//$('<button type="button" class="product-highlight btn btn-primary">Highlight</button>
// <button type="button" class="remove-tag btn btn-primary">Sterge</button>').appendTo($newFormLi);
$newLinkLi.append($newFormLi);
// handle the removal, just for this example
$('.remove-tag').click(function(e) {
e.preventDefault();
$(this).closest('tr').remove();
regenerateTagList();
return false;
});
$('.product-highlight').on('click', function(e) {
e.preventDefault();
$(this).closest('tr').toggleClass('toggle-highlight');;
});
}
// Initialize Typeahead
function typeInitialize() {
// Create typeahead instance
var url = Routing.generate('offer_ajax_search', {
name: 'WILDCARD'
});
// Trigger typeahead + bloodhound
var products = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: function(obj) {
console.log('fired');
return obj.u_name;
},
prefetch: '/export/json/products.json',
remote: {
url: url,
wildcard: 'WILDCARD',
}
});
products.initialize();
$('.product-group').find('.typeahead:last').typeahead({
minLength: 3,
highlight: true,
limit: 10,
}, {
name: 'product',
display: 'u_name',
source: products.ttAdapter()
}).on('typeahead:select', function(e, datum) {
e.preventDefault();
/* Act on the event */
var information = '<div class="col-md-2"><label for="boxCode" class="label-control">BEX Code</label><input class="form-control" type="text" disabled="true" value="' + datum.u_bexCode + '"/></div>';
information += '<div class="col-md-2"><label for="base-price">Pret de baza</label><input class="form-control " type="text" disabled="true" value="' + datum.u_image + '"/></div>';
var div = $(this).parent().closest('.form-group').find('.product-information');
$(div).empty().append(information);
}).on('typeahead:autocomplete', function(e, datum) {
e.preventDefault();
/* Act on the event */
var information = '<div class="col-md-2"><label for="boxCode" class="label-control">BEX Code</label><input class="form-control" type="text" disabled="true" value="' + datum.u_bexCode + '"/></div>';
information += '<div class="col-md-2"><label for="base-price">Pret de baza</label><input class="form-control " type="text" disabled="true" value="' + datum.u_image + '"/></div>';
var div = $(this).parent().closest('.form-group').find('.product-information');
$(div).empty().append(information);
});
$("input[type='text']").on("click", function() {
$(this).select();
});
}
HTML:
<div class="row">
<div class="col-md-12">
<form name="offer" method="post" action="/app_dev.php/offer-generator/new/submited" class="form-horizontal">
<div class="form-group"><label class="col-sm-2 control-label required" for="offer_name">Name</label><div class="col-sm-10"><input type="text" id="offer_name" name="offer[name]" required="required" maxlength="255" class="form-control"></div>
</div>
<div id="products-group" data-prototype="<td class="product-counter col-md-1"><input type="text" id="offer_products___name___position" name="offer[products][__name__][position]" disabled="disabled" required="required" class="counter form-control" value="__name__" /></td>
<td class="product-name"><input type="text" id="offer_products___name___name" name="offer[products][__name__][name]" required="required" class="typeahead product form-control" name="product" id="products" data-provider="product" placeholder="Nume Produs" autocomplete="false" /></td>
<td class="col-md-1"><input type="text" id="offer_products___name___price" name="offer[products][__name__][price]" required="required" class="form-control" /></td>
<td class="col-md-1"><input type="text" id="offer_products___name___quantity" name="offer[products][__name__][quantity]" required="required" class="form-control" /></td>
<td class="product-action">
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="product-highlight btn btn-warning">Highlight</button>
<button type="button" class="remove-tag btn btn-danger">delete</button>
</div>
</td>
"><table class="table table-striped table-hover table-bordered append-me">
<thead>
<tr>
<th class="col-md-1">Position</th>
<th>Product</th>
<th class="col-md-1">Price</th>
<th class="col-md-1">Quantity</th>
<th class="col-md-2">Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table></div>
</form></div>
<div class="form-buttons">
<div class="btn-group" role="group" aria-label="..."><button href="#" class="btn btn-info add_tag_link">Add Product</button>
<button type="submit" id="offer_save" name="offer[save]" class="btn-default btn">Create Offer</button>
<button type="submit" id="offer_send_email" name="offer[send_email]" class="btn-default btn">Send Email</button>
<button type="submit" id="offer_export_excel" name="offer[export_excel]" class="btn-default btn">Export Excel</button>
<button type="submit" id="offer_export_pdf" name="offer[export_pdf]" class="btn-default btn">Export PDF</button>
</div>
</div>
<div class="form-group"><div class="col-sm-2"></div><div class="col-sm-10"><div id="offer_products" data-prototype="<div class="form-group"><label class="col-sm-2 control-label required">__name__label__</label><div class="col-sm-10"><div id="offer_products___name__"><div class="form-group"><label class="col-sm-2 control-label required" for="offer_products___name___pricePerLine">Line Total</label><div class="col-sm-10"><input type="text" id="offer_products___name___pricePerLine" name="offer[products][__name__][pricePerLine]" required="required" class="form-control" /></div>
</div></div></div>
</div>"></div></div>
</div><input type="hidden" id="offer__token" name="offer[_token]" class="form-control" value="cSVdt50kupA_BwFeY4T43PslnfjiA-UgjT4EA_HBdqs">
</div>

Categories