I am working with table where copy a table row using javascript issue is that when i click on add more button then copy a table row but input fields are not showing here is my code of table
<table class="striped display" cellspacing="0" width="100%" id="myTable">
<tbody>
<tr>
<td class="input-field col s2">
<label>Module</label>
<select data-rel="chosen" name="moduleid[]" class="form-control">
<?php
$RowRes=mysqli_query($con,"Select id, name from tbl_module where status=1 order by id asc");
while($URow=mysqli_fetch_array($RowRes)){
echo "<option value=".$URow[0].">".$URow[1]."</option>";}?>
</select>
</td>
<td class="input-field col s2">
<label>Week Days</label>
<select id="week_days" data-rel="chosen" name="week_days[]" class="form-control" multiple="multiple">
<option value="1">Monday</option>
<option value="2">Tuesday</option>
<option value="3">Wednesday</option>
<option value="4">Thursday</option>
<option value="5">Friday</option>
</select>
</td>
<td><button type="button" name="add" id="more_btn" class="btn right">Add More</button></td>
</tr>
</tbody>
and here is the javascript code where append a table row on button click
<script type="text/javascript">
$(document).ready(function() {
var i=1;
$('#more_btn').click(function() {
i++;
$('#myTable tbody').append('<tr id="row'+i+'"><td class="input-field col s2"><label>Module</label><select data-rel="chosen" name="moduleid[]" class="form-control"><?php$RowRes=mysqli_query($con,"Select id, name from tbl_module where status=1 order by id asc");while($URow=mysqli_fetch_array($RowRes)){echo "<option value=".$URow[0].">".$URow[1]."</option>";}?></select></td><td class="input-field col s2"><label>Week Days</label><select data-rel="chosen" name="week_days[]" class="form-control" multiple="multiple"><option value="1">Monday</option><option value="2">Tuesday</option><option value="3">Wednesday</option><option value="4">Thursday</option><option value="5">Friday</option></select></td><td><button type="button" name="remove" id="'+i+'" class="btn btn-danger btn_remove">X</button></td></tr>');
$('.btn_remove').click(function(){
var button_id = $(this).attr("id");
$('#row'+button_id+'').remove();
});
});
});
Here is the image of issue
see that first row of table input fields are working perfectly but second row of table that copy when click on Add More button input fields are not working
You can just use JQuery to achieve what you want with the clone method and remove the embeded PHP code.
A simple fiddle can be found here https://jsfiddle.net/xpvt214o/809590/ that merely updates the id of the main <tr> itself. But the code looks as follows:
$(document).ready(function() {
var i=1;
$('#more_btn').click(function() {
i++;
$clone = $('#first').clone(true);
$clone.attr('id', "row" + i);
$clone.find('.btn_remove').attr('data-remove-id', 'row'+i);
$('#myTable tbody').append($clone);
});
$('#myTable').on('click','.btn_remove',function(){
var button_id = $(this).data("remove-id");
$('#'+button_id+'').remove();
});
});
The only id i'm manipulating here is the id of the table row itself. But using jQuery selectors you can change the ids etc. of any of the cloned elements.
I do have a sneaky suspicion your current code won't work as expected, as even in your example all the form inputs have the same names (you only seem to be updating the id of the table row). You may want to make the form names themselves more dynamic by appending the i elsewhere. But that is obviously a different question.
You might also want to consider just having one "Add more" button at the bottom of all the forms, rather than duplicating that as they all have the same id as well. And you don't want to end up with any unintended consequences bearing in mind the click handler is associated with that element.
In your select the php code will not execute:
<select data-rel="chosen" name="moduleid[]" class="form-control"><?php$RowRes=mysqli_query($con,"Select id, name from tbl_module where status=1 order by id asc");while($URow=mysqli_fetch_array($RowRes)){echo "<option value=".$URow[0].">".$URow[1]."</option>";}?></select>
you need to make an api and get data from server.
On first load it works php executed on server and html response generated and that sent to browser. but by adding elements with javascript will not be able to execute php code.
Related
I've data
{product_name: "mushroom", id_p: 13, product_weight: "5", product_unit: "kg"}
How can I display product_weight after i select product name
<td class="col-md-7">
<select style="width:50%;" class="productcategory" id="prod_cat_id" name="id_c[]">
<option value="0" disabled="true" selected="true">category</option>
#foreach($category as $c)
<option value="{{$c->id_c}}" name="id_c" id="id_c">{{$c->category_name}}</option>
#endforeach
</select>
<select style="width:48%;" class="productname" name="id_p[]">
<option value="0" disabled="true" selected="true"> product</option>
</select>
</td>
<td class="col-md-1">
<div id="weights_wrapper" class="productweight" >
</div>
</td>
i want to output productweight in weight_warpper
for(var i=0;i<data.length;i++){
op+='<option value="'+data[i].id_p+'" name="id_p" data-product_weight="'+data[i].product_weight+'" data-product_unit="'+data[i].product_unit+'">'+data[i].product_name+'</option>';
}
$("select.productname").on("change",function(){
var weight = $(this).find(":selected").data("product_weight");
var unit = $(this).find(":selected").data("product_unit");
var span = "<span>"+weight+unit+"</span>";
$("#target_div_where_to_display_weight").html(span);
});
if I add new product my id weights_wrapper will change into weights_wrapper1 i want to output like not sure how to loop this
$("#target_div_where_to_display_weight '+ i +' ").html(span);
here is my append
$(document).ready(function() {
$('#add-form').click(function() {
i++;
$('#add-me').append(
+'<div id="weights_wrapper'+ i +'" class="productweight" name="product_weight">'
)};
I had an answer prepared based on the snips you put in the question, which was as simple as one change, but after looking at the full code, I see you are adding multiple whole rows of product selections, which each having their own weight display div.
A few things need to be changed, and tackled. The biggest problem you are facing is that you need to isolate your index used for each product row you are going to have on the page. Simply relying on the overused 'i' is causing you issues, since 'i' is not initially defined to cover the static html's elements, and its reused in for loops, and such. Gets confusing!
The first time the page is made (the first row, with the static html) should have an initial index set for the id's to use. Then when you add more whole rows, they continue the index value from there.
Static first row:
<tr>
<td class="col-md-7">
... snip ...
<select style="width:48%;" id="productname_1" id_index="1" class="productname" name="id_p[]">
<option value="0" disabled="true" selected="true"> product</option>
</select>
</td>
<td class="col-md-1">
<div id="weights_wrapper_1" class="productweight"></div>
</td>
</tr>
This would be considered row one, indexed to 1. Then when you add another whole row using the js, you need to first initialize that:
var id_i = 1;// 1 meaning one row already exists in the static html
Then follow with the other js output where you build another row, be sure to follow the same format as the initial static row (same id naming convention). Substituting "id_i" for the "1", so that it builds the html with "productname_2" and "weights_wrapper_2" etc.
$('#add-form').click(function() {
id_i++;// will change to '2' on first click
$('#add-me').append( ... the html build ... );
}
If you will spot further above in the "select" element, I added "id_index='#'", which can be used by jquery, to use the right index number to reference which one of the "weights_wrapper_#" you want to put the weight info span into:
$("select.productname").on("change",function(){
... snip ...
var id_index = $(this).attr("id_index");
$("#weights_wrapper_"+ id_index).html(span);
}
I have the following row structure that serves as a template to clone it and add it to a table each time a user presses an "Add" button, This template is hidden:
<tr class="plantilla">
<td>
<select class="cmb_arboles" id="cmb_arboles" name="arboles[]">
</select>
</td>
<td>
<input type="text" id="txttoneladas" name="txttoneladas[]"/>
</td>
<td>
<input type="text" id="txtprecio" name="txtprecio[]"/>
</td>
<td>
<select id="cmb_destino" name="destino[]">
</select>
</td>
<td class="eliminar_fila">
Eliminar
</td>
</tr>
When the "add" button is pressed, invokes:
$("#agregar").click(function()
{
nid++;
$("#plantilla tbody tr:eq(0)").clone().attr("id",nid).appendTo("#plantilla tbody");
$("#plantilla tbody tr:eq(nid)").find("td:eq(0)").find("select").attr("id","cmb_arboles_"+nid);
});
The first line, generates the sequence of the row number. The second line clones the entire template as a new row in the table and adds an id = nid to the .
The third line, accesses the row and looks for the select to add the nid sequential to the select id, but this does not work. When doing several tests, I conclude that the problem is that "tr: eq (nid)" does not accept the nid as variable, because when changing the nid by a specific integer, for example 1, it works, adding id to select. The question here is how to put the nid as a parameter in the: eq () so that it works correctly and do what I have explained ????
The same situation happens in the following line of code:
$(document).on('change', '.cmb_arboles', function () {
var $select = $(this);
var $row = $select.closest('tr');
var idd = $row.attr('id');
var valor=$("#tabla tbody tr[id=idd]").find("td:eq(0)").find("select").val();
});
Of lines 1 to 3, you get the number of the row in which you have selected in the select component.
The last line gets the value of the select that was selected, with the information of the row number where the selection was made, but this does not work. When doing several tests, I conclude that the problem is in "tr [id = idd]", which does not correctly process the variable "idd". I made the test of changing the idd by a specific integer, for example 1 and then I generate a new line in the table with id = 1 and the line of code works correctly, returning the option that was selected in the select element.
With these two examples, I want to check if someone can tell me how to place the parameters I mentioned in the two cases, so that the functionality is executed correctly and does what is expected.
I will be enormously grateful.
the issue is you have to give
("#plantilla tbody tr:eq(nid)" as (("#plantilla tbody tr:eq('"+nid+"')"
I have created a fiddle. check it out. I didn't use jquery for the same.
<style>
#template {
display: none;
}
</style>
<table><tbody id="template">
<tr class="plantilla">
<td>
<select class="cmb_arboles" id="cmb_arboles" name="arboles[]">
</select>
</td>
<td>
<input type="text" id="txttoneladas" name="txttoneladas[]" />
</td>
<td>
<input type="text" id="txtprecio" name="txtprecio[]" />
</td>
<td>
<select id="cmb_destino" name="destino[]">
</select>
</td>
<td class="eliminar_fila">Eliminar</td>
</tr></tbody>
</table>
<input type="button" id="agregar" value="Add">
<table>
<tbody id="plantilla"></tbody>
</table>
<script>
var nid = -1;
document.getElementById('agregar').onclick = function(){
var table = document.getElementById('plantilla');
var newRow = document.getElementById('template').innerHTML;
nid++;
newRow = newRow.replace('id="cmb_arboles"', 'id="cmb_arboles_'+nid+'"');
newRow.replace('id="cmb_arboles"', 'id="cmb_arboles_'+nid+'"');
table.innerHTML += newRow;
}
</script>
https://jsfiddle.net/nugee3s6/
You are hard coding the id value in $("#tabla tbody tr[id=idd]") not using the variable above it
If you wanted to use the variable it would be:
$("#tabla tbody tr[id=" +idd +"]")
But it makes no sense to use the ID to search again for the same row since you already have that row element as $row
So change to:
$(document).on('change', '.cmb_arboles', function () {
var $select = $(this);
var $row = $select.closest('tr');
var valor=$row.find("td:eq(0) select").val();
});
Then don't worry about using ID's, you don't need them
Hi! Guys I know nothing when it comes to JQuery... Please help me with this.
I created bootstrap form with a button add another field if the user want additional input fields. The new field are cloned from the original field.
The date-picker didn't work at first (on cloned field) so I add code to solve that.. (which I was luck to do and it took me 7hrs to get it correct)..
but then I found out even the cloned select box aren't working also.
-> Since the selector was using ID (#e1), I thought that was a reason so I changed it to class (.e1). That didn't help.
->So I tried the same method (like how I did on date-picker) but it also failed..
Here is the Code:
-> At Page header
<script src="assets/js/jquery-2.0.3.min.js"></script>
<script>
function cloneRow()
{
var row = document.getElementById("rowToClone"); // find row to copy
var num = Math.floor((Math.random() * 500) + 1);
var table = document.getElementById("tableToModify"); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.id = "row" + num; // change id or other attributes/contents
table.appendChild(clone); // add new row to end of table
clone.querySelectorAll('[id="id-date-picker-1"]')[0].id = "id-date-picker-" + num; //Put Unique ID
//For Selector
$(function(){
$('.e1').select2();
$('.clone').click(function() {
var clone = $('.select2').clone();
var cloned = clone.find('.e1');
cloned.removeClass('select2').removeAttr('id');
clone.appendTo('.elements');
$(cloned).select2();
});
});
}
</script>
The Row to be cloned
<tbody id="rowToClone">
<tr>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="AL" />Alabama
<option value="AK" />Alaska
<option value="AZ" />Arizona
</select>
</div>
</td>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="VA" />Virginia
<option value="WA" />Washington
</select>
</div>
</td>
</tr>
-> The trigger button
<button type="button" onclick="cloneRow()" class="btn btn-default purple"><i class="fa fa-plus"></i> Add </button>
->Page Footer
//On Page Footer
//--Jquery Select2--
$(".e1").select2(); //I added this line
$("#e1").select2();
$("#e2").select2({
placeholder: "Select a State",
allowClear: true
});
-> Please help me.. I will appreciate.
A couple of problems (your HTML for the options is invalid), but a lot of plugins, that change the DOM, simply do not like to be cloned. They store instance information in element data and are often not re-entrant (cannot reapply the plugin to elements that already have the DOM changes).
As taking existing rows to clone can get messy, I would suggest a slightly different approach to the cloning, that will avoid these problems.
Simply keep a separate template row in your page, that you can clone, inside a dummy script block:
<script id="rowToClone" type="text/template">
<tr>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option></select>
</div>
</td>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="VA">Virginia</option>
<option value="WA">Washington</option></select>
</div>
</td>
<td>
<div class="form-group" style="width: 100%;">
<input type="text" class="datapicker"/>
</div>
</td>
</tr>
</script>
type="text/template" is unknown, so the script is ignored by all browsers.
Then the clone becomes as simple as:
$('#clonerow').click(function(){
$('#table tbody').append($('#rowToClone').html());
// now apply any plugins to the new row
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j1smswmt/2/
Here is an expanded version with datepicker applied to each new row:
$('#clonerow').click(function(){
$('#table tbody').append($('#rowToClone').html()).find('tr:last .datapicker').datepicker();
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j1smswmt/3/
Notes:
Your options are currently invalid. You need to enclose the text inside matching <option> & </option> tags.
As you are using jQuery avoid using inline onclick handlers. They separate the event registration from the event handler for no real benefit. Do it the jQuery way instead.
In case anyone still experience this issue but would still want to use the jQuery clone:
If you are using Bootstrap, you actually just need to remove the bootstrap-select and then reinitialise the normal cloned select.
Just add these two lines of code after you do your clone:
clone.find('.bootstrap-select').remove();
clone.find('select').selectpicker();
Based on answer from this Github issue: https://github.com/silviomoreto/bootstrap-select/issues/605
I have a table that has one <tr> and two <td> inside of it. The first <td> shows a drop-down that has a list of books that the user chooses and the second <td> has a button that will trigger a function after choosing a book. The button works fine, but the problem is that it triggers the function even when the option is set to the "Select Book" title while it is supposed to work only when the book name is chosen not the title which asking the user to select a book.
<table>
<tr>
<td>
<div class="" style="position:relative" >
<select id="test">
<option value="" disabled="disabled" selected="selected">Select Book</option>
<?php
//API calls happening to get the list of books
?>
<option value="<?php //echo id of each book; ?>"><?php //echo name of books ?></option>
</select>
</div>
</td>
<td>
<input type="submit" value="Add to Cart" onclick="addBook()">
</td>
</tr>
</table>
here is the javascript I am running on clicking on the button.
function addBook() {
//getting product name and append it in the report table
var BookName = $("#test option:selected").text();
var tr = "<tr><td>" + BookName + "</td></tr>";
$("#SecondTable").append(tr);
}
So as you can see with the above JS, I will also print "Select Book" as it is assuming that "Select Book" is a book name!
You can check first if the option selected is disabled, then attempt to load the view, please check your function i have edited...
function addBook() {
//getting product name and append it in the report table
var selectedbook = $("#test option:selected");
if(!selectedbook.is(":disabled"))
{
var BookName = selectedbook.text();
var tr = "<tr><td>" + BookName + "</td></tr>";
$("#SecondTable").append(tr);
}
}
<option disabled="disabled">foo</option> makes it so that value is not selectable. It does not stop you from submitting the form.
If you want to validate a form before submitting, write a validation function that you execute in the onsubmit of the form. You can find many examples on how to do this if you search for "form validation".
Also keep in mind that the disabled option is merely a suggestion. A user of your form can still submit any value they like (even bypass your validation function). Validation must take place on the server. Whatever else you do in HTML is nice to have.
Initially, table has only one tr (label/header) and then on click of add button click , i create new tr which looks as below. and all other consequence click of add will clone the last tr.
<tr>
<script type="text/javascript">
//fetch the value of select picker control and set into hidden field.
AJS.$('#' + '${field_uid}-resourcetypepicker-new1').change(function () {
AJS.$('#' + '${field_uid}-resourcetype-new1').val(AJS.$(this).attr('value'));
});
//fetch the value of select picker control and set into hidden field.
AJS.$('#' + '${field_uid}-locationpicker-new1').change(function () {
console.log(AJS.$(this).attr('value'));
AJS.$('#' + '${field_uid}-location-new1').val(AJS.$(this).attr('value'));
});
</script>
<td>
<input id="${field_uid}-resourcetype-new1"
name="${field_uid}"
type="hidden"
value="$r.getResourceType()" />
<select id="${field_uid}-resourcetypepicker-new1">
<option value="adad" #if ($r.getResourceType() == "adad") selected="selected"#end >adad</option>
<option value="dada" #if ($r.getResourceType() == "dada") selected="selected"#end >dada</option>
<option value="aadd" #if ($r.getResourceType() == "aadd") selected="selected"#end >aadd</option>
</select>
</td>
<td>
<input id="${field_uid}-location-new1"
name="${field_uid}"
type="hidden"
value="$r.getLocation()" />
<select id="${field_uid}-locationpicker-new1">
<option value="Internal(Local)" #if ($r.getLocation() == "Internal(Local)") selected="selected"#end >Internal(Local)</option>
<option value="Contractor(Local)" #if ($r.getLocation() == "Contractor(Local)") selected="selected"#end >Contractor(Local)</option>
<option value="Contractor(Offshore)" #if ($r.getLocation() == "Contractor(Offshore)") selected="selected"#end >Contractor(Offshore)</option>
</select>
</td>
<td>
<input id="${field_uid}-rate-new1"
name="${field_uid}"
type="text"
value="$r.getRate()" /> <!-- $textutils.htmlEncode($r.getRate()) -->
</td>
<td>
<input id="${field_uid}-effort-new1"
name="${field_uid}"
type="text"
value="$r.getEffort()" />
</td>
</tr>
PROBLEM:
In above stuff, existing javascript that points to specific control id '#' + '${field_uid}-resourcetypepicker-new1' means (render ID looks like customfield-id-111-new1). Now, problem is, each clone row will have different unique ID for select/picker list control. and this javascript will points to first row control only as AJS.$('customfield-id-111-new1'). But it should be AJS.$('customfield-id-111-new2') then for next row AJS.$('customfield-id-111-new3') .
so, what is the best way to write below jquery stuff which can points to each cloned control rather then pointing to first row controls only ? any way through tr reference control or any other way.
AJS.$('#' + '${field_uid}-resourcetypepicker-new1').change(function () {
AJS.$('#' + '${field_uid}-resourcetype- new1').val(AJS.$(this).attr('value'));
});
Also, in cloned row, it did not include this javascript , do i need to append after clone ?
Please let me know if any more details need.
NOTE: AJS.$ is equal to $. it is used in velocity template file in JIRA.
Thank You
In light of the updated question, see the following code
AJS.$('[id^="${field_uid}-resourcetypepicker-"]')
This selector can be used to get any item with ID that starts with ${field_uid}-resourcetypepicker so you don't have to worry about the last part of the id i.e. new1, new2 etc.
Secondly, your change event will bind to all those elements that are present on page load. But if you create elements dynamically (clone or whatever), the events won't work. You should use
AJS.$('[id^="${field_uid}-resourcetypepicker-"]').on('change', function () {
...
});
This will work for all the elements on the page that match the selector