This question already has answers here:
jQuery ID selector works only for the first element
(7 answers)
Closed 6 years ago.
I'm trying to hide table rows when a tickbox is checked. I have managed to get it working, but it will only hide the first instance of the id. Could someone direct me in to changing the js so it will hide all with matching id.
JSFIDDLE
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('#tierPoints').fadeIn('slow');
else
$('#tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
In HTML, an id has to be unique. See www.w3.org... for more details.
Try to change id="tiersPoints" to class="tiersPoints".
You need to use the "class" selector instead of ID Selector and the ID needs to be unique. You can have multiple elements with same Class Name.
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
You need to have unique ids. Use classes in this case:
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
An id should be distinct within your page.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints1">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints2">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints3">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
Here is solution:
As i mentioned in comment : You need to use tierPoints class. You cannot you multiple tr with same id
$(document).ready(function () {
$('#checkbox1').change(function () {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
input[type=checkbox]{padding:0; margin:0;}
td, th {
background: #ddd;
color: #000;
padding: 2px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2><input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td >75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
Try this. Change id by class. Id is unique by definition.
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
Related
I have following Code in my view.
#foreach($categories as $category)
<tr class="cat-row">
<td class="cat-id">{{$category->id}}</td>
<td>{{$category->name}}</td>
<td>Get ID</td>
</tr>
#endforeach
If I want to get a simple alert with the id of the current row by clicking the Get ID button, what should I do in jquery?
give the get id button a proper selector like class '.getid'
$(document).on('click', '.getid', function() {
let id = $(this).closest('tr').find('.cat-id').text();
console.log(id);
});
you have to bind the listener to document to apply on dynamically inserted dom
Here is my contribution.
Something very similar to what Kapsonfire wrote.
$(document).on('click', '.btn-danger', (e) => {
let target = e.target;
let topmostParent = target.parentElement.parentElement;
let id = $(topmostParent).find('.cat-id').text();
console.log(id);
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<table>
<tr class="cat-row">
<td class="cat-id">123</td>
<td>Test</td>
<td>Get ID</td>
</tr>
<tr class="cat-row">
<td class="cat-id">124</td>
<td>Test</td>
<td>Get ID</td>
</tr>
<tr class="cat-row">
<td class="cat-id">125</td>
<td>Test</td>
<td>Get ID</td>
</tr>
<tr class="cat-row">
<td class="cat-id">126</td>
<td>Test</td>
<td>Get ID</td>
</tr>
</table>
Here is solution for that
$(".getId").on('click',function() {
let id = $(this).attr('id');
console.log(id);
});
/*PHP File*/
#foreach($categories as $category)
<tr class="cat-row">
<td class="cat-id">{{$category->id}}</td>
<td>{{$category->name}}</td>
<td>Get ID</td>
</tr>
#endforeach
We need to hide the row when the value is empty . but cant able to get the value of the empty column value and check it . Code used so far is
(function($) {
$('#event tr').each(function() {
if ($(this).find('.event:empty').length) $(this).remove();
});
})(jQuery);
Please see the below screenshot and marked cell is empty we need to hide the entire row
HTML Structure
<table class="tribe-events-calendar" id="event">
<thead>
<tr>
<th id="tribe-events-date" class="width-print" title="date" style="width:10%">date</th>
<th id="tribe-events-date" class="width-print" title="Weekday" style="width:10%">Weekday</th>
<th id="tribe-events-date" title="holiday name" style="width:20%">holiday name</th>
<th id="tribe-events-date" title="holiday type" style="width:60%">holiday type</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:15%">
<div id="tribe-events-daynum-2-0">
2 </div>
</td>
<!-- day -->
<td style="width:15%">
Mon</td>
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
some value
</td>
<!-- HOLIDAY Type-->
<td>
<p>National Holiday </p>
</td>
<!-- View More -->
</tr>
<tr>
<!-- Day Header -->
<td style="width:15%">
<div id="tribe-events-daynum-2-0">
2 </div>
</td>
<!-- day -->
<td style="width:15%">
Mon</td>
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
</td>
<!-- HOLIDAY Type-->
<td>
<p>National Holiday </p>
</td>
<!-- View More -->
</tr>
</tbody>
</table>
The td contains whitespace and it acts as textNode so :empty selector don't work here since which only select element which doesn't have any child nodes.
So check the text content and filter out td with whitespace or empty using filter() method.
// get all `tr` within the table except the header
// to avoid header tr use tbody in selector
$('#event tbody tr').filter(function() {
// get the event column, get text content,
// trim out text and check string is empty
// 0(length) is falsy value so use `!`
return !$('.event', this).text().trim().length;
// hide the filtered element
// if you would like to remove then use remove() method
}).hide();
$('#event tbody tr').filter(function() {
return !$('.event', this).text().trim();
}).hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="tribe-events-calendar" id="event">
<thead>
<tr>
<th id="tribe-events-date" class="width-print" title="date" style="width:10%">date</th>
<th id="tribe-events-date" class="width-print" title="Weekday" style="width:10%">Weekday</th>
<th id="tribe-events-date" title="holiday name" style="width:20%">holiday name</th>
<th id="tribe-events-date" title="holiday type" style="width:60%">holiday type</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:15%">
<div id="tribe-events-daynum-2-0">
2</div>
</td>
<!-- day -->
<td style="width:15%">
Mon</td>
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
some value
</td>
<!-- HOLIDAY Type-->
<td>
<p>National Holiday</p>
</td>
<!-- View More -->
</tr>
<tr>
<!-- Day Header -->
<td style="width:15%">
<div id="tribe-events-daynum-2-0">
2</div>
</td>
<!-- day -->
<td style="width:15%">
Mon</td>
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
</td>
<!-- HOLIDAY Type-->
<td>
<p>National Holiday</p>
</td>
<!-- View More -->
</tr>
</tbody>
</table>
If your element have white spaces or new line then :empty will not be very effective. You can check for the length of the html after trimming the spaces for the same logic.
(function($) {
$('#event tbody tr').each(function() {
if ($.trim($(this).find("td.event").html()) == "")
$(this).remove();
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="tribe-events-calendar" id="event">
<thead>
<tr>
<th id "tribe-events-date" class="width-print" title="date" style="width:10%">date</th>
<th id="tribe-events-date" class="width-print" title="Weekday" style="width:10%">Weekday</th>
<th id="tribe-events-date" title="holiday name" style="width:20%">holiday name</th>
<th id="tribe-events-date" title="holiday type" style="width:60%">holiday type</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:15%">
<div id="tribe-events-daynum-2-0">
2</div>
</td>
<!-- day -->
<td style="width:15%">
Mon</td>
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
some value
</td>
<!-- HOLIDAY Type-->
<td>
<p>National Holiday</p>
</td>
<!-- View More -->
</tr>
<tr>
<!-- Day Header -->
<td style="width:15%">
<div id="tribe-events-daynum-2-0">
2</div>
</td>
<!-- day -->
<td style="width:15%">
Mon</td>
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
</td>
<!-- HOLIDAY Type-->
<td>
<p>National Holiday</p>
</td>
<!-- View More -->
</tr>
</tbody>
</table>
Most likely empty isnt working because you have whitespace inside the td. Try
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event"></td>
instead of
<!-- HOLIDAY NAME -->
<td style="width:85%" class="event">
</td>
You can do this
$('#event tr').each(function() {
var td= $(this).find("td");
var _this=this;
$(td).each(function() {
var text = $(this).text();
if(text=='' || text==null|| typeof text=='undefined'){
$(_this).hide();
}
});
});
First of all a background of what i want to achieve,
<tr ng-repeat-start="eachParam in myArray">
<td rowspan=2>On site</td>
<td rowspan="2" class = "success">{{eachParam.support}}</td>
<td class = "warning">FE</td>
</tr>
<tr>
<td class = "warning">BE</td>
</tr ng-repeat-end>
I expected it to create a structure like below:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table class = "table table-bordered">
<tbody>
<!-- Repeat 1-->
<tr>
<td rowspan = 2>super parent1</td>
<td rowspan = 2>parent1.1</td>
<td>child 1.1.1</td>
</tr>
<tr>
<td>child 1.1.2</td>
</tr>
<!-- Repeat 2-->
<tr>
<td rowspan = 2>super parent2</td>
<td rowspan = 2>parent2.1</td>
<td>child 2.1.1</td>
</tr>
<tr>
<td>child 2.1.2</td>
</tr>
</tbody>
</table>
you can see in the snippet that, i want to repeat those two super parents using ng-repeat-start and ng-repeat-end so that the intermediate <tr> won't be left out while i am out repeating the super parent or the parent.
Please note the childs are static element.
Now the exception i am getting is:
Unterminated attribute, found 'ng-repeat-start' but no matching
'ng-repeat-end' found
You should add ng-repeat-end to the opening of the tr tag, not the closing tag. Like this:
<tr ng-repeat-start="eachParam in myArray">
<td rowspan=2>On site</td>
<td rowspan="2" class = "success">{{eachParam.support}}</td>
<td class = "warning">FE</td>
</tr>
<tr ng-repeat-end>
<td class = "warning">BE</td>
</tr>
1.) I have created a nested table, then what I want to do is when I click the 'Delete' button inside the child table, its row will be deleted.
2.) I have <select> tag. The problem is how can I put a validation which checks if the item type has been already selected by one customer, but this selected item can be also selected at the next Customer.
For example, Customer1 selects Iron. Now the Customer1 cannot choose the Iron type of item on the next item. Customer1 may also select Copper or Wood but not Iron. Then if I have Customer2 the Iron type of Item can be selectable.
Here's my code:
$(".addItem").on('click', function(e) {
$(this).closest('table').find(".item:last").after('<tr class="item"><td><button>Delete</button></td><td>New item</td><td></td><td></td><td></td><td><select name="" id=""><option value="">Iron</option><option value="">Copper</option><option value="">Wood</option></select></td></tr>');
});
$(".addCustomer").on('click', function(e) {
var newCustomer = $('.customer:last').after('<tr class="customer"><td>New Customer</td><td></td><td></td><td></td></tr>');
var newCart = $('.cart:first').clone(true, true).wrap('td');
newCart.find('tbody').html("").html('<tr class="item"><td><button>Delete</button></td><td>New item</td><td></td><td></td><td></td><td><select name="" id=""><option value="">Iron</option><option value="">Copper</option><option value="">Wood</option></select></td></tr>');
$('.customer:last').append(newCart);
e.preventDefault();
});
$('.itemType').on('change', function() {
var selected = $(this)find('option:selected').val();
if ($(this).find('option:selected').val() === selected) {
alert("Item already selected.");
}
});
table,
td,
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title>PO</title>
<header>
<form id="panel">
</form>
</header>
<section id="I">
<table id='PO1' class="purchaseOrder">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Address</th>
<th>Gender</th>
<th>Cart</th>
</tr>
</thead>
<tbody>
<tr id='C1' class='customer'>
<td>Some Name</td>
<td>30</td>
<td>My Address</td>
<td>Male</td>
<td>
<table class='cart'>
<thead>
<tr>
<th>Delete</th>
<th>Brand</th>
<th>Quantity</th>
<th>Size</th>
<th>Color</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr id='item1' class='item'>
<td><button>Delete</button></td>
<td>Yamaha</td>
<td>30</td>
<td>Large</td>
<td>Black</td>
<td>
<select name="" class="itemType">
<option value="i">Iron</option>
<option value="c">Copper</option>
<option value="w">Wood</option>
</select>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan='5'></td>
<td>
<button class="addItem">Add Item</button>
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan='3'></td>
<td>
<button class="addCustomer">Add Customer</button>
</td>
</tr>
</tfoot>
</table>
</section>
<footer> </footer>
I have fixed the Delete issue. In terms of validation, answer my below question and I will fix the same.
Okay, I handled it now properly with an empty item and disabling the selected value on other item.
$(".addItem").on('click', function(e) {
var parent = $(this).closest('table');
var lastItem = parent.find(".item:last");
var newItem = $('<tr class="item"><td><button>Delete</button></td><td>New item</td><td></td><td></td><td></td><td><select name="" id="" class="itemType"><option value="-1"></option><option value="i">Iron</option><option value="c">Copper</option><option value="w">Wood</option></select></td></tr>');
if(lastItem && lastItem.length > 0) {
parent.find(".item:last").after(newItem);
} else {
parent.append(newItem);
}
fixNewSelectOption(newItem);
handleDeleteAction();
});
$(".addCustomer").on('click', function(e) {
var newCustomer = $('.customer:last').after('<tr class="customer"><td>New Customer</td><td></td><td></td><td></td></tr>');
var newCart = $('.cart:first').clone(true, true).wrap('td');
newCart.find('tbody').html("").html('<tr class="item"><td><button>Delete</button></td><td>New item</td><td></td><td></td><td></td><td><select name="" id="" class="itemType"><option value="-1"></option><option value="i">Iron</option><option value="c">Copper</option><option value="w">Wood</option></select></td></tr>');
$('.customer:last').append(newCart);
handleDeleteAction();
e.preventDefault();
});
$(document).on('click', '.item button', function(){
if($(this).closest('table').find('.item button').length > 1) {
$(this).closest('tr').remove();
}
handleDeleteAction();
});
$(document).on('change', '.itemType', function(){
fixSelectOption($(this));
});
function handleDeleteAction() {
$('table.cart').each(function(){
var cart = $(this);
var deleteButtons = cart.find('.item button');
deleteButtons.prop('disabled', deleteButtons.length <= 1);
});
}
function fixSelectOption(elm) {
var selected = elm.val();
var options = elm.find('option[value!="' + selected + '"]');
var elms = elm.closest('table').find('.itemType').not(elm);
elms.each(function(){
var current = $(this);
if(current.val() === selected){
current.val('-1');
}
options.each(function(){
var optValue = $(this).val();
if(optValue !== '-1' && !$(this).prop('disabled')){
current.find('option[value="' + optValue + '"]').prop('disabled', false);
}
});
if(selected !== '-1'){
current.find('option[value="' + selected + '"]').prop('disabled', true);
}
});
}
function fixNewSelectOption(elm) {
var elms = elm.closest('table').find('.itemType').not(elm);
elms.each(function(){
var current = $(this);
if(current.val() !== '-1'){
elm.find('option[value="' + current.val() + '"]').prop('disabled', true);
}
});
}
table,
td,
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title>PO</title>
<header>
<form id="panel">
</form>
</header>
<section id="I">
<table id='PO1' class="purchaseOrder">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Address</th>
<th>Gender</th>
<th>Cart</th>
</tr>
</thead>
<tbody>
<tr id='C1' class='customer'>
<td>Some Name</td>
<td>30</td>
<td>My Address</td>
<td>Male</td>
<td>
<table class='cart'>
<thead>
<tr>
<th>Delete</th>
<th>Brand</th>
<th>Quantity</th>
<th>Size</th>
<th>Color</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr id='item1' class='item'>
<td><button disabled>Delete</button></td>
<td>Yamaha</td>
<td>30</td>
<td>Large</td>
<td>Black</td>
<td>
<select id="select" class="itemType">
<option value="i">Iron</option>
<option value="c">Copper</option>
<option value="w">Wood</option>
</select>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan='5'></td>
<td>
<button class="addItem">Add Item</button>
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan='3'></td>
<td>
<button class="addCustomer">Add Customer</button>
</td>
</tr>
</tfoot>
</table>
</section>
<footer> </footer>
To delete that respective row on click of any "Delete" button, could you try using this
$(document).on('click', '.item button', function(){
$(this).parent().parent().remove();
});
Here is a Codepen
Another thing I noticed, what are you trying to do in your $('.itemType').on('change', function() ? Because as of now all you are doing is literally checking the value of the selected option to ITSELF which always obviously will be true.
you have to pass an element id which will be deleted from both customer's cart and selected row like this;
<tr class="item"><td><button data-id="1">Delete</button></td><td>New item</td><td></td><td></td><td></td><td><select name="" id=""><option value="">Iron</option><option value="">Copper</option><option value="">Wood</option></select></td>
jquery part:
$("tr.item button").click(function(){
var item_to_remove = $(this).attr("data-id");
var row = $(this).parent().parent();
$.ajax({
url: "url to cart handler for delete item",
data: "id="+item_to_remove,
type: "post",
success: function(data){
row.remove();
},
error: function(){
console.log("ajax req for delete failed");
}
});
});
For the deletion of rows I added checboxes.
PLUNKER
SNIPPET
table {
table-layout: fixed;
}
table,
td,
th {
border: 1px solid black;
}
.name,
.brand,
.color {
width: 10%;
}
.age,
.address,
.pay,
.qty,
.size {
width: 5%;
}
.cart th:first-of-type {
width: 2.5%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title>PO</title>
<link href="style.css" rel="stylesheet">
</head>
<body>
<header>
</header>
<section id="I">
<table id='PO1' class="purchaseOrder">
<thead>
<tr>
<th class='name'>Name</th>
<th class='age'>Age</th>
<th class='address'>Address</th>
<th class='pay'>Pay</th>
<th>Cart</th>
</tr>
</thead>
<tbody>
<tr id='C1' class='customer'>
<td>Jon Doe</td>
<td>30</td>
<td>Earth</td>
<td>Credit</td>
<td>
<table class='cart'>
<thead>
<tr>
<th> </th>
<th class='brand'>Brand</th>
<th class='qty'>Qty</th>
<th class='size'>Size</th>
<th class='color'>Color</th>
</tr>
</thead>
<tbody>
<tr id='item1' class='item'>
<td>
<input class="chx" name="chx" type="checkbox">
</td>
<td>New Item</td>
<td></td>
<td></td>
<td>
<select name='color'>
<option value='black'>Black</option>
<option value='white'>White</option>
</select>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<button class="remItem" onclick='remItem(this)'>-</button>
</td>
<td colspan='3'></td>
<td>
<button class="addItem" onclick='addItem("itemTemplate", this)'>+</button>
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan='3'></td>
<td>
<button class="addCustomer">Add Customer</button>
</td>
</tr>
</tfoot>
</table>
</section>
<footer>
<template id="cartTemplate">
<table class='cart'>
<thead>
<tr>
<th> </th>
<th class='brand'>Brand</th>
<th class='qty'>Qty</th>
<th class='size'>Size</th>
<th class='color'>Color</th>
</tr>
</thead>
<tbody>
<tr class='item'>
<td>
<input class="chx" name="chx" type="checkbox">
</td>
<td>New Item</td>
<td></td>
<td></td>
<td>
<select name='color'>
<option value='black'>Black</option>
<option value='white'>White</option>
</select>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<button class="remItem" onclick='remItem(this)'>-</button>
</td>
<td colspan='3'></td>
<td>
<button class="addItem" onclick='addItem("itemTemplate",this)'>+</button>
</td>
</tr>
</tfoot>
</table>
</template>
<template id='itemTemplate'>
<tr class="item">
<td>
<input class="chx" name="chx" type="checkbox">
</td>
<td>New Item</td>
<td></td>
<td></td>
<td>
<select name="color">
<option value="black">Black</option>
<option value="white">White</option>
</select>
</td>
</tr>
</template>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(".addCustomer").on('click', function(e) {
var newCustomer = $('.customer:last').after('<tr class="customer"><td>New Customer</td><td></td><td></td><td></td></tr>');
var newCart = newClone('cartTemplate');
$('.customer:last').append(newCart);
e.preventDefault();
});
function newClone(id) {
var template = document.getElementById(id);
var clone = document.importNode(template.content, true);
return clone;
}
function addItem(id, origin) {
var newItem = newClone(id);
$(origin).closest('table').append(newItem);
}
function toggle(origin) {
var chxList = $(origin).closest('table').find('.chx:checked');
chkList.click(function() {
chkList.prop('checked', origin.checked)
})
}
function remItem(origin) {
var chxList = $(origin).closest('table').find('.chx:checked');
chxList.each(function(idx, obj) {
obj.closest('.item').remove();
});
}
</script>
</body>
</html>
I know that you got answer on your question, but I couldn't notice some bad patterns in your code. You probably heard for best practices phrase and how things needs to be done on right way. By that I want to give one suggestions. Avoid using HTML in Javascript code whenever it is possible because it makes the application less well-structured.
By that I want to introduce you to templates.
Example how can we optimize your code (from accepted answer):
Wrap everything form newItem variable in script tag and put somewhere in your body:
<script id="newItem-template" type="text/x-custom-template">
<tr class="item"><td><button>Delete</button></td>
<td>New item</td><td></td><td></td><td></td><td>
<select name="" id="" class="itemType"><option value="-1"></option>
<option value="i">Iron</option><option value="c">Copper</option>
<option value="w">Wood</option></select></td></tr>
</script>
Browser will simply ignore this, until you call html() method to return that content.
So instead of this:
var newItem = $('<tr class="item"><td><button>Delete</button></td><td>New item</td><td></td><td></td><td></td><td><select name="" id="" class="itemType"><option value="-1"></option><option value="i">Iron</option><option value="c">Copper</option><option value="w">Wood</option></select></td></tr>');
In your javascript file you will have only this:
var newItem = $('#newItem-template').html();
Here is optimized working code: jsFiddle
This is jQuery way to manage with templates, but there is powerful template engines if your project get bigger:
JavaScript templating engines
Please, I'm stuck here trying to format the Y-axis in Highcharts so it indicates currency symbol but mainly, i need the unit abbreviations to show. Here is my Html and javascript. It gets data from an HTML table.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="jquery-1.9.0.min.js"></script>
<script src="highcharts.src.js"></script>
<script src="jquery.highchartTable.js"></script>
<script>
$(document).ready(function() {
$('table.highchart').highchartTable();
});
</script>
</head>
<body>
<table class="table table-bordered table-condensed table-striped table-primary table-vertical-center checkboxs highchart" data-graph-container-before="1" data-graph-type="column" data-graph-yaxis-1-formatter-callback="graph_ValueFormatter" data-graph-height="350">
<thead>
<tr>
<th data-graph-hidden="1">Location</th>
<th class="center" style="width: 100px;">Sales</th>
<th class="center" style="width: 100px;">Pipeline</th>
<th class="center" style="width: 100px;">Projected</th>
</tr>
</thead>
<tbody>
<!-- Item -->
<tr class="selectable">
<td><strong>Africa Re, VI Lagos</strong></td>
<td class="center">31,977</td>
<td class="center">1,230</td>
<td class="center">31,977</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Muliner Towers, Ikoyi Lagos</strong></td>
<td class="center">28,756</td>
<td class="center">1,079</td>
<td class="center">28,835</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Somewhere, London</strong></td>
<td class="center">13,328</td>
<td class="center">1,833</td>
<td class="center">14,161</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Somewhere, Johanesburg</strong></td>
<td class="center">38,893</td>
<td class="center">3,430</td>
<td class="center">38,893</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Someplace, Nairobi</strong></td>
<td class="center">241,178</td>
<td class="center">2,247</td>
<td class="center">243,425</td>
</tr>
<!-- // Item END -->
</tbody>
</table>
</body>
</html>![enter image description here][1]
You can use formatter in yAxis labels: http://api.highcharts.com/highcharts#yAxis.labels.formatter