select2 doesn't work when add from dynamically with jquery - javascript

i have a form that the elements is dynamic. we can add a row according to the needs. Here is a image link
dynamic form
as we can see, we can add a row just press "tambah kolom" button and then the row will be attached to the form. i use jquery to adding dynamic. here is my forms code
HTML
<tr>
<td>
<input type="number" class="form-control" value="{{ old('itemujiriksa[0][jumlah_barang]') }}" name="itemujiriksa[0][jumlah_barang]">
</td>
<td>
<input type="text" class="form-control" value="{{ old('itemujiriksa[0][nama_barang]') }}" name="itemujiriksa[0][nama_barang]">
</td>
<td class="form_tabung">
<select name="itemujiriksa[0][tube_id]" class="form-control tube" style="width: 100%">
</select>
</td>
<td class="form_alat" style="display:none">
<select name="itemujiriksa[0][alat_id]" class="form-control alat" style="width: 100%">
</select>
</td>
<td>
<input type="text" class="form-control" value="{{ old('itemujiriksa[0][keluhan]') }}" name="itemujiriksa[0][keluhan]">
</td>
<td>
<input type="file" class="form-control" value="{{ old('itemujiriksa[0][fototabung][]') }}" name="itemujiriksa[0][fototabung][]" multiple />
</td>
</tr>
and here is my jquery code
jquery
<script>
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $("#input_fields_wrap"); //Fields wrapper
var add_button = $("#add_field_button"); //Add button ID
var x = {{$a}}; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
$(wrapper).append('<tr>\
<td>\
<input type="number" class="form-control" value="{{ old('jumlah_barang[]') }}" name="itemujiriksa[' + x +'][jumlah_barang]">\
</td>\
<td>\
<input type="text" class="form-control" value="{{ old('nama_barang[]') }}" name="itemujiriksa[' + x +'][nama_barang]">\
</td>\
<td class="form_tabung">\
<select name="itemujiriksa[0][tube_id]" class="form-control tube" style="width: 100%">\
</select>\
</td>\
<td class="form_alat" style="display:none">\
<select name="itemujiriksa[0][alat_id]" class="js-selectize form-control" placeholder="Pilih No Alat">\
<option disabled selected value></option>\
#foreach($alats as $at)\
<option value="{{ $at->id }}">{{ $at->no_alat }}</option>\
#endforeach\
</select>\
</td>\
<td>\
<input type="text" class="form-control" value="{{ old('keluhan[]') }}" name="itemujiriksa[' + x +'][keluhan]">\
</td>\
<td>\
<input type="file" class="form-control" value="{{ old("itemujiriksa['+ x +'][fototabung][]") }}" name="itemujiriksa[' + x +'][fototabung][]" multiple>\
</td>\
<td><a class="btn btn-danger remove_field">Hapus Kolom</a></td>\
</tr>'); //add input box
x++; //text box increment
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parents("tr").remove(); x--;
}) });
and here's my select2 code
SELECT2
$(document).ready(function() { var $select2Elm = $('.alat');
$select2Elm.select2({
width: 'resolve',
placeholder: "Pilih No Alat",
ajax: {
url: function(){
var value = $('#customer').val();
var url = "/admin/getDataAlat/ujiriksa/"+value;
console.log(url);
return url;
},
dataType: 'json',
type: "GET",
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, page) {
// parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to
// alter the remote JSON data
return {
results: $.map(data, function (item) {
return {
text: item.name,
id: item.id
}
})
};
},
cache: true
},
}); });
my question is
i have defined class alat to initiate the no tabung select box for populate data from select2. but after adding a new row which is the class is same. the new select box doesnt populate data. what should i do master?

you'll need to initialize each new select element after you append the html.
$(add_button).click(function(e){
//append new table rows here
$(wrapper).append('...');
//reinitialize the new select box
$('.alat').select2({
//configuration
});
});

