Checkboxes in DataTables need to capture all checked values - javascript

I am having 100s of items in my datatable, displayed using 'forEach' in script as below
<div class="panel-body">
<table class="table table-striped" id="table1">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Customer</th>
<th scope="col">CheckBoxes</th>
</tr>
</thead>
<tbody>
<c:forEach items="${list}" varStatus="status" var="name">
<tr>
<td>${status.index + 1}</td>
<td>${name.getName()}</td>
<td>${name.getCustomer()}</td>
<td>
<input type="checkbox" class="custom-control-input" id="checkRule" value="${rule.getName()}">
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
What I am trying is, upon checking respective checkboxes, I need those value to be fetched and sent in AJAX (POST).
$(document).ready(function(){
const myArray = [];
$('#checkRule').click(function(){
console.log('checked');
if( $('#checkRule').is(':checked') ) {
myArray.push( $('#checkRule').val() );
console.log(myArray);
}else{
const index = myArray.indexOf( $('#checkRule').val() );
if (index > -1) {
myArray.splice(index, 1);
}
console.log(myArray);
}
});
$('#correlation_table').DataTable();
$('#send').click(function(){
var result = myArray;
console.dir('Import result >>>>> ',result);
$.ajax({
url: "sendAll",
headers: {
'Accept': 'text/plain',
'Content-Type': 'application/json'
},
type: "POST",
dataType: "html",
data: JSON.stringify(result),
success :function(data) {
console.log(data);
},
error :function(err){
console.log(err);
}
});
});
});
Upon using this above code, I am reaching nowhere.
Console output for "console.log('Import result >>>>> ',result);" is
Import result >>>>> Array []
How can I get all 'Name' upon checking multiple checkboxes in table?

You have given same ids to all your checkboxes so only first checkboxes value you will be getting in your array instead use class selector instead of id and then simply use $(this) to get the reference of checkbox change and add those values in your array using .val()
Demo Code :
$(document).ready(function() {
const myArray = [];
//use class here
$('.checkRule').change(function() {
//use `this` to get refernce of current checkbox change
if ($(this).is(':checked')) {
myArray.push($(this).val()); //put that value
} else {
const index = myArray.indexOf($(this).val());
if (index > -1) {
myArray.splice(index, 1);
}
}
});
$('#correlation_table').DataTable();
$('#send').click(function() {
var result = myArray;
console.log('Import result >>>>> ', result);
//your ajax call..
});
});
<div class="panel-body">
<link rel='stylesheet' type='text/css' href='https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css'>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<table class="table table-striped" id="correlation_table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Customer</th>
<th scope="col">CheckBoxes</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>sss</td>
<td>123</td>
<td>
<!-- use class instead of id-->
<input type="checkbox" class="custom-control-input checkRule" value="ss">
</td>
</tr>
<tr>
<td>2</td>
<td>ses</td>
<td>23</td>
<td>
<input type="checkbox" class="custom-control-input checkRule" value="ses">
</td>
</tr>
<tr>
<td>3</td>
<td>sswi</td>
<td>13</td>
<td>
<input type="checkbox" class="custom-control-input checkRule" value="sswi">
</td>
</tr>
<tr>
<td>4</td>
<td>ssww</td>
<td>12</td>
<td>
<input type="checkbox" class="custom-control-input checkRule" value="ssww">
</td>
</tr>
</tbody>
</table>
</div>
<button id="send">SEnd</button>

Related

Ajax append one row instead of array

