How do I actually retrieve the Primary Key (model.ID) of the selected row from my table. And i want to make same cases if a single row is selected button A B C are enabled but if multiple rows are selected only button c is enabled , a and b will be disabled.
I posted my coding below.
$(document).ready(function () {
var table = $('#LineTables').DataTable();
$('#LineTables tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
}
else {
table.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
});
});
});
<table id="LineTables" class="display dataTable">
<thead>
<tr>
<th>#Html.DisplayNameFor(model => model.Priority)</th>
<th>#Html.DisplayNameFor(model => model.ProductionOrderNumber)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.Product.ProductGroup.Name)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.Product.ProductName)</th>
<th>#Html.DisplayNameFor(model => model.Quantity)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.Product.Pole)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.Product.Amperage)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.SalesOrderType1.Name)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.Market)</th>
<th>#Html.DisplayNameFor(model => model.ProductionOrderStatu.Name)</th>
<th>#Html.DisplayNameFor(model => model.SalesOrder.SalesOrderNumber)</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Priority)</td>
<td>#Html.DisplayFor(modelItem => item.ProductionOrderNumber)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.Product.ProductGroup.Name)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.Product.ProductName)</td>
<td>#Html.DisplayFor(modelItem => item.Quantity)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.Product.Pole)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.Product.Amperage)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.SalesOrderType1.Name)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.Market)</td>
<td>#Html.DisplayFor(modelItem => item.ProductionOrderStatu.Name)</td>
<td>#Html.DisplayFor(modelItem => item.SalesOrder.SalesOrderNumber)</td>
<td>
#Html.ActionLink("New Barcode", "Barcode", new { id = item.ID }, new { #class = "barcode btnic btnicon" })
</td>
</tr>
} </tbody>
</table>
#Html.ActionLink("A", "Index", "A", .......... , new { #class = "btn btn-default btn-ms" })
#Html.ActionLink("B", "Index", "B", .......... , new { #class = "btn btn-default btn-ms" })
#Html.ActionLink("C", "Index", "C", .......... , new { #class = "btn btn-default btn-ms" })
Based comments above:
Firstly you cant use #Html.ActionLink(..) for the 'buttons (these are rendered on the server side and you dont know the selected ID at that point) - use a html <button id="edit">Edit</button>. In the row.click function, test the number of selected rows and enable/disable the buttons as required
var selectedRows = $(this).closest('tbody').children('tr')
.filter('.selected').length;
if (selectedRows = 1) {
// enable edit and details buttons
} else {
// disable edit and details buttons
}
Then in the click events for each button (edit button shown)
$('#edit').click(function() {
var ID = $(this).find('input[type="hidden"]').val(); // as per first answer
window.location.href = '/yourController/edit/' + ID;
return false;
});
The delete button will be a little more complicated - one way would be to loop the selected rows, get the ID and use AJAX to post the ID to your 'Delete' action method, then in the success function, delete the row from your table, for example (not tested)
var url = "#Url.Action("Delete")"; // your delete action
$('#delete').click(function() {
$('#LineTables').children('tbody').children('tr')
.filter('.selected').each(function) {
var row = $(this);
var ID = row.find('input[type="hidden"]').val();
$.post(url, { ID = ID }, function() {
row.remove();
});
Related
I'm having a problem in retrieving only the ids of the selected row via a checkbox in my table where the elements are dynamically created.
In the code below I have put only the one of interest.
Specifically I get the following error:
Cannot read properties of null (reading 'textContent')
.
.
.
let child = document.createElement("tr");
child.innerHTML = `
<td>${item.id}</td>
<td><img src=articoli_img/${item.image} width="150" heigth="150"></td>
td>${item.date}</td>
<td>${'<input type="checkbox" id="myCheck">'}</td>`;
table.appendChild(child);
})
}
};
function retrieveID() {
var cbs = document.querySelectorAll('#my-table input[type="checkbox"]:checked');
console.log(cbs.length);
const ids = Array.from(cbs).map(cb => cb.closest('td').nextElementSibling.textContent);
console.log(ids);
}
<table id="my-table" width="90%">
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</table>
<br><br>
<input type="button" value="GetID" onclick="retrieveID()" />
Can you kindly help me?
You can simply store the id in a attribute of the checkbox:
child.innerHTML = `... <td>${`<input type="checkbox" id="myCheck" data-item-id="${item.id}">`}</td>`;
// ...
const ids = Array.from(cbs).map((cb) => cb.getAttribute("data-item-id"));
which will make your code look like this:
let table = document.getElementById("my-table");
const Items = [
{
id: 1,
image: "test1.jpg",
date: "2020-01-01",
},
{
id: 2,
image: "test2.jpg",
date: "2020-01-02",
},
{
id: 3,
image: "test3.jpg",
date: "2020-01-03",
},
];
Items.forEach(function (item) {
let child = document.createElement("tr");
child.innerHTML = `
<td>${item.id}</td>
<td><img src="articoli_img/${item.image}" width="150" heigth="150"></td>
td>${item.date}</td>
<td>${`<input type="checkbox" id="myCheck" data-item-id="${item.id}">`}</td>`;
table.appendChild(child);
});
function retrieveID() {
var cbs = document.querySelectorAll(
'#my-table input[type="checkbox"]:checked'
);
console.log(cbs.length);
const ids = Array.from(cbs).map((cb) => cb.getAttribute("data-item-id"));
console.log(ids);
}
<table id="my-table" width="90%">
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</table>
<br><br>
<input type="button" value="GetID" onclick="retrieveID()" />
You have a lot of small errors in your code. i have rewritten your code a little bit. so that you are able to read out the clicked rows. you can then pull the data from the tr element yourself.
let table = document.getElementById("my-table");
let allart = [];
allart['Items'] = [{id: 1, image: 'xx', date: 2022}]
console.log(allart['Items'][0].id)
allart.Items.forEach(function(item) {
let child = document.createElement("tr");
child.setAttribute("id", "data-" +item.id);
child.innerHTML = `
<td>${item.id}</td>
<td><img src=articoli_img/${item.image} width="150" heigth="150"></td>
<td>${item.date}</td>
<td><input type="checkbox" data-ref="${item.id}" id="myCheck"></td>`;
table.appendChild(child);
})
//xmlhttp.open("GET", url, true);
//xmlhttp.send();
function retrieveID() {
var cbs = document.querySelectorAll('#my-table input[type="checkbox"]:checked');
console.log(cbs.length);
console.log(cbs[0])
let col = [];
cbs.forEach(c => {
let id = c.getAttribute('data-ref');
let data = document.querySelector('#data-' + id)
console.log(data)
// do something
})
}
<table id="my-table" width="90%">
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</table>
<br><br>
<input type="button" value="GetID" onclick="retrieveID()" />
I would suggest that you rework your solution somewhat: do not use the selected state directly from the DOM (HTML). Instead, update the dataset based on an event handler that reacts to some user event.
The snippet below does this:
stores the checked state in the Items
the checked state is updated when the checkbox change event fires
when you get the IDs, it's simply a filter of the Items array.
Also, I updated your example as there were some errors.
const table = document.querySelector("#my-table tbody");
const btnGetId = document.getElementById('get-id')
/*.
.
.*/
const allart = {
Items: [{
id: 'id1',
image: 'fakeImage1',
date: Date.now(),
checked: false,
},
{
id: 'id2',
image: 'fakeImage2',
date: Date.now(),
checked: false,
},
],
}
allart.Items.forEach(function(item) {
let child = document.createElement("tr");
child.innerHTML = `
<td>${item.id}</td>
<td><img src="articoli_img/${item.image}" width="150" heigth="150"></td>
<td>${item.date}</td>
<td><input type="checkbox" data-itemid="${item.id}"/></td>`;
table.appendChild(child);
})
// }
// };
// reacting to selection
const updateChecked = (id, items) => {
return items.map(item => {
if (id === item.id) {
return {
...item,
checked: !item.checked
}
}
return item
})
}
// adding event handlers to the checkboxes
const cbs = document.querySelectorAll('tr input[type="checkbox"]')
cbs.forEach(cb => {
cb.addEventListener('change', function(e) {
const id = e.target.getAttribute("data-itemid")
allart.Items = updateChecked(id, allart.Items)
})
})
// xmlhttp.open("GET", url, true);
// xmlhttp.send();
// updating the event handler on GetId click
btnGetId.addEventListener('click', function() {
const selectedItems = retrieveId(allart.Items)
// here you have the items that are selected
// you can use all the data it has
console.log(selectedItems)
})
// returning the items that are selected
function retrieveId(items) {
return items.filter(({ checked }) => checked)
}
<table id="my-table" width="90%">
<thead>
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</thead>
<tbody></tbody>
</table>
<br><br>
<input id="get-id" type="button" value="GetID" />
I build this code for select all checboxes and pass to controller, I using button when click it check all checkboxes and pick up all variables like (idtip, idemployee) trought array send to controller to update database table.
<tr>
<th>name</th>
<th>tips</th>
<th>
<button id="btnClick" class="btnClick">Select all</button>
</th>
</tr>
Here is my input and script.
#foreach (var item in (IEnumerable<cit.Models.getCheIdTip_Result>)Model)
{
<tr>
<td>#item.idtip</td>
<td>#item.tipname</td>
<td>
<div class="pure-checkbox" idtip="#item.idtip">
<input type="checkbox" idtip="#item.idtip" class="checktip"
checked="#(item.idemployee == ViewBag.idemployee ? true : false)"
name="#item.id.ToString()" id="#item.id.ToString()" />
<label for="#item.id.ToString()"></label>
</div>
</td>
</tr>
}
</table>
<input type="hidden" value="#ViewData["idemployee"]" name="idemployee" id="idemployee" class="idemployee" />
<script>
$('.pure-checkbox').click(function () {
$(this).parents('td').toggleClass('chked')
})
var wantedids = [idemployee,idtip]
$("#btnClick").click(function () {
for (var i = 0; i < $('.pure-checkbox').length; i++) {
if ($('.pure-checkbox').eq(i).parents('td').hasClass('chked')) {
wantedids.push(
$('.pure-checkbox').eq(i).attr('idtip')
)
}
}
$.post("UrlSettingsDocument.Tips", { ids: wantedids },
)
})
I using button when click it check all checkboxes and pick up all
variables like (idtip, idemployee) trought array send to controller to
update database table.
You could refer the following sample code:
Create a ViewModel to display records:
public class TestViewModel
{
public int id { get; set; }
public int idtip { get; set; }
public string idemployee { get; set; }
public bool isChecked { get; set; }
}
In the Controller, add the following actions:
//Set the initial data and return to view.
public IActionResult Default()
{
List<TestViewModel> items = new List<TestViewModel>()
{
new TestViewModel(){ id=101, idtip=1001, idemployee="AAA" },
new TestViewModel(){id=102,idtip=1002, idemployee="BBB" },
new TestViewModel(){id=103, idtip=1003, idemployee="CCC" },
new TestViewModel(){ id=104,idtip=1004, idemployee="DDD" },
new TestViewModel(){id=105, idtip=1005, idemployee="EEE" }
};
ViewBag.idemployee = "CCC"; //set the default checked item.
return View(items);
}
public IActionResult AddItems(IEnumerable<TestViewModel> items)
{
//insert the items into database.
return Ok("OK");
}
Then, in the View page (Default.cshtml), using the following code to display the content:
Here we can use a select all checkbox, after checking it, will select all items.
#model IEnumerable<WebApplication.Models.TestViewModel>
#{
ViewData["Title"] = "Default";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table class="table">
<thead>
<tr>
<th>
<input type="checkbox" id="btnSelectAll" class="btnClick" /> <label for="btnSelectAll">Select All</label>
</th>
<th>
#Html.DisplayNameFor(model => model.idtip)
</th>
<th>
#Html.DisplayNameFor(model => model.idemployee)
</th>
<th>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
<div class="pure-checkbox" idtip="#item.idtip">
<input type="checkbox" idtip="#item.idtip" data-idemployee="#item.idemployee" class="checktip"
checked="#(item.idemployee == ViewBag.idemployee ? true : false)"
name="#item.id.ToString()" id="#item.id.ToString()" />
<label for="#item.id.ToString()"></label>
</div>
</td>
<td>
#Html.DisplayFor(modelItem => item.idtip)
</td>
<td>
#Html.DisplayFor(modelItem => item.idemployee)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>
<button id="btnSubmit" class="btnClick">Submit</button>
At the end of the Default.cshtml page, using the following script to achieve the select all function and submit the records to the controller.
#section Scripts{
<script>
$(function () {
//If checked the select all checkbox, select all items. else unchecked.
$("#btnSelectAll").click(function () {
if ($(this).is(":checked")) {
$(".checktip").each(function (index, item) {
$(item).prop("checked", true);
});
}
else {
$(".checktip").each(function (index, item) {
$(item).prop("checked", false);
});
}
});
$("#btnSubmit").click(function () {
var testViewModels = [];
//using the class selector to loop through the checkbox list and get all items, if you want to get the checked items, add an if...else statement in the each function.
$(".checktip").each(function (index, item) {
var TestViewModel = {};
TestViewModel.idtip = $(this).attr("idtip");
TestViewModel.idemployee = $(this).attr("data-idemployee");
TestViewModel.isChecked = $(this).is(":checked");
testViewModels.push(TestViewModel);
});
$.ajax({
type: "Post",
url: "/Home/AddItems", //remember change the controller to your owns.
data: { items: testViewModels }, //the name ("items") should be the same with the parameter's name in the controller.
success: function (data) {
console.log(data)
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
</script>
}
The result as below:
On clicking the retire user checkbox I am triggering the form submit for ("RetireUser", "Users")
My script is navigating to /Users/RetireUser but I need to pass the Id parameter.
Didn't have much luck with ajax
Thanks in advance for the help
#foreach (var item in UsersModel)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Username)</td>
<td>#Html.DisplayFor(modelItem => item.FirstName)</td>
<td>#Html.DisplayFor(modelItem => item.LastName)</td>
<td>#Html.DisplayFor(modelItem => item.Email)</td>
<td>#Html.DisplayFor(modelItem => item.Phone)</td>
<td>#Html.DisplayFor(modelItem => item.Status)</td>
<td>#Html.DisplayFor(modelItem => item.DateRetired)</td>
<td>#Html.DisplayFor(modelItem => item.DateAdded)</td>
#using (Html.BeginForm("RetireUser", "Users", FormMethod.Post, new { role = "form", id="retire_user" }))
{
<td>#Html.CheckBoxFor(modelItem => item.RetireUser)</td>
}
<td>Edit</td>
</tr>
}
<script>
$('#item_RetireUser').click(function () {
$('#retire_user').submit();
});
the html
the script
if it's a html why not give each a id i.e here 12 is user_id and with the help of jquery you can retrieve and send that id via ajax or normal url call.
I am working on a Table Row filtering script.
Initially, the all table rows are visible, but after manipulating some dropdowns / forms the filter criteria dictate which rows are going to be visible and which not. Example:
var jobs = [{
id: 0,
company: "Google",
location: "Zurich"
}, {
id: 1,
company: "Facebook",
location: "Ireland"
}];
// this function isn't run in this example for reasons of brevity. it's to show how the jobs array is generated
const filterRow = function (data, filters) {
let filtersEnabled = Object.keys(filters).filter(element => filters[element].length !== 0);
return data.filter(row => {
return filtersEnabled.every(k => {
return filters[k].indexOf(row[k]) !== -1
})
})
}
let $tableRows = $('table tbody tr');
const updateDisplay = function() {
// that's not ideal
$tableRows.addClass('hidden')
jobs.forEach((row) => {
$(`[data-id="${row.id}"]`).removeClass('hidden')
})
}
$('.js-filter').on('click', () => updateDisplay())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<button class="js-filter">filter table now</button>
<table class="table table-bordered">
<tbody>
<tr data-company="google" data-id="0" data-loation="zurich">
<td>Google</td>
<td>Zurich</td>
<td>0</td>
</tr>
<tr data-company="facebook" data-id="1" data-loation="ireland">
<td>Facebook</td>
<td>Ireland</td>
<td>1</td>
</tr>
<tr data-company="microsoft" data-id="2" data-loation="california">
<td>microsoft</td>
<td>California</td>
<td>2</td>
</tr>
</tbody>
</table>
The jobs array determines which rows are going to be visible. (so in this particular case, only rows with id 0 and 1 are going to be visible.
Given that the jobs array is changing programmatically, I would like a jQuery (or other) way to directly hide the rows with ID not present in the array (thus being able to use animate.css to fade rows out etc.
What I currently do is
hiding all rows,
then showing the ones in the array. That's rather a workaround and it complicates my transitions/animations.
You can use the jQuery .filter() method to iterate over the rows and filter them.
On each iteration you can check to see if the row's data-id attribute is found in the jobs array by using the .some() method. From there, you can return the boolean and filter out rows that have an id that matches an object in the jobs array.
$rows.filter((index, row) => {
return !jobs.some(job => job.id === +row.dataset.id);
}).addClass('hidden');
Alternatively, you could also use the jQuery .not() method in place of .filter():
$rows.not((index, row) => {
return jobs.some(job => job.id === +row.dataset.id);
}).addClass('hidden');
Or if you want to break isJobById into another function:
const isJobById = id => jobs.some(job => job.id === +id);
const updateDisplay = () => {
$rows.not((i, row) => isJobById(row.dataset.id)).addClass('hidden');
}
You can also change the following line:
$('.js-filter').on('click', () => updateDisplay());
.. and pass the updateDisplay function directly:
$('.js-filter').on('click', updateDisplay);
Full snippet:
var jobs = [{
id: 0,
company: "Google",
location: "Zurich"
}, {
id: 1,
company: "Facebook",
location: "Ireland"
}];
let $rows = $('table tbody tr');
const isJobById = id => jobs.some(job => job.id === +id);
const updateDisplay = () => {
$rows.not((i, row) => isJobById(row.dataset.id)).addClass('hidden');
}
$('.js-filter').on('click', updateDisplay);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<button class="js-filter">filter table now</button>
<table class="table table-bordered">
<tbody>
<tr data-company="google" data-id="0" data-loation="zurich">
<td>Google</td>
<td>Zurich</td>
<td>0</td>
</tr>
<tr data-company="facebook" data-id="1" data-loation="ireland">
<td>Facebook</td>
<td>Ireland</td>
<td>1</td>
</tr>
<tr data-company="microsoft" data-id="2" data-loation="california">
<td>microsoft</td>
<td>California</td>
<td>2</td>
</tr>
</tbody>
</table>
I am using asp.net MVC 5.
In Bootbox js
$(document).on("click", ".MyLink", function (e) {
bootbox.confirm("Are you sure?", function(result) {
Example.show("Confirm result: "+result);
});
});
#Html.ActionLink("Delete", "Delete", new { id = item.CustomerID }, new { #class = "MyLink" })
How to delete the HTML action link ?
Please find the full details of the code:-
Javascript code:-
<script src="~/Scripts/bootbox.min.js"></script>
$(document).on("click", ".MyLink", function (e) {
var self = this;
bootbox.confirm("Are you sure?", function (result) {
Example.show("Confirm result: " + result);
$(self).remove();
});
});
HTML Code:-
<h2>Index</h2>
<p>Content here. <a class="MyLink" href=#>Alert!</a></p>
<p>
#Html.ActionLink("Create New", "Create")
</p>
Also see the inside<table> code for your
reference:-
<table class="table">
<tr>
<th> First Name </th>
<th> Last Name </th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td> #Html.DisplayFor(modelItem => item.FirstName) </td>
<td> #Html.DisplayFor(modelItem => item.LastName) </td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.CustomerID }) |
#Html.ActionLink("Details", "Details", new { id = item.CustomerID }) |
#*#Html.ActionLink("Delete", "Delete", new { id = item.CustomerID, #class = "MyLink" })*#
Delete
</td>
</tr>
}
Also see the Controller code for your reference:-
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
db.Customers.Remove(customer);
db.SaveChanges();
if (customer == null)
{
return HttpNotFound();
}
return RedirectToAction("Index");
//return View(customer);
}