You can initialize after append your code.
You can see below example
$(document).on("click",".add-new-item",function(e){
var html = 'your html';
$( '.element' ).append(html);
initSelect2();});
function initSelect2() {
$('.select2_single').select2();}

Related

Select2: does not work once loaded through onclick event in vue js

We implemented the select2 on our select options in our project. In our project, we have item section(Inventory, Quantity and Unit) and in the bottom part there's a button "Add Item".
When I clicked the "Add Item", it will add new row in my item section. But the added row,my inventory doesn't have select2
EXAMPLE:
//
// As you can see here, this is the default when the user clicked the "Add" button
// When the user clicked the "Add Item"
As you can see, the select2 of my 2nd row in item didn't work but when I try again to add a new item. It will work.
Question: Why I have to add another row before my previous row in item to have a select2?
ADD vue
<button class="btn btn-primary" #click="addItem"><i class="fa fa-plus" aria-hidden="true"></i> Add Item</button>
Event
function getAssetLimit(){
var table = 'assets'
$('select.asset').select2({
placeholder: 'Select Asset',
allowClear: true,
ajax: {
url: '/select2/getAssetFilterLimit',
dataType: 'json',
data: function(params) {
return {
term: params.term || '',
page: params.page || 1,
table: params.table || table
}
},
cache: true
}
});
}
// export default
methods: {
addItem(e) {
e.preventDefault();
getAssetLimit();
// if (this.asset === 'undefined' || this.asset === '') {
this.inputs.push({
asset_id: '',
unit: '',
description: '',
});
},
Clicked the Add Item
<tbody>
<tr v-for="(input, i) in inputs" :key="i">
<td class="sticky">
<select class="form-control-input form-control asset" name="item_asset[]" :data-counter="i+1">
<option></option>
</select>
</td>
<td>
<input type="number" name="item_quantity[]" class="form-control form-control-input item-quantity" step="0.0001" required>
</td>
<td>
<input type="text" name="item_unit[]" class="form-control form-control-input item-unit" readonly="readonly" :data-counter="i+1">
</td>
<!-- <td v-if="asset[2]">
<textarea name="item_specification[]" class="form-control" readonly="readonly" :data-counter="i">{{ asset[2] | striphtml }}</textarea>
</td> -->
<!-- <td v-else> -->
<td>
<textarea name="item_description[]" class="form-control" readonly="readonly" :data-counter="i+1"></textarea>
</td>
</tr>
</tbody>

Fill Textfield Based on Select Option

I'm trying to get "hargaJual" value when I select some option. But when I insert a new row in the table and select a new option, it will change only the first row of "Harga" and leave the second-row blank.
Here's the result :
<td>
<select class="custom-select" id="kodeSparepart" name="kodeSparepart[]">
<option value=""> --Pilih Sparepart-- </option>";
#foreach($sparepart as $s) {
<option value="{{ $s['kodeSparepart'] }}" data-price="{{ $s->hargaJual }}"> {{ $s['namaSparepart'] }} </option>";
}
#endforeach
</select>
</td>
<td>
<input class="form-control" type="text" id="hargaJualTransaksi" name="hargaJualTransaksi[]" autocomplete="off" readonly>
</td>
And here is my javascript
//for insert new row in table
$(function(){
$('#addMore').on('click', function() {
var data = $("#tb tr:eq(1)").clone(true).appendTo("#tb");
data.find("input").val('');
});
$(document).on('click', '#remove', function() {
var trIndex = $(this).closest("tr").index();
if(trIndex>=1) {
$(this).closest("tr").remove();
} else {
alert("Sorry!! Can't remove first row!");
}
});
});
//fill hargaJualTransaksi field
$(function() {
$('#kodeSparepart').on('change', function(){
var price = $(this).children('option:selected').data('price');
$('#hargaJualTransaksi').val(price);
});
});
You need to use event delegation on since the rows are dynamically rendered to the DOM :
$(function() {
$('body').on('change', '.kodeSparepart', function(){
var price = $(this).children('option:selected').data('price');
$('.hargaJualTransaksi').val(price);
});
});
NOTE: The id attribute must be unique so you needs to change every kodeSparepart and hargaJualTransaksi to classes instead of id's, it will be something like :
<input class="form-control hargaJualTransaksi" type="text" name="hargaJualTransaksi[]" autocomplete="off" readonly>
Try below code:
$("body").on('click', '#kodeSparepart', function (event) {
var price = $(this).children('option:selected').data('price');
$('#hargaJualTransaksi').val(price);
}

Dynamic Form Input with Select

Trying my hand on dynamic form fields with itemz[].
I would like the form fields duplicate and have the select populate from the json object.
<!-- DYNAMIX ITEMS-->
<div class='container1'>
<tr>
<td>
<select id='itemz' name='itemz[]' class='itemz'> </select>
</td>
<td>
<input class='form-control' type='text' name='count[]' value=''>
<input class='form-control' type='hidden' name='weight[]' value='<?= $items['weight']; ?> '>
</td>
<!-- ADD MORE -->
<td>
<button class='add_form_field'>Add More</button>
</td>
</tr>
</div>
Here is the JS that is suppose to:
1) populate the drop down
but it only populates the first box, I tried using a for each on the class but no luck.
2) Duplicates the dropdown, but instead of appending after it adds it before the first main div
<script>
// POPULATING THE DROP DOWN
var obj={
Prod:
<?php echo $products; ?>
};
for(var i=0;i<obj.Prod.length;i++)
{
var option=$('<option></option>').text(obj.Prod[i]['item']);
$( ".itemz" ).append(option);
}
// DUPLICATING THE DROP DOWNS
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".container1"); //Fields wrapper
var add_button = $(".add_form_field"); //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("<tr><td><select id='itemz' name='itemz[]' class='itemz'></select></td> <td><input class='form-control' type='text' name='count[]' value=''><input class='form-control' type='hidden' name='weight[]' value=''> </td> <td><a href='#' class='remove_field'>Remove</a> </td></tr></div>"); //add input box
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
</script>
Here is my JSON object:
Prod:
[{"id":"1","item":"Piano","weight":"200"},{"id":"2","item":"Fridge","weight":"50"},{"id":"3","item":"Freezer","weight":"100"},{"id":"4","item":"Sofa","weight":"20"},{"id":"5","item":"Microwave","weight":"10"},{"id":"6","item":"Dining Table","weight":"40"},{"id":"7","item":"Coffee Table","weight":"20"}]
};
var obj={
Prod:[
{
"id":"1",
"item":"Piano",
"weight":"200"
},{
"id":"2",
"item":"Fridge",
"weight":"50"
},{
"id":"3",
"item":"Freezer",
"weight":"100"
},{
"id":"4",
"item":"Sofa",
"weight":"20"
},{
"id":"5",
"item":"Microwave",
"weight":"10"
},{
"id":"6",
"item":"Dining Table",
"weight":"40"
},{
"id":"7",
"item":"Coffee Table",
"weight":"20"
}
]
};
var max_fields= 10;
var curent_fields=0;
function add_options(_el){
for(var key in obj.Prod){
var text=obj.Prod[key].item;
var id=obj.Prod[key].id;
var weight=obj.Prod[key].weight;
var el =$('<option/>').text(text).val(id).attr('weight',weight);
$(_el).append(el);
}
}
function add_controls(){
if(curent_fields>=max_fields){
alert('max feilds '+max_fields);
return false;
}
$('.container1').append('<tr><td><select name="itemz[]" class="itemz"></select></td><td><input class="form-control" type="text" name="count[]" value=""><input class="form-control" type="hidden" name="weight[]" value="">Remove</td><td>');
add_options($('.itemz').last());
$('.itemz').last().change(function(){
select_change(this);
});
$('.itemz').last().parent().next().find('.remove_field').click(function(){
$(this).parent().parent().remove();
curent_fields--;
});
curent_fields++;
}
function select_change(_el){
var curent_weight=$(_el).children(':selected').attr('weight');
var curent_id=$(_el).children(':selected').val();
var curent_item=$(_el).children(':selected').text();
//set hidden feid value
$(_el).parent().next().find('[name^="weight"]').val(curent_weight);
//your more code...
console.log([curent_id,curent_weight,curent_item]);
}
function start(){
add_options($('.itemz').last());
$('.itemz').last().change(function(){
select_change(this);
});
}
start();
$('.add_form_field').click(function(){
add_controls();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='container1'>
<tr>
<td>
<select id='itemz' name='itemz[]' class='itemz'> </select>
</td>
<td>
<input class='form-control' type='text' name='count[]' value=''>
<input class='form-control' type='hidden' name='weight[]' value=''>
</td>
<!-- ADD MORE -->
<td>
<button class='add_form_field'>Add More</button>
</td>
</tr>
</div>

Change value of input pair javascript

For an application I am working on, I want to autocomplete a field using the input of the other field. My form will contain several pairs of inputs, which causes the problem for me to only change one specific input field.
$(function () {
$(".master").change(function () {
word = $(this).val();
$(this).parents('tr').find(".slave").val(word);
});
});
To add extra fields to the form, the script below is used.
$(document).ready(function() {
var max_fields = 1000; //maximum input boxes allowed
var wrapper = $(".input_fields_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('<tr><td><div class="form-group"><input type="text" class="master" name="or['+x+']"></div></td><td> </td><td><div class="form-group"><input type="text" class="slave" name="tr['+x+']"></div></td></tr>'); //add input box
}
});
});
This is the form I'm using. This is one of the 100 rows in this form.
<form method="POST">
<table width="100%" class="input_fields_wrap">
<tr>
<td width="48%">
<div class="form-group">
<select id="original" name="original" class="form-control">
<option value="nederlands">Nederlands</option>
</select>
</div>
</td>
<td width="4%"></td>
<td width="48%">
<div class="form-group">
<select id="translated" name="translated" class="form-control">
<option value="frans">Frans</option>
</select>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-group"><input type="text" class="master" name="or[0]"></div>
</td>
<td> </td>
<td>
<div class="form-group"><input type="text" class="slave" name="tr[0]"></div>
</td>
</tr>
</table>
<button type="submit" id="save" class="btn btn-success pull-right">Opslaan</button>
</form>
So just to be clear, I want to change the value of the "translation" input according to the value of the input in the same row. As my form contains so many rows, I don't know how to change that specific input according to the input in the same table row. Thanks in advance!
Here you go, I had to take out the ajax call but if you need help adding it back in just let me know.
I changed your html a bit by using classes instead of id's and this is the relevant js.
$(function () {
$("table").on('change', '.master', function () {
word = $(this).val();
$(this).parents('tr').find(".slave").val(word);
});
});
https://jsfiddle.net/6LaLm33t/4/
What you can do is get the parent, and then find the #translation of that parent. original and translation should probably be classes.
var word = '';
$(function () {
$(".original").change(function () {
word = $(this).val();
var arr;
$.ajax({ type: "POST", async: false, url: 'wordsuggestion' + word, success: function(data) {
arr = data;
$(this).parents('tr').find(".translation").val(arr);
}});
});
});
If you don't want (or can't, for some reason) to change HTML (you will have to do it, anyway, if there are multiple id's!), this is one of the ways to get desired result:
$('table tr td:first-child input').on("keyup", function() {
$(this).closest('tr').find('td:last-child input').val($(this).val());
});
So, if you have 3 cells (td's) in row, first selector will 'grab' first input, second one will find last/second input in the same row.
$('table tr td:first-child input').on("keyup", function() { //or desired event...change...input..
$(this).closest('tr').find('td:last-child input').val($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td>
<div class="form-group"><div class="ui-widget"><input type="text" id="original" class="form-control" name="or[0]"></div></div>
</td>
<td> </td>
<td>
<div class="form-group"><input type="text" id="translation" class="form-control tags" name="tr[0]"></div>
</td>
</tr>
<tr><td>
<div class="form-group"><div class="ui-widget"><input type="text" id="original" class="form-control" name="or[0]"></div></div>
</td>
<td> </td>
<td>
<div class="form-group"><input type="text" id="translation1" class="form-control tags" name="tr[0]"></div>
</td>
</tr>
<tr><td>
<div class="form-group"><div class="ui-widget"><input type="text" id="original1" class="form-control" name="or[0]"></div></div>
</td>
<td> </td>
<td>
<div class="form-group"><input type="text" id="translation2" class="form-control tags" name="tr[0]"></div>
</td>
</tr>
</table>

Deleting input fields dynamically that dont have a unique attribute

I have a dynamic form that allows fields to be added and deleted dynamically with the help of jquery. The existing fields are autopopulated from values in mysql table. The add button adds a new input field while the delete button removes an input field. The fields loaded with values from the db are tagged with data-saved attributed. Now my dilemma is focused in the delete button. How can I delete new sections that are not tagged with data-saved attribute? EXAMPLE
JQUERY
$(document).ready(function () {
$('#btnAdd').click(function () {
var $clones = $('#input_table tr'),
num = $clones.size() + 1,
next_num = parseInt($clones.last().find('input[name^="person_id"]').val()) + 1,
$template = $clones.first(),
newSection = $template.clone().attr('id', 'pq_entry_'+num),
person_id = 'person_id_'+num;
person_fname = 'person_fname_'+num;
person_status = 'person_status_'+num;
newSection.removeAttr('data-saved');
// clear out all sections of new input
newSection.find('input').val('');
newSection.find('select').val([]);
newSection.find('input[name^="person_id"]').attr({
'id': person_id,
'name': person_id
}).val();
newSection.find('input[name^="person_fname"]').attr({
'id': person_fname,
'name': person_fname,
'placeholder' : 'Person #'+num+' First Name'
}).val();
newSection.find('select').attr({
'id': person_status,
'name': person_status
}).val(next_num);
newSection.find('input[type="button"]').attr('data-ident', next_num);
$('#input_table').append(newSection);
$('#btnDel').prop('disabled', '');
if (num == 100) $('#btnAdd').prop('disabled', 'disabled');
});
$('#btnDel').click(function () {
var num = $('.clonedSection').length; // how many duplicate input fields we currently have
$('#pq_entry_' + num).remove(); // remove the last element
// enable the "add" button
$('#btnAdd').prop('disabled', '');
// if only one element remains, disable the "remove" button
if (num - 1 == 1) $('#btnDel').prop('disabled', 'disabled');
});
$('#btnDel').prop('disabled', 'disabled');
});
HTML
<tbody id="input_table" >
<tr id="pq_entry_1" class="clonedSection" data-saved="1">
<td><input type="text" name="person_id" value='1' readonly /></td>
<td>
<input id="person_id_1" name="person_id_1" type="text" value='1'/>
<input id="person_fname_1" name="person_fname" placeholder=" First Name" type="text" value='James'/>
</td>
<td>
<select id="person_status_1" name="person_status_1"></select>
</td>
</tr>
<tr id="pq_entry_2" class="clonedSection" data-saved="2">
<td><input type="text" name="person_id" value='2' readonly /></td>
<td>
<input id="person_id_2" name="person_id_2" type="text" value='2'/><input id="person_fname_2" name="person_fname" placeholder=" First Name" type="text" value='Cynthia'/>
</td>
<td>
<select id="person_status_2" name="person_status_2"></select>
</td>
</tr>
</tbody>
<input type='button' id='btnAdd' value='add another Person' />
<input type='button' id='btnDel' value='Delete New Field' /></br>
From
$('#pq_entry_' + num).remove(); // remove the last element
Change into
var toDelete = $('#pq_entry_' + num).not('[data-saved]');
if (toDelete.length) {
// Last one wasn't a db-entry
toDelete.remove();
// enable the "add" button
$('#btnAdd').prop('disabled', '');
// if only one element remains, disable the "remove" button
if ($('.clonedSection:not([data-saved])').length == 0)
$('#btnDel').prop('disabled', 'disabled');
}
Working example: http://jsfiddle.net/az9LQ/
You can simplify it a lot:
Add a <script type="text/template"> element which can hold the HTML to be appended each time (it won't be visible on the page). I've substituted $1 for the row number which you are dynamically updating and all occurrences of $1 can be replaced in a single shot (and if you want to replace other values then you can extend this and use $2, $3, ... $n for multiple substitutions).
Set up various static variables outside the 'click' handlers including an addedRows array to store the rows as they are added.
In the 'add' handler:
Create the row from the template, replacing $1 with the row number;
Store the row in an addedRows array for later use in the 'delete' handler;
Dynamically update elements as needed; and
Update the buttons.
In the 'delete' handler:
The addedRows array stores all references to the dynamically added rows so just pop() the last row from the array and remove() it;
Update the buttons.
JSFIDDLE
HTML:
<table>
<tbody id="input_table" >
<tr id="pq_entry_1" class="clonedSection" data-saved="1">
<td><input type="text" name="person_id" value='1' readonly /></td>
<td>
<input id="person_id_1" name="person_id_1" type="text" value='1'/>
<input id="person_fname_1" name="person_fname" placeholder=" First Name" type="text" value='James'/>
</td>
<td>
<select id="person_status_1" name="person_status_1"></select>
</td>
</tr>
<tr id="pq_entry_2" class="clonedSection" data-saved="2">
<td><input type="text" name="person_id" value='2' readonly /></td>
<td>
<input id="person_id_2" name="person_id_2" type="text" value='2'/><input id="person_fname_2" name="person_fname" placeholder=" First Name" type="text" value='Cynthia'/>
</td>
<td>
<select id="person_status_2" name="person_status_2"></select>
</td>
</tr>
</tbody>
</table>
<input type='button' id='btnAdd' value='add another Person' />
<input type='button' id='btnDel' value='Delete New Field' /></br>
<script type="text/template" id="template">
<tr id="pq_entry_$1" class="clonedSection">
<td><input type="text" name="person_id" value="$1" readonly /></td>
<td>
<input id="person_id_$1" name="person_id_$1" type="text"/>
<input id="person_fname_$1" name="person_fname" placeholder="Person #$1 First Name" type="text" />
</td>
<td>
<select id="person_status_$1" name="person_status_$1"></select>
</td>
</tr>
</script>
JavaScript:
$(document).ready(function () {
var template = $('#template' ).html(),
$input_table = $( '#input_table' ),
addedRows = [],
num_saved_rows = $('#input_table tr').length;
$('#btnAdd').click(function () {
var row = $( template.replace( /\$1/g, num_saved_rows + addedRows.length + 1 ) )
.appendTo( $input_table );
addedRows.push( row );
$('#btnDel').prop('disabled', num_saved_rows + addedRows.length == 100 );
// Not sure what you are doing with the 'select' element but you can
// dynamically update the attributes of any element like this:
$( 'select', row ).val( '' );
});
$('#btnDel').click(function () {
if ( addedRows.length )
{
addedRows.pop().remove();
$('#btnAdd').prop('disabled', false);
$('#btnDel').prop('disabled', !addedRows.length);
}
});
$('#btnDel').prop('disabled', 'disabled');
});
Not sure what you are trying to do with the select element as it has no OPTION children.

Categories

Resources