I'm building this form were the user can add input field dynamically by clicking the + sign.
Then the user can remove the previously added input by clicking the - sign.
My problem is when the user removes one field, all fields are removed. I believe it depends on the position of the .field_wrapper.
I've moved the .field_wrapper to various positions but nothing seems to work. Either way the previously added input is not removed or all inputs are removed.
Can someone advise me on what I'm missing.
here is a link to a fiddle
$(document).ready(function() {
var max_fields = 10;
var add_input_button = $('.add_input_button');
var field_wrapper = $('.field_wrapper');
var new_field_html = '<input name="title[]" class="form-control form-item type="text" value="" data-label="title" />-';
var input_count = 1;
//add inputs
$(add_input_button).click(function() {
if (input_count < max_fields) {
input_count++;
$(field_wrapper).append(new_field_html);
}
});
//remove_input
$(field_wrapper).on('click', '.remove_input_button', function(e) {
e.preventDefault();
$(this).parent('div').remove();
input_count--;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form-horizontal">
<div class="row field_wrapper">
<label class="col-md-offset-1 col-sm-3 control-label" for="title">Title</label>
<div class="col-md-6 col-sm-9 col-10">
<input id="title" class="form-control form-item required" name="input_title[]" type="text" value="" data-label="title" />
+
</div>
</div>
</form>
The reason is because the parent('div') from the remove button is the div which holds all the content. The simple way to fix this would be to wrap the new input and remove link in its own div.
Also note that add_input_button and field_wrapper already contain jQuery objects, so you don't need to wrap them again. Try this:
$(document).ready(function() {
var max_fields = 10;
var $add_input_button = $('.add_input_button');
var $field_wrapper = $('.field_wrapper');
var new_field_html = '<div><input name="title[]" class="form-control form-item type="text" value="" data-label="title" />-</div>';
var input_count = 1;
//add inputs
$add_input_button.click(function() {
if (input_count < max_fields) {
input_count++;
$field_wrapper.append(new_field_html);
}
});
//remove_input
$field_wrapper.on('click', '.remove_input_button', function(e) {
e.preventDefault();
$(this).parent('div').remove();
input_count--;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form-horizontal">
<div class="row field_wrapper">
<label class="col-md-offset-1 col-sm-3 control-label" for="title">Title</label>
<div class="col-md-6 col-sm-9 col-10">
<input id="title" class="form-control form-item required" name="input_title[]" type="text" value="" data-label="title" />
+
</div>
</div>
</form>
Related
I have a section of code that contains a dropdown and 3 readonly input fields. The input fields are populated using javascript, this works fine on it's own using the below code -
$(document).on('change', '.unit', function(e) {
//Getting Value
var role = $('.unit option:selected').data('role');
var power = $('.unit option:selected').data('power');
var type = $('.unit option:selected').data('type');
//Setting Value
$(".role").val(role);
$(".power").val(power);
$(".type").val(type);
});
I am wanting to clone the element using this code -
//define template
var template = $('.duplicate-sections .form-section:first').clone();
//define counter
var sectionsCount = 1;
//add new section
$('body').on('click', '.addsection', function() {
//increment
sectionsCount++;
//loop through each input
var section = template.clone(true, true).find(':input').each(function(){
//set id to store the updated section number
var newId = this.id + sectionsCount;
//update for label
$(this).prev().attr('for', newId);
//update id
this.id = newId;
}).end()
//inject new section
.appendTo('.duplicate-sections');
return false;
});
//remove section
$('.duplicate-sections').on('click', '.remove', function() {
//fade out section
$(this).closest('.form-section').fadeOut(300, function(){
$(this).closest('.form-section').empty();
});
return false;
});
The cloning process works and the dropdown and the inputs are cloned. However when populating the cloned input fields it uses the values from the parent not the clone.
My html is -
<div class="duplicate-sections">
<div class="form-section">
<div class="form-group row">
<label for="inputFirstName" class="col-form-label col-sm-3 text-left text-sm-right">Unit Type</label>
<div class="col-sm-3">
<select name="unit" id="unit" class="form-control unit"><option value="">Select</option><option
data-role="HQ" data-power="4" data-type="Company Commander" value="1">Ehrwig Arellano</option>
<option data-role="HQ" data-power="6" data-type="Company Commander" value="2">Ehrwig
Arellano</option>
<option data-role="HQ" data-power="2" data-type="Tempestor Prime" value="3">Tempestor Prime</option>
</select></div>
<div class="col-sm-2 increment_controls">
<input type="text" id="role" name="role" class="form-control role" readonly placeholder="Role">
</div>
<div class="col-sm-1 increment_controls">
<input type="text" id="power" name="power" class="form-control power" readonly placeholder="PL">
</div>
<div class="col-sm-3 increment_controls">
<input type="text" id="type" name="type" class="form-control type" readonly placeholder="Type">
</div>
</div>
<label for="inputFirstName" class="col-form-label col-sm-3 text-left text-sm-right">
</label><input class="remove col-sm-9" type="button" value="Remove Unit"></input>
</div>
</div>
<label for="inputFirstName" class="col-form-label col-sm-3 text-left text-sm-right"></label>
<input class="addsection col-sm-9" type="button" value="Add Unit"></input>
The whole thing can be found here - JSFiddle
You need to update change event handler script for Unit as here you need to update input fields from the relevant form section only and not for all input fields.
see below code
$(document).on('change', '.unit', function(e) {
//Getting Value
var $option = $(this).find('option:selected');
var role = $option.data('role');
var power = $option.data('power');
var type = $option.data('type');
//Setting Value
var $parent = $(this).closest('.form-section');
$parent.find(".role").val(role);
$parent.find(".power").val(power);
$parent.find(".type").val(type);
});
Demo JSFiddle
The idea is to return an error message to each field, changing the original requied message of jquery. The way I'm doing it, returns: "The true field is required."
function addRequired() {
var container, inputs, index, input;
// Get the container element
container = $('#entityFields');
// Find its child `input` elements
inputs = container.find('input').not("#EntityWebsite, #EntitySocialMoney");
for (index = 0; index < inputs.length; ++index) {
input = inputs[index];
input.required = true;
$.validator.messages.required(input.labels[0].innerText);
}
}
$.validator.messages.required = function (label) {
var requiredMessage = "The " + label + " field is required."
return requiredMessage ;
}
My html is something like this:
<div class="modal-body">
<div id="seriesTab" class="tab-pane">
<div id="entityFields" class="form-row">
<label>Entity</label>
<input type="text" columnDivClass="col-md-6 form-group">
<label>Address:</label>
<input type="text" columnDivClass="col-md-6 form-group">
<label>Email:</label>
<input type="text" columnDivClass="col-md-6 form-group">
<label>Phone:</label>
<input type="text" columnDivClass="col-md-6 form-group">
<label>Website:</label>
<input type="text" columnDivClass="col-md-6 form-group">
<label>SocialMoney:</label>
<input type="text" columnDivClass="col-md-6 form-group">
</div>
</div>
</div>
input do not have label property. To fetch label which is before input then you can use input.previousElementSibling.innerText. So your updated code would be like below.
$.validator.messages.required(input.previousElementSibling.innerText);
Alternatively if you wish to use jquery then you can find text from previous label with $(input).prev('label').text()
$.validator.messages.required($(input).prev('label').text());
I am building script where I can add some dynamic fields and then delete it if I want. But I can't delete that first el class in my script, because it deletes all within input_fields_container class. How to do it correctly? Here's my code:
<div class="input_fields_container">
<div class="col-lg-12">
<div class="col-lg-2"></div>
<button class="btn btn-sm btn-primary add_more_button" style="float: left; margin-bottom: 10px;">
#lang('main.add more fields')
</button>
</div>
#foreach(Auth::user()->test as $data)
<div class="el">
<div class="form-group">
<label class="col-lg-2 control-label">#lang('main.test')</label>
<div class="col-lg-6">
<input type="text" name="test[]" class="form-control" value="{{ $data->test }}" >
</div>
</div>
</div>
#endforeach
</div>
<script type="text/javascript">
$(document).ready(function() {
var max_fields_limit = 10; //set limit for maximum input fields
var x = 1; //initialize counter for text box
$('.add_more_button').click(function(e){ //click event on add more fields button having class add_more_button
e.preventDefault();
if(x < max_fields_limit){ //check conditions
x++; //counter increment
$('.input_fields_container').append('<div class="el"><div class="form-group"><label class="col-lg-2 control-label">#lang('main.test')</label><div class="col-lg-6"><input type="text" name="test[]" class="form-control"></div></div><div class="form-group"><label class="col-lg-2 control-label"></div></div><div>#lang('main.delete')</div></div>');
}
});
$('.input_fields_container').on("click",".remove_field", function(e){ //user click on remove text links
e.preventDefault(); $(this).parents().eq(1).remove(); x--;
})
});
</script>
Your HTML in your append is structured wrong. Your div for the remove_field is not inside the '.el' div.
Try this...
$('.input_fields_container').append('<div class="el"><div class="form-group"><label class="col-lg-2 control-label">Main.test</label><div class="col-lg-6"><input type="text" name="test[]" class="form-control"></div></div><div class="form-group"><label class="col-lg-2 control-label"></div><div>main.delete</div></div></div>');
https://jsfiddle.net/chadsaun/Ljxw03Lp/
Try this
You need to change the class="el" to id="el"
$(document).on('click', '.remove_field', function () {
$('#el').closest('#el').remove();
});
You can give that 'a' tag an onclick function by id in the for loop. and one id for div with class name 'el' something like this code below:
$('.add_more_button').click(function(e){ //click event on add more fields button having class add_more_button
e.preventDefault();
if(x < max_fields_limit){ //check conditions
x++; //counter increment
$('.input_fields_container').append('<div class="el" id='el" + id +"'>
<div class="form-group">
<label class="col-lg-2 control-label">#lang('main.test')</label>
<div class="col-lg-6"><input type="text" name="test[]" class="form-control"></div>
</div>
<div class="form-group"><label class="col-lg-2 control-label"></div>
</div>
<div>
#lang('main.delete')
</div>
</div>');
}
});
And then you can add the deletInput function like this code below, in this function the method finds div with the id of el+id and remove it:
function deleteInput(id){
$('#el'+id+'').remove();
}
Remember your id for el element must be unique.
This is the concept of removing inputs by id.
Hope this would help!
I've the problem with div id in script. I just want to know how to control div id for using function id in another script. Here's my form:
<div class="container">
<div class="row">
<div class="col-md-7 field_wrapper">
<div data-role="dynamic-fields">
<div class="form-inline">
<div class="form-group" id="txtboxToFilter">
<label for="nip">NIP:</label>
<input type="text" class="form-control" id="UserName" onkeyup="checkname();" placeholder="Masukkan NIP" required/>
</div>
<div class="form-group">
<i class='fa fa-fw fa-plus'></i>
</div>
<span id="name_status"></span>
</div>
</div>
</div>
</div>
And here's my script:
$(document).ready(function(){
var addButton = $('.add_button'); //Add button selector
var wrapper = $('.field_wrapper'); //Input field wrapper
var fieldHTML = '<div data-role="dynamic-fields"><div class="form-inline"><div class="form-group" id="txtboxToFilter"><label for="nip">NIP:</label> <input type="text" class="form-control" id="UserName" onkeyup="checkname();" placeholder="Masukkan NIP" required/></div><div class="form-group"><label for="jabatan">Jabatan:</label><select class="form-control" id="jabatan" name="jeniskejadian" required><option value=""></option><option value="SMC / KAKANSAR">SMC / KAKANSAR</option><option value="STAFF OPERASI / KASIOPS">STAFF OPERASI / KASIOPS</option><option value="OSC / KORPOS">OSC / KORPOS</option><option value="DANTIM">DANTIM</option><option value="RESCUER">RESCUER</option><option value="STAFF KOMUNIKASI">STAFF KOMUNIKASI</option><option value="HUMAS">HUMAS</option><option value="STAFF ADMINLOG">STAFF ADMINLOG</option></select></div><div class="form-group"><i class="fa fa-fw fa-minus"></i></div><span id="name_status"></span></div></div>'; //New input field html
var x = 1; //Initial field counter is 1
$(addButton).click(function(){ //Once add button is clicked
x++; //Increment field counter
$(wrapper).append(fieldHTML); // Add field html
});
$(wrapper).on('click', '.remove_button', function(e){ //Once remove button is clicked
e.preventDefault();
$(this).parent('div').parent('div').remove(); //Remove field html
x--; //Decrement field counter
});
});
function checkname()
{
var name=document.getElementById( "UserName" ).value;
if(name)
{
$.ajax({
type: 'post',
url: 'checkdata.php',
data: {
user_name:name,
},
success: function (response) {
$( '#name_status' ).html(response);
if(response=="OK")
{
return true;
}
else
{
return false;
}
}
});
}
else
{
$( '#name_status' ).html("");
return false;
}
}
For the first time in
<div class="form-group" id="txtboxToFilter">
<label for="nip">NIP:</label>
<input type="text" class="form-control" id="UserName" onkeyup="checkname();" placeholder="Masukkan NIP" required/>
</div>
It can be used to using function checkname(), but if I would to click in
<div class="form-group">
<i class='fa fa-fw fa-plus'></i>
</div>
for adding the same input type text with function of my script $(addButton)
var fieldHTML = '<div data-role="dynamic-fields"><div class="form-inline"><div class="form-group" id="txtboxToFilter"><label for="nip">NIP:</label> <input type="text" class="form-control" id="UserName" onkeyup="checkname();" placeholder="Masukkan NIP" required/></div><div class="form-group"><i class="fa fa-fw fa-minus"></i></div><span id="name_status"></span></div></div>';
but the result is that var fieldHTML couldn't use function onkeyup checkname(). Please help me...
You should pass a reference of the element on which the inline event listener is attached to. You need to pass the this reference to the function and use the this reference to get the element.
Change you functions by adding this.
e.g.
<input type="text" class="form-control" id="UserName" onkeyup="checkname(this);" placeholder="Masukkan NIP" required/>
Also, for fieldHTML
var fieldHTML = '<div data-role="dynamic-fields"><div class="form-inline"><div class="form-group" id="txtboxToFilter"><label for="nip">NIP:</label>
<input type="text" class="form-control" id="UserName" onkeyup="checkname(this);" placeholder="Masukkan NIP" required/></div><div class="form-group"><label for="jabatan">Jabatan:</label><select class="form-control" id="jabatan" name="jeniskejadian" required><option value=""></option><option value="SMC / KAKANSAR">SMC / KAKANSAR</option><option value="STAFF OPERASI / KASIOPS">STAFF OPERASI / KASIOPS</option><option value="OSC / KORPOS">OSC / KORPOS</option><option value="DANTIM">DANTIM</option><option value="RESCUER">RESCUER</option><option value="STAFF KOMUNIKASI">STAFF KOMUNIKASI</option><option value="HUMAS">HUMAS</option><option value="STAFF ADMINLOG">STAFF ADMINLOG</option></select></div><div class="form-group"><i class="fa fa-fw fa-minus"></i></div><span id="name_status"></span></div></div>';
Function checkname(element) as :
variable element contains the element this is being used. You can access the element by using element variable.
function checkname(element)
{
var name= element.value;
console.log('Checkname '+name);
}
So I have a series of dynamically generated inputs using the following code:-
$(document).ready(function() {
var max_fields = 16; //maximum input boxes allowed
var wrapper = $(".GCSE_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div style="margin-top: 5px;"><div class="col-lg-5 col-md-5 col-sm-12 col-xs-12"><input type="text" name="Subject[]" class="form-control spec_one" id="GCSESubject[]" placeholder="Subject"></div><div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"><input type="text" class="form-control spec_one" id="SubjectLevel[]" name="SubjectLevel[]" placeholder="GCSE?"></div><div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"><select name="GCSEGrade[]" id="SubjectGrade[]" class="form-control spec_one"><option value="A*">A*</option><option value="A">A</option><option value="B">B</option><option value="c">C</option><option value="D">D</option><option value="E">E</option><option value="F">F</option><option value="g">G</option></select></div><div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"><input type="text" class="form-control spec_one gcse_year" id="GCSEYear[]" name="GCSEYear[]" placeholder="Year"></div>CX</div>'); //add input box
$
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
What I am trying to do is to create a function that will copy the value of GCSEYear[] (the input next to where the C button is clicked), and copy the value into all subsequent GCSEYear[] inputs that exist, but not all inputs of type GCSEYear[] (there maybe inputs before, not after, that I don't want changed).
The following code is an example but populates all fields of class gcse_year and not just the subsequent/next fields of that type.
$(document).ready(function(){
$('a[id^="copy_gcse_all"]').click(function(){
$('.gcse_year input').val($(this).closest('div').find('.gcse_year input').val())
});
I realise this is a relatively simple thing to do but I should be grateful if someone could point me in the right direction.
You can achieve what you require by placing a common class on the parent div you append on click of the Add button. You can then use closest() to select that div, and then nextAll() to get it's subsequent siblings before find() returns the GCSE year inputs you want to amend.
Here's a full working example with several other improvements to the logic:
var max_fields = 16;
var $wrapper = $(".GCSE_wrap");
var $add_button = $(".add_field_button");
$add_button.click(function(e) {
e.preventDefault();
if ($wrapper.find('> div').length < max_fields) {
$wrapper.append('<div style="margin-top: 5px;" class="wrapper-item"><div class="col-lg-5 col-md-5 col-sm-12 col-xs-12"><input type="text" name="Subject[]" class="form-control spec_one" placeholder="Subject"></div><div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"><input type="text" class="form-control spec_one" name="SubjectLevel[]" placeholder="GCSE?"></div><div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"><select name="GCSEGrade[]" class="form-control spec_one"><option value="A*">A*</option><option value="A">A</option><option value="B">B</option><option value="c">C</option><option value="D">D</option><option value="E">E</option><option value="F">F</option><option value="g">G</option></select></div><div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"><input type="text" class="form-control spec_one gcse_year" name="GCSEYear[]" placeholder="Year"></div>CX</div>');
}
});
$wrapper.on("click", ".remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('div').remove();
}).on('click', '.copy_gcse_all', function(e) {
e.preventDefault();
var $wrapperItem = $(this).closest('.wrapper-item');
var year = $wrapperItem.find('.gcse_year').val();
$wrapperItem.nextAll('.wrapper-item').find('.gcse_year').val(year);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="add_field_button">Add</button>
<div class="GCSE_wrap"></div>
Also note that I removed all the id attributes from the long HTML string you append(), as this results in multiple elements sharing the same id which is invalid HTML.