I have an ajax function that gets an array of data from the backend and when I try to append those data in the blade it only shows 1 row instead of an array of rows.
Issues
Only 1 row append by ajax
Select option will be empty when results return while I don't have any code to clear my select option.
Code
$(function() {
// get cities
$('#province').on('change', function(e) {
e.preventDefault();
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
});
var hospitalId = $(this).val();
$.ajax({
url: '{{ url('hospitals') }}/'+encodeURI(hospitalId),
dataType: "json",
type: 'GET',
success: function(data) {
console.log('dd: ', data.data);
if(data.data != null) {
$('.resError').hide();
$('.result').show();
// data to append
$.each(data.data, function(key, value) {
$('#code').html(value.code);
$('#name').html(value.name);
$('#type').html(value.type);
$('#class').html(value.class);
$('#beds').html(value.beds);
$('#owner').html(value.owner);
$('#province').html(value.province);
$('#city').html(value.city);
$('#address').html(value.address);
});
} else {
$('.resError').show();
$('.result').hide();
$('.resError').html('something went wrong, try again!');
}
},
error:function(err) {
$('.resError').show();
$('.resError').html('You need to select province!');
$('.result').hide();
$('#code').html('');
$('#name').html('');
$('#type').html('');
$('#class').html('');
$('#beds').html('');
$('#owner').html('');
$('#province').html('');
$('#city').html('');
$('#address').html('');
}
});
});
});
results
Update
<p>Results</p>
<div class="resError clearfix mt-4" style="display:none;"></div>
<div class="result clearfix mt-4" style="display:none;">
<table class="mb-3 table table-bordered table-hover">
<tbody>​​​
<tr>
<th width="50">Code</th>
<td id="code"></td>
</tr>
<tr>
<th width="50">Name</th>
<td id="name"></td>
</tr>
<tr>
<th width="50">Type</th>
<td id="type"></td>
</tr>
<tr>
<th width="50">Class</th>
<td id="class"></td>
</tr>
<tr>
<th width="50">Beds</th>
<td id="beds"></td>
</tr>
<tr>
<th width="50">Owner</th>
<td id="owner"></td>
</tr>
<tr>
<th width="50">Province</th>
<td id="province"></td>
</tr>
<tr>
<th width="50">City</th>
<td id="city"></td>
</tr>
<tr>
<th width="50">Address</th>
<td id="address"></td>
</tr>
</tbody>
</table>
</div>
in blade
<p>Results</p>
<div class="resError clearfix mt-4" style="display:none;"></div>
<div class="result clearfix mt-4" style="display:none;">
<table class="mb-3 table table-bordered table-hover">
<tbody id="body">​​​
</tbody>
</table>
</div>
in javascript
$.each(data.data, function(key, value) {
var element = `
<tr>
<th width="50">Code</th>
<td id="code">${value.code}</td>
</tr>
<tr>
<th width="50">Name</th>
<td id="name">${value.name}</td>
</tr>
<tr>
<th width="50">Type</th>
<td id="type">${value.type}</td>
</tr>
<tr>
<th width="50">Class</th>
<td id="class">${value.class}</td>
</tr>
<tr>
<th width="50">Beds</th>
<td id="beds">${value.beds}</td>
</tr>
<tr>
<th width="50">Owner</th>
<td id="owner">${value.owner}</td>
</tr>
<tr>
<th width="50">Province</th>
<td id="province">${value.province}</td>
</tr>
<tr>
<th width="50">City</th>
<td id="city">${value.city}</td>
</tr>
<tr>
<th width="50">Address</th>
<td id="address">${value.address}</td>
</tr>
`;
$('#body')append(element);
});
In your below code, you are appending value by the fieldId, that's why it is only appending only the last row(each iteration, the value is being updated in background) values are being set.
$('#code').html(value.code);
$('#name').html(value.name);
$('#type').html(value.type);
$('#class').html(value.class);
$('#beds').html(value.beds);
$('#owner').html(value.owner);
$('#province').html(value.province);
$('#city').html(value.city);
$('#address').html(value.address);
So, to achieve your purpose, you have to append these as a complete row and insert into the table, not just appending fieldwise value but rowwise and insert that row into the table. I hope you get my point.
The problem is that you are always changing the same elements of the same table. I think you will need to append one table per row:
$.each(data.data, function(key, value) {
$(".result").append('<table class="mb-3 table table-bordered table-hover">...</table>')
});
However, you may want to use Handlebars or some other templating library to avoid creating a long string with the table.

How to change content inside table when condition search is false using javascript

I have a code for table and search text :
<div class="table-responsive">
Search Data : <input type="text" class="txtSearch" id="search_field">
<div class="tableFixHead">
<table id="fid_table" class="ui celled table" style="width:100%">
<thead>
<tr class="t_head">
<th>No</th>
<th>Name</th>
<th>Gender</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John</td>
<td>Male</td>
</tr>
<tr>
<td>2</td>
<td>Lily</td>
<td>Female</td>
</tr>
<tr>
<td>3</td>
<td>Joe</td>
<td>Male</td>
</tr>
</tbody>
</table>
</div>
</div>
And I have simple search code using javascript like this :
$('#search_field').on('keyup', function() {
var value = $(this).val();
var patt = new RegExp(value, "i");
$('#fid_table').find('tr').each(function() {
var $table = $(this);
var result = $table.find('td').text().search(patt);
if (!(result >= 0)) {
$table.not('.t_head').hide();
}
if ((result >= 0)) {
$(this).show();
}
});
});
And I want make $table.not('.t_head').hide() change to text inside tag <td> and make a text like this Sorry, bla bla bla.
Before I input text on search field
After I input and the result is false
Use the whole table body to search for the text, so if it returns -1 you could use it to negate and toggle the element that shows the message ( I have placed it as an additional row, that is hidden on load) about no results.
Also, you could use a .toggle(), instead of the conditional block to simplify the code and constrain the selection to the tbody of the table element, to avoid filtering the thead of the table element.
And finally, use the jQuery's .filter() to iterate through selection and return only those that fulfill the conditions:
$(document).ready(function(){
var tableRows = $('#fid_table tbody tr');
var table = $('#fid_table tbody');
var noResults = $('.no-results');
noResults.hide();
$('#search_field').on('keyup', function() {
var value = $(this).val().toLowerCase();
var patt = new RegExp(value, "i");
tableRows.filter(function() {
var toggle = $(this).text().toLowerCase().search(patt) > -1;
$(this).toggle(toggle );
});
var noResultsToggle = table.text().toLowerCase().search(patt) === -1;
noResults.toggle(noResultsToggle);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-responsive">
Search Data : <input type="text" class="txtSearch" id="search_field">
<div class="tableFixHead">
<table id="fid_table" class="ui celled table" style="width:100%">
<thead>
<tr class="t_head">
<th>No</th>
<th>Name</th>
<th>Gender</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John</td>
<td>Male</td>
</tr>
<tr>
<td>2</td>
<td>Lily</td>
<td>Female</td>
</tr>
<tr>
<td>3</td>
<td>Joe</td>
<td>Male</td>
</tr>
</tbody>
<tfoot>
<tr class="no-results">
<td colspan="3" align="center">
Sorry, there are no results for given search string
</td>
</tr>
</tfoot>
</table>
</div>
</div>
You can have an element with the message. Show/hide that element based on the condition:
Try the following way:
$('#search_field').on('keyup', function() {
var value = $(this).val();
var patt = new RegExp(value, "i");
$('#fid_table').find('tr').each(function() {
var $table = $(this);
var result = $table.find('td').text().search(patt);
if (!(result >= 0)) {
$table.hide();
$('#message').show()
}
else if((result >= 0)) {
$('#message').hide();
$(this).show();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-responsive">
Search Data : <input type="text" class="txtSearch" id="search_field">
<div class="tableFixHead">
<div id="message" style="display:none">Sorry, no data!</div>
<table id="fid_table" class="ui celled table" style="width:100%">
<thead>
<tr class="t_head">
<th>No</th>
<th>Name</th>
<th>Gender</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John</td>
<td>Male</td>
</tr>
<tr>
<td>2</td>
<td>Lily</td>
<td>Female</td>
</tr>
<tr>
<td>3</td>
<td>Joe</td>
<td>Male</td>
</tr>
</tbody>
</table>
</div>
</div>

Get id of checkboxes when checked using D3

I have a Bootstrap table in the following format
<div class="col-sm-8">
<div class="tablecontainer">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Instances</th>
<th scope="col">Chains</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type='checkbox' id='[0]' class='jmolInline'>1</td>
<td>4LF8|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[1]' class='jmolInline'>2</td>
<td>4LF7|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[2]' class='jmolInline'>1</td>
<td>4B3W|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[3]' class='jmolInline'>2</td>
<td>4AA4|1|A</td>
</tr>
</tbody>
</table>
</div>
I would like to get the ids of the checkboxes as they are being checked using d3. I've tried the following but it doesn't seem to work. What would be the best way to get the checked ids stored in an array using d3?
var checked = []
var boxes = d3.selectAll("input.jmolInline:checked");
boxes.each(function() {
checked.push(this.id)
});
console.log(checked)
use this code to get the job done
var inputs = d3.selectAll('input[type="checkbox"]')._groups[0];
document.getElementById('submit').addEventListener('click', function() {
var checked = [];
for (i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
checked.push(inputs[i].id);
}
}
document.getElementById('result').innerHTML = 'Array of ids selected ' + checked;
console.log(checked);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div class="col-sm-8">
<div class="tablecontainer">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Instances</th>
<th scope="col">Chains</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type='checkbox' id='[0]' class='jmolInline'>1</td>
<td>4LF8|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[1]' class='jmolInline'>2</td>
<td>4LF7|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[2]' class='jmolInline'>1</td>
<td>4B3W|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[3]' class='jmolInline'>2</td>
<td>4AA4|1|A</td>
</tr>
</tbody>
</table>
<button id="submit">get Id</button>
<div id="result"></div>
</div>

How to serialize a form in custom key/value pairs?

I need to serialize a form in a custom key/value pair format. This is how my HTML code looks like:
<form name="ltq_frm" id="ltq_frm">
<table class="table" id="licenses_to_quote">
<thead>
<tr>
<th>License ID</th>
<th>Quote ID</th>
<th>Agreement Type</th>
<th>Customer Site</th>
</tr>
</thead>
<tbody id="licenses_to_quote_body">
<tr data-id="96">
<td>
96
<input type="hidden" name="license_id" value="96">
</td>
<td>
<input class="hidden-select2-96" type="hidden" name="quote_id" value="249"> 249
</td>
<td>Percentage Support</td>
<td>Frito-Lay, Inc.</td>
</tr>
<tr data-id="100">
<td>
100
<input type="hidden" name="license_id" value="100">
</td>
<td>
<input class="hidden-select2-100" type="hidden" name="quote_id" value="">
</td>
<td>Percentage Support</td>
<td>Frito-Lay, Inc.</td>
</tr>
</tbody>
</table>
</form>
<button id="subm">
Click
</button>
And this is how I am serializing it:
$(function() {
$('#subm').click(function() {
var sA = $('#ltq_frm').serializeArray();
var s = $('#ltq_frm').serialize();
console.log(sA);
console.log(s);
});
});
This is "working" but I am getting an array of four values as output. I would like to get something like:
[
'license_id' => 'quote_id'
]
Using the example above:
[
96 => 249,
100 =>
]
The values above comes from the hidden elements on the form, those named as license_id and quote_id.
I was checking here but I couldn't get the idea in how to transform my values into the needed key/value pairs.
This is a jsFiddle I was working with in case you need it.
Note: this is a code in development so if you have a better suggestion or need to give me something different go ahead
You could manually map each row, get the two inputs, use the first as the key and the second as the value, like this
var result = $('#ltq_frm tbody tr').map(function() {
var inp = $('input', this), o = {};
o[inp.first().val()] = inp.last().val();
return o;
}).get();
FIDDLE
I get it. You need a custom code like this to do it:
var finalObj = { };
$.each(​$('form')​.serializeArray()​, function() {
finalObj[this.name] = this.value;
})​;
console.log(finalObj);
Snippet
var finalObj = { };
$.each($('form').serializeArray(), function() {
finalObj[this.name] = this.value;
});
console.log(finalObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="ltq_frm" id="ltq_frm">
<table class="table" id="licenses_to_quote">
<thead>
<tr>
<th>License ID</th>
<th>Quote ID</th>
<th>Agreement Type</th>
<th>Customer Site</th>
</tr>
</thead>
<tbody id="licenses_to_quote_body">
<tr data-id="96">
<td>
96
<input type="hidden" name="license_id" value="96">
</td>
<td>
<input class="hidden-select2-96" type="hidden" name="quote_id" value="249"> 249
</td>
<td>Percentage Support</td>
<td>Frito-Lay, Inc.</td>
</tr>
<tr data-id="100">
<td>
100
<input type="hidden" name="license_id[]" value="100">
</td>
<td>
<input class="hidden-select2-100" type="hidden" name="quote_id[]" value="">
</td>
<td>Percentage Support</td>
<td>Frito-Lay, Inc.</td>
</tr>
</tbody>
</table>
</form>
Update: To get your custom way, I need to still change it further. In your question, the code has some inconsistencies. Those I corrected are as follows:
license_id[] to license_id.
quote_id[] to quote_id.
Please follow one single convention.
var finalObj = { };
var lastLID = "";
$.each($('form').serializeArray(), function() {
if (this.name == "license_id")
lastLID = this.value;
else (this.name == "quote_id")
finalObj[lastLID] = this.value;
});
console.log(finalObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="ltq_frm" id="ltq_frm">
<table class="table" id="licenses_to_quote">
<thead>
<tr>
<th>License ID</th>
<th>Quote ID</th>
<th>Agreement Type</th>
<th>Customer Site</th>
</tr>
</thead>
<tbody id="licenses_to_quote_body">
<tr data-id="96">
<td>
96
<input type="hidden" name="license_id" value="96">
</td>
<td>
<input class="hidden-select2-96" type="hidden" name="quote_id" value="249"> 249
</td>
<td>Percentage Support</td>
<td>Frito-Lay, Inc.</td>
</tr>
<tr data-id="100">
<td>
100
<input type="hidden" name="license_id" value="100">
</td>
<td>
<input class="hidden-select2-100" type="hidden" name="quote_id" value="">
</td>
<td>Percentage Support</td>
<td>Frito-Lay, Inc.</td>
</tr>
</tbody>
</table>
</form>

How can I identify a specific item in <select> and add a delete button each row in jquery

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

Categories

Resources