I have a HTML table which has a column for checked rows(which has a check box in the cell).
I am using knockout to bind the selected check boxes to an observable array with an attribute ID as shown below.(this works fine without "checked")
The NListTable is an observable array from getJson (which populate the table on return).I want to be able to post the selected IDs after the table is populated.
<thead>
<tr>
<th style=" text-align:center"><b>Generate Notice</b><input type="checkbox" data-bind="checked: SelectAll" /></th>
<th style=" text-align:center"><b>Name</b></th>
<th style=" text-align:center"><b>Application Number</b></th>
<th style=" text-align:center"><b>Right ID</b></th>
<th style=" text-align:center"><b> Division</b></th>
<th style=" text-align:center"><b>Use ID</b></th>
</tr>
</thead>
<tbody data-bind="foreach:NListTable">
<tr>
<td style=" text-align:center">
<input type="checkbox" data-bind="checked: Selected">
</td>
<td style=" text-align:center">
<p data-bind="text:Name"></p>
</td>
<td style=" text-align:center">
<p data-bind="text:AppNum"></p>
</td>
<td style=" text-align:center">
<p data-bind="text:ID"></p>
</td>
<td style=" text-align:center">
<p data-bind="text:DivName"></p>
</td>
<td style=" text-align:center">
<p data-bind="text:useID"></p>
</td>
</tr>
</tbody>
JS
function RowData(Name, AppNum, ID, DivName, useID) {
var self = this;
self.Selected = ko.observable(true);
self.Name = ko.observable(Name);
self.AppNum = ko.observable(AppNum);
self.ID = ko.observable(ID);
self.DivName = ko.observable(DivName);
self.useID = ko.observable(useID);
}
self.NListTable = ko.observableArray([new RowData()]);
//self.selectedThings = ko.observableArray([]);
self.SelectAll = ko.computed({
read: function () {
var item = ko.utils.arrayFirst(self.NListTable(), function (item) {
return !item.Selected();
});
return item == null;
},
write: function (value) {
ko.utils.arrayForEach(self.NListTable(), function (rowData) {
rowData.Selected(value);
});
}
});
getJSON
function (data) {
$("#nListTable").show();
for (var i = 0; i < data.length; i++) {
if (data[i] != null) {
self.NListTable.push(RowData(data[i].FirstName + ' ' + data[i].LastName, data[i].AppPre + '-' + data[i].AppNum, data[i].ID, data[i].DivName, data[i].useID));
}
}
});
I am trying to select all check boxes when the page loads by using the HTML attribute "checked" but this does not work all my check boxes are unchecked even when I use this.
How do I pre select all check boxes
Well you should be doing something like this
View Model:
self.SelectAll = ko.computed({
read: function () {
var item = ko.utils.arrayFirst(self.NListTable(), function (item) {
return !item.Selected();
});
return item == null;
},
write: function (value) {
ko.utils.arrayForEach(self.NListTable(), function (rowData) {
rowData.Selected(value);
});
}
});
Working fiddle here
Related
I have below web page it shows I have created one table & added AddRow & remove row functions using jquery. I am calling JSP file through AJAX call for auto search.
But it seems working for only first row of table & when m searching in newly added row suggestions are showing in first row only.
Below is screenshot
$(document).ready(function() {
// Denotes total number of rows
var rowIdx = 0;
// jQuery button click event to add a row
$('#addBtn').on('click', function() {
// Adding a row inside the tbody.
$('#tbody').append(`
<tr id="R${++rowIdx}">
<td class="row-index text-center">
<p>Row ${rowIdx}</p>
</td>
<td class="cb"><input class="form-control" type="text" value="" id="inputString" name="inputString" />
<div id="showList">
<ul class="list-group"></ul>
</div>
</td>
<td>
<input type="checkbox" name="debit" class="form-control">
</td>
<td>
<input type="checkbox" name="credit"class="form-control">
</td>
<td>
<input type="number" name="amount" class="form-control">
</td>
<td class="text-center">
<button class="btn btn-danger remove" type="button">Remove</button>
</td>
</tr>`);
});
/*$("#tbody").on("keyup"," input[name^=inputString]", function(){
$("tbody tr").each(function () {
var search = $(this).closest('tr').find("td:eq(rowIdx) input").val();
if(search !='' && search !=null) {
$.ajax({
type:'POST',
url:'ledgers.jsp',
data:'key='+search,
success:function(data){
$('#showList').html(data);
}
});
}
else {
$('#showList').html('');
}
});
});*/
$("#tbody").on("keyup", " input[name^=inputString]", function() {
$("tbody tr").each(function() {
var search = $(this).closest('tr').find("input").val();
if (search != '' && search != null) {
$.ajax({
type: 'POST',
url: 'ledgers.jsp',
data: 'key=' + search,
success: function(data) {
$('#showList').html(data);
}
});
} else {
$('#showList').html('');
}
});
});
$("#tbody").on("click", "li", function() {
$('#inputString').val($(this).text());
$('#showList').html('');
});
// jQuery button click event to remove a row.
$('#tbody').on('click', '.remove', function() {
// Getting all the rows next to the row
// containing the clicked button
var child = $(this).closest('tr').nextAll();
// Iterating across all the rows
// obtained to change the index
child.each(function() {
// Getting <tr> id.
var id = $(this).attr('id');
// Getting the <p> inside the .row-index class.
var idx = $(this).children('.row-index').children('p');
// Gets the row number from <tr> id.
var dig = parseInt(id.substring(1));
// Modifying row index.
idx.html(`Row ${dig - 1}`);
// Modifying row id.
$(this).attr('id', `R${dig - 1}`);
});
// Removing the current row.
$(this).closest('tr').remove();
// Decreasing total number of rows by 1.
rowIdx--;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group required col-md-8">
<table class="table table-bordered" id="table_field">
<thead>
<tr id="r1">
<th>Row No</th>
<th>Ledger Name</th>
<th>Debit</th>
<th>Credit</th>
<th>Amount</th>
<th>Add or Remove</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
<tr>
<input class="btn btn-success" type="button" name="add" id="addBtn" value="Add">
</tr>
</table>
<center>
<input class="btn btn-success" type="submit" name="save" id="save" value="Save">
</center>
</div>
can anybody suggest me whats wrong with above code.
Run auto search for every table row TD input field
enter image description here
Please replace the keyup function() with below code:
$("#tbody").on("keyup", "input[name^=inputString]", function() {
var $this = $(this);
$("tbody tr").each(function() {
var search = $(this).closest('tr').find("input").val();
if (search != '' && search != null) {
$.ajax({
type: 'POST',
url: 'ledgers.jsp',
data: 'key=' + search,
success: function(data) {
$this.next('#showList').html(data);
}
});
} else {
$('#showList').html('');
}
});
});
Please let me know if you find any issues.
Thanks.
I am using select option in a datatable and I want to get value of selected option from rows of that table,When I want to get the selected option in each row of the table, since the select "id" is one so it brings the same value every time(the first selected value), but the selected option value changes in each row.
HTML CODE:
<div class="card-body">
<table id="customerTable" class="data-table-customer table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Tel</th>
<th>Agent</th>
</tr>
</thead>
<tbody>
#foreach (var customer in Model.customerLoadList)
{
<tr id="customerRow">
<td>#customer.Name</td>
<td>#customer.Surname</td>
<td>#customer.PhoneNumber</td>
<td class="agentList">
<div class="form-group">
// id="agentList" this id is same for all values, how i change it to dynamic id
<select id="agentList" name="agentList" class="agentSelect form-control">
#foreach (var agent in Model.agentList)
{
<option value="#agent.AgentId">#agent.AgentNameSurname</option>
}
</select>
</div>
</td>
</tr>}
</table>
</div>
JQUERY CODE
function SaveCustomer() {
var customerListForAdd = new Array();
var table = document.getElementById("customerTable");
var tableLenght = table.rows.length;
for (var i = 0; i < tableLenght - 1; i++) {
var customerObj = {
Name: ($('.data-table-customer').DataTable().cell(i, 0).data()).toString(),
Surname: ($('.data-table-customer').DataTable().cell(i, 1).data()).toString(),
PhoneNumber: ($('.data-table-customer').DataTable().cell(i, 2).data()).toString(),
// i get value from this code but all of the value are same i wanna make it dynamic
Agent: $('select[name=agentList]').filter(':selected').val()
};
customerListForAdd.push(customerObj);
}
$.ajax({
type: 'POST',
url: '/Stock/SaveCustomerList',
data: { "customerListForAdd": customerListForAdd },
ContentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (r) {
alert(r + " record(s) inserted.");
}
});
}
you need to change the <select> id every time when you achieve the value of option
veiw
<div class="card-body">
<table id="customerTable" class="data-table-customer table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Tel</th>
<th>Agent</th>
</tr>
</thead>
<tbody>
#*change here*#
#{int i = 0;}
#foreach (var customer in ViewBag.A)
{
<tr id="customerRow">
<td>#customer.Name</td>
<td>#customer.Surname</td>
<td>#customer.PhoneNumber</td>
<td class="agentList">
<div class="form-group">
<select id="agentList_#i" name="agentListName" class="agentSelect form-control">
#foreach (var agent in ViewBag.B)
{
<option value="#agent.AgentId">#agent.AgentNameSurname</option>
}
</select>
</div>
</td>
</tr>
i++;
}
</tbody>
</table>
<button onclick="SaveCustomer()">Save</button>
</div>
script
<script>
function SaveCustomer()
{
var customerListForAdd = new Array();
var table = document.getElementById("customerTable");
var tableLenght = table.rows.length;
var rows = table.rows;
for (var i = 0; i < tableLenght - 1; i++) {
var customerObj = {
Name: ($('.data-table-customer').DataTable().cell(i, 0).data()).toString(),
Surname: ($('.data-table-customer').DataTable().cell(i, 1).data()).toString(),
PhoneNumber: ($('.data-table-customer').DataTable().cell(i, 2).data()).toString(),
// i get value from this code but all of the value are same i wanna make it dynamic
AgentId: $('#agentList_'+i).val()
};
customerListForAdd.push(customerObj);
}
$.ajax({
type: 'POST',
url: '/Home/test2',
data: JSON.stringify(customerListForAdd),
contentType: 'application/json;charset=utf-8',
success: function (data) {
alert(data);
}
});
</script>
Then,you can get value from Jquery function
In my scenario i have a table which inputs data from user and save the table rows first in json array then pass this array to MVC controller using ajax.
The data in table (eg name eid student id )are fill from server side from controller using jquery then user have to provide marks against each student.then the table data along with marks pass from view to controller using ajax.
Scenario for Problem:
if user fill some rows not all ones then only filled rows data should be inserted in json array.How can I achieve this using Jquery . first check if the row is filled then add that row data in array
#Html.DropDownList("ClarderSousSecteurID", "--- Tous ---")
<input id="date" value='#DateTime.Now.ToString(" dd/mm/yyyy")' />
<input id="date" type="hidden" value='#ViewBag.P_No' />
<table id="tableId" class="table table-bordered table-condensed table-hover table-striped">
<thead>
<tr>
<th>Student_id</th>
<th>Name</th>
<th>Did he perform well</th>
<th>According to Criteria</th>
<th>To the point</th>
<th>EID</th>
</tr>
</thead>
<tbody></tbody>
</table>
<input type="submit" id="savebtn" class="btn btn-success" value="Save" style="display:none;" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
var date;
var val;
$("#ClarderSousSecteurID").change(function () {
val = $("#ClarderSousSecteurID").val();
$("#tableId > tbody").empty();
date = $("#date").val();
$("#savebtn").show();
alert("selected=" + val + date)
var data = JSON.stringify({
'val': val
});
$.ajax({
type: "POST",
url: "/judge_dashboard/Getstudents",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var tr;
//Append each row to html table
for (var i = 0; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + data[i].stud_id + "</td>");
tr.append("<td>" + data[i].stud_name + "</td>");
tr.append("<td><input id='one'></td>");
tr.append("<td><input id='two'></td>");
tr.append("<td><input id='three'></td>");
tr.append("<td>" + data[i].E_id + "</td>");
$('table').append(tr);
}
alert(r + "=== record(s) inserted." + data);
}
});
});
$("body").on("click", "#savebtn", function () {
var marks = new Array();
$("#tableId TBODY TR").each(function () {
{
alert("filled row")
var row = $(this);
var details = {};
details.DATE = date;
details.One_marks = row.find("TD").eq(2).html();
details.Two_marks = row.find("TD").eq(3).html();
details.Three_marks = row.find("TD").eq(4).html();
details.Eid = row.find("TD").eq(5).html();
details.Contest_id = val;
marks.push(details);
}
});
//Send the JSON array to Controller using AJAX.\
var data = JSON.stringify({
'judges': marks,
'val': val
});
alert(data);
$.ajax({
type: "POST",
url: "/Contest_judge/InsertJudge",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + "=== record(s) inserted." + data);
}
});
});
</script>
Note: order of data in Json Array should be following
Date,one(or One_marks),two(or Two_marks),three(or Three_marks),Eid
because I have to insert the whole row as a object in database from controller so the order of column elements for each row in json array matter
Based on your sample, I wasn't sure if you were labeling your inputs, so this example has no-name inputs, but inherits their context from the header row.
$("body").on("click", "#savebtn", function() {
var marks = new Array();
$("#tableId tbody tr").each(function() {
let mark = {
Eid: $(this).find('td').eq(5).text(),
DATE: 'date',
Contest_id: 'val'
}
let empty = true;
$(this).find('td').each(function(i, o) {
if ($(o).find('input').length > 0 && $(o).find('input').eq(0).val().trim() !== '') {
mark[$("#tableId thead th").eq(i).text()] = $(o).find('input').eq(0).val();
empty = false;
}
})
if (!empty) marks.push(mark);
});
//Send the JSON array to Controller using AJAX.\
var data = JSON.stringify({
'judges': marks,
'val': 'val'
});
console.log(data)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tableId" class="table table-bordered table-condensed table-hover table-striped">
<thead>
<tr>
<th>Student_id</th>
<th>Name</th>
<th>Did he perform well</th>
<th>According to Criteria</th>
<th>To the point</th>
<th>EID</th>
</tr>
</thead>
<tbody>
<tr>
<td>123</td>
<td>abc</td>
<td><input/></td>
<td><input /></td>
<td><input /></td>
<td>111</td>
</tr>
<tr>
<td>223</td>
<td>abc</td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td>222</td>
</tr>
<tr>
<td>323</td>
<td>abc</td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td>333</td>
</tr>
</tbody>
</table>
<button id='savebtn'>save</button>
Need to prevent the user from entering more than the existing quantity. It should check the total quantities entered on change event as well as on submit click.
For example, the first row(Part 1) has 50 quantities when the user is adding rows and the total quantities entered against "Part 1" should not exceed 50 and a text should display above the row. Any help would be appreciated.
HTML:
<form name="req" method="post">
<table id="exampleTbl">
<tr>
<td>Part 1</td>
<td><input type="number" name="quantity" value="50"></td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
<tr>
<td>Part 2</td>
<td><input type="number" name="quantity" value="100"></td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
</table>
<input type="submit" name="Submit" value="Submit">
</form>
Jquery:
$(function() {
$('#exampleTbl').delegate('button.addRow', 'click', function() {
var row = $(this).closest('tr'); // get the parent row of the clicked button
var html = $(this).closest('tr').clone();
$(html).insertAfter(row); // insert content
let btn = $('Remove');
btn.click(function () {
$(html).remove(); // Remove row on click
})
$(html).find('.addRow').replaceWith(btn);
});
});
In below code snippet i have given class to your trs to differentiate them with original quantity and the quantity which user can change . Also , whenever user will change input then we need find sum of all quantity of Part 1 or Part 2 .So , i have use tr class which will have either Part 1 or Part 2 to iterate over trs input .
Demo Code :
$(function() {
$('#exampleTbl').delegate('button.addRow', 'click', function() {
var row = $(this).closest('tr'); // get the parent row of the clicked button
var html = $(this).closest('tr').clone();
$(html).insertAfter(row); // insert content
let btn = $('Remove');
btn.click(function() {
$(html).remove(); // Remove row on click
})
$(html).find('.addRow').replaceWith(btn);
});
});
$(document).on("change", "input", function() {
var sum = 0;
$(".total_qty_entered").remove(); //remove div
var name = $(this).closest('tr').attr('class'); //get class
//get original quantity
var qty = $("." + name + "_original").find('td:eq(2)').text();
//loop through tr with same class > inputs
$("." + name + " input[name=quantity]").each(function() {
sum += +$(this).val();
});
console.log("Quantity : " + qty + " | Sum : " + sum)
if (sum > qty) {
$(this).before('<div class="alert alert-danger total_qty_entered" role="alert">Total Quantity should not exceed ' + qty + '</div>');
}
});
//call when on submit
function mySubmitFunction(e) {
//e.preventDefault();
var result = true;
$("tr[data-value ='original']").each(function() {
var name = $(this).find('td:eq(0)').text();
var qty = $(this).find('td:eq(2)').text();
var new_name = name.replace(/\s/g, '');
var sum = 0;
$("." + new_name + " input[name=quantity]").each(function() {
sum += +$(this).val();
});
console.log("Name : " +name+ " Sum : "+sum + " || Qty : " + qty)
if (sum > qty) {
//do something
alert("please check quanity is greater for "+name)
result = false;
}
});
return result;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="req" method="post" onsubmit="return mySubmitFunction(event)">
<table id="exampleTbl">
<!--added this class-->
<tr data-value="original" class="Part1_original">
<td>Part 1 </td>
<td>Original Quantity : </td>
<td>50</td>
</tr>
<!--added this class-->
<tr class="Part1">
<td>Part 1</td>
<td><input type="number" name="quantity" value="50"></td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
<tr data-value="original" class="Part2_original">
<td>Part 2</td>
<td>Original Quantity : </td>
<td>100</td>
</tr>
<tr class="Part2">
<td>Part 2</td>
<td><input type="number" name="quantity" value="100"></td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
</table>
<input type="submit" name="Submit" value="Submit">
</form>
Update 1 :
You can give class to your input so that it can use in each to iterate over the inputs having same class and check if against the total quantity .
Demo code :
$(function() {
$('#exampleTbl').delegate('button.addRow', 'click', function() {
var row = $(this).closest('tr'); // get the parent row of the clicked button
var html = $(this).closest('tr').clone();
$(html).insertAfter(row); // insert content
let btn = $('Remove');
btn.click(function() {
$(html).remove(); // Remove row on click
})
$(html).find('.addRow').replaceWith(btn);
});
});
$(document).on("change", "input", function() {
var sum = 0;
//get total quantity
var qty = $(this).closest('td').next('td').text(); //get class
var name = $(this).attr('class'); //get class
//loop through tr with same class > inputs
$("tr > td input[class=" + name + "]").each(function() {
sum += +$(this).val();
});
$(".total_qty_entered").remove(); //remove div
if (sum > qty) {
$(this).before('<div class="alert alert-danger total_qty_entered" role="alert">Total Quantity should not exceed ' + qty + '</div>');
}
});
//call when on submit
function mySubmitFunction(e) {
//e.preventDefault();
var result = true;
//loop through td input
$("tr > td input").each(function() {
var name = $(this).attr('class');
var qty = $(this).closest('td').next('td').text(); //get class
var sum = 0;
//iterate through all inputs with same class
$("." + name).each(function() {
sum += +$(this).val();
});
if (sum > qty) {
//do something
$(this).before('<div class="alert alert-danger total_qty_entered" role="alert">Total Quantity should not exceed ' + qty + '</div>');
result = false;
}
});
return result;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="req" method="post" onsubmit="return mySubmitFunction(event)">
<table id="exampleTbl">
<tr>
<td>Part 1</td>
<td><input type="number" name="quantity" value="50" class="Part1"></td>
<td>50</td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
<tr>
<td>Part 2</td>
<td><input type="number" name="quantity" value="100" class="Part2"></td>
<td>100</td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
</table>
<input type="submit" name="Submit" value="Submit">
</form>
I have an html table with a checkbox on first column. I would like to highlight the row where checkboxes are checked with knockout.
<table class="defaultGrid">
<thead>
<tr>
<th>Check</th>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: model.Things">
<tr>
<td><input type="checkbox" data-bind="click: $root.selectThing " /></td>
<td data-bind="text: ID"></td>
<td data-bind="text: Name"></td>
</tr>
</tbody>
</table>
Here is an example on jsFiddle: http://jsfiddle.net/jJ4H6/1/
I don't know how to proceed. I don't want to add an extra property on my model like 'isSelected'.
Any idea?
Thanks.
I would definitely add a knockout observable to your 'Thing' that determines whether or not your tr element has a yellow background or not.
However, if you really don't want to add something like this to your view model, you'll have to add some logic to your selectThing function to handle this for you e.g.
self.selectThing = function(item, event) {
$(event.target).parent().parent().addClass('selected');
};
Check out this Jfiddle http://jsfiddle.net/jJ4H6/27/
$(function() {
Thing = function(id, name, selected) {
var self = this;
self.ID = id,
self.Name = name
self.isChecked = ko.observable(false);
};
function viewModel() {
var self = this;
self.model = {};
self.model.CurrentDisplayThing = ko.observable();
self.model.Things = ko.observableArray(
[
new Thing(1, "Thing 1"),
new Thing(2, "Thing 2"),
new Thing(3, "Thing 3")
]);
self.selectThing = function(item) {
};
}
ko.applyBindings(new viewModel());
});