Edit inline in table in index view - javascript

I use the following code to display the table rows
for every row there is edit and delete button ,what i want to do is
when I click on edit for specific row change the row from display only
to editable row (instead of navigating to other page for edit),how should I do that?
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
<th>
#Html.DisplayNameFor(model => model.checkBox1)
</th>
<th></th>
</tr>
<tbody id="data-table">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.checkBox1)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</tbody>
This is how the table look like
Ive try to change the code to something like this but I got following errors:
<tbody id="data-table">
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
if (Model[i].Id == ViewBag.SelectedID)
{
<td>
#Html.EditorFor(model=> model[i].name)
</td>
<td>
#Html.EditorFor(m=> m[i].checkBox1)
</td>
<td>
<button type="submit" name="submit" value="save">Save</button>
<button type="submit" name="submit" value="cancel">Cancel</button>
</td>
}
}
else
{
<td>
#Html.DisplayFor(m => m[i].name)
</td>
<td>
#Html.DisplayFor(m=> m[i].checkBox1)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = Model[i].Id }) |
#Html.ActionLink("Delete", "Delete", new { id = Model.Id })
</td>
}
</tr>
}
The error is in statments:
#Html.EditorFor(m => m[i].name) and
#Html.EditorFor(m=> m[i]checkBox1)
try specifing the arguments explicitly,any idea?

Try with the following code
Below function make row editable
var nCurrentEdit = 0;
$('#data-table').on('click', '.btnCustomEdit', function () {
nCurrentEdit = $(this).attr("id");
var oTR = $(this).parents("tr").first();
var sText = '<input type="text" value="' + oTR.find("td:nth-child(1)").text().trim() + '" />';
oTR.find("td:nth-child(1)").html(sText);
oTR.find(":disabled").prop("disabled", false);
if (oTR.find("#btnsubmit").length == 0)
oTR.find("td:last").append("<input id='btnUpdate' type='submit' value='Update' class='btn btn-default'>");
oTR.find("td:last a").hide();
event.preventDefault();
});
Following function update the record and convert the row normal from editable mode.
$('#data-table').on('click', '#btnUpdate', function () {
var postData = {
id : nCurrentEdit,
name: $("#name").val(),
checkBox1: $("#checkBox1").val(),
checkBox2: $("#checkBox2").val(),
checkBox3: $("#checkBox3").val()
};
$.post('#Url.Action("AjaxEdit", "Roles")', postData, null);
var sNewText = $(this).parents("tr").first().find("td:first input").val();
$(this).parents("tr").first().find("td:first").append(sNewText);
$(this).parents("tr").first().find("td:first input").remove();
$(this).parents("tr").find("input[type=checkbox]").prop("disabled", true);
$(this).parent().find("a").show();
$(this).hide();
});

You could maybe use jEditable http://www.appelsiini.net/projects/jeditable and intagrate it with your table.
Maybe you can use DataTables too with jEditable if it's fits your project, something like http://datatables.net/release-datatables/examples/server_side/editable.html

Related

How to do calculation where a value has to be entered in a row for each row of table using Razor Pages and JavaScript?

I have a table for product data and the user can enter the amount of a product to buy in each row.
I would like to compute the total price per product in each row and then the total price of the whole purchase below the table.
This is my table:
<table id="productTable">
<thead>
<tr>
<th>Amount</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].Price)
</th>
<th>Total</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Products)
{
<tr>
<td>
<input type="number" id="quantityInput" onchange="calcSubTotal()" min="0" value="0" />
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td id="priceLabel">
#Html.DisplayFor(modelItem => item.Price)
</td>
<td id="labelSubTotal"></td>
</tr>
}
</tbody>
The items are coming from the model (IList). I want to multiply the entered value of the input (type number) and the price of the corressponding row using JavaScript.
In JavaScript I am using getElementById to access the UI-Elements. How I can access the row of the table where the focus of the HTML-Input is?
My JavaScript:
<script type="text/javascript">
function calcSubTotal() {
var numberInput = document.getElementById('quantityInput');
var val = numberInput.value;
var amount = parseFloat(val);
var priceLabel = document.getElementById('priceLabel');
var priceValue = priceLabel.innerText;
var price = parseFloat(priceValue);
var totalPrice = amount * price;
var subTotalLabel = document.getElementById('labelSubTotal');
subTotalLabel.innerText = totalPrice.toString();
}
</script>
It may work if only have one record.But you have several raws of record.Each id of Price and Total are the same.You need to distinguish the id like below:
<table id="productTable">
//..
<tbody>
#{
int i = 0; //add this..
}
#foreach (var item in Model.Products)
{
<tr>
<td>
//change the onchange function...
<input type="number" id="quantityInput" onchange="calcSubTotal(this,#i)" min="0" value="0" />
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td id="priceLabel_#i"> //change here...
#Html.DisplayFor(modelItem => item.Price)
</td>
<td id="labelSubTotal_#i"></td> //change here...
</tr>
i++; //add this....
}
</tbody>
</table>
#section Scripts
{
<script type="text/javascript">
function calcSubTotal(element,index) {
var numberInput = $(element).val();
var amount = parseFloat(numberInput);
var priceLabel = document.getElementById('priceLabel_'+index);
var priceValue = priceLabel.innerText;
var price = parseFloat(priceValue);
var totalPrice = amount * price;
var subTotalLabel = document.getElementById('labelSubTotal_'+index);
subTotalLabel.innerText = totalPrice.toString();
}
</script>
}
Result:

Show/Hide divs in JQuery for items in a ForLoop

I am attempting to change my DisplayFor to an EditorFor when the checkbox is clicked, I'm not sure if theres a better way that I could've done this change but if you have any suggestions I'm open to them. But anyways, with the way I did it, it is only doing the JQuery for the first part in my ForLoop and I am not sure how to make it to apply to all the parts in the list. As right now it is displaying both the displayFor and the editorFor.
I have rows that are generated like this
#for (int i = 0; i < item.IHP.Count; i++)
{
Part part = db.Parts.Find(Model.Parts[i].ID);
#Html.HiddenFor(x => x.Parts[i].ID)
<tr class="tr_clone">
<td>
#part.PartIDLink
</td>
<td>
#Html.DisplayFor(x => x.Parts[i].PartName)
#Html.HiddenFor(x => x.Parts[i].PartName)
</td>
<td style="font-weight:bold">
#Html.DisplayFor(x => x.Parts[i].QtyInItem)
#Html.HiddenFor(x => x.Parts[i].QtyInItem)
</td>
<td>
<input type="checkbox" id="all#(part.ID)" class="part-class" data-partId="#(part.ID)" checked>
</td>
<td>
<div class="AllTxt">
#Html.DisplayFor(x => x.Parts[i].QtyInItem)
</div>
<div class="editQty">
#Html.EditorFor(x => x.Parts[i].Qty)
</div>
</td>
#foreach (var actionType in partActionTypes)
{
<td>
#Html.RadioButtonFor(x => x.Parts[i].SelectedActionType, actionType, new { name = "partRadio" })
</td>
}
</tr>
My Jquery code looks like this
<script>
$(document).ready(function () {
//iterate through checkboxs
$(" input[type='checkbox']").each(function () {
//if checkbox is checked
if ($(this).is(':checked')) {
//show alltext div
$(this).closest('.tr_clone').find(".AllTxt").show();
//hide other div
$(this).closest('.tr_clone').find(".editQty").hide();
} else {
$(this).closest('.tr_clone').find(".editQty").show();
$(this).closest('.tr_clone').find(".AllTxt").hide();
}
});
});
$(document).ready(function () {
$('.tr_clone input.part-class').change(function () {
let Id = $(this).attr('id');
let partId = $(this).attr('data-partId');
//getting closest tr
var selector = $(this).closest('.tr_clone');
if ($(this).prop("checked") == true){
// remove cloned row
$('#' + Id + 'clone').remove();
selector.find(".AllTxt").show();
selector.find(".editQty").hide();
}
else {
var $tr = $(this).closest('.tr_clone');
var $clone = $tr.clone();
$clone.find('td');
$tr.after($clone);
$($clone).find(".part-class").hide();
$clone.find('input[type="radio"]').attr("name", (i, n) => n + 'clone');
$clone.attr('id', (Id) + "clone");
selector.find(".AllTxt").hide();
selector.find(".editQty").show();
}
});
});
</script>
But it only does this for the the first part in the ForLoop. How can I make it so that it applies it to every part in the for loop?
You have given id to your div instead use class here and whenever any checkbox is checked use $(this).closest('.tr_clone') and using this we can hide or show div of required tr only .
Demo Code ( I have removed some code and added dummy data to it ) :
$(document).ready(function() {
//iterate through checkboxs
$(" input[type='checkbox']").each(function() {
//if checkox is checked
if ($(this).is(':checked')) {
//show alltext div
$(this).closest('.tr_clone').find(".AllTxt").hide();
//hide other div
$(this).closest('.tr_clone').find(".editQty").show();
} else {
$(this).closest('.tr_clone').find(".editQty").hide();
$(this).closest('.tr_clone').find(".AllTxt").show();
}
});
$('.tr_clone input.part-class').change(function() {
let Id = $(this).attr('id');
let partId = $(this).attr('data-partId');
//getting closest tr
var selector = $(this).closest('.tr_clone');
//if checkbox is checked
if ($(this).prop("checked") == true) {
///find divand show or hide
selector.find(".AllTxt").show();
selector.find(".editQty").hide();
} else {
selector.find(".AllTxt").hide();
selector.find(".editQty").show();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="tr_clone">
<td>
#part.PartIDLink
</td>
<td>
PartName
</td>
<td style="font-weight:bold">
QtyInItem
</td>
<td>
<input type="checkbox" id="1" class="part-class" data-partId="1" checked>
</td>
<td>
<!---added class instead of id-->
<div class="AllTxt">
SomethingAll
</div>
<div class="editQty">
SomethingQty
</div>
</td>
</tr>
<tr class="tr_clone">
<td>
#part.PartIDLink
</td>
<td>
PartName
</td>
<td style="font-weight:bold">
QtyInItem
</td>
<td>
<input type="checkbox" id="2" class="part-class" data-partId="2">
</td>
<td>
<div class="AllTxt">
SomethingAll
</div>
<div class="editQty">
SomethingQty
</div>
</td>
</tr>
</table>

how to get a value from textbox and pass it from actionlink to controller

I'm working on an ASP.NET MVC application and i need to pass TextBox value from view to controller this TextBox is in table and i need get the input value.
#foreach (var item in Model)
{
<tr class="odd gradeX">
<td>
#Html.DisplayFor(modelItem => item.Product.ProductName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Product.Reference)
</td>
<td>
#Html.TextBoxFor(modelItem => item.QuantityWanted, new { style = "width:60%", type = "number", min = "0", step = "1", max = item.Quantity })
#Html.ActionLink("Add", "Add", new { idProduct = item.ProductID, idUser = item.UserID, quantityWanted= item.QuantityWanted })
</td>
</tr>
}
I used javascript and jquery but i didn't get anything and quantityWanted always returns null or 0 value.
I think you want code like this:
#foreach (var item in Model)
{
<tr class="odd gradeX">
<td>
#Html.DisplayFor(modelItem => item.Product.ProductName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Product.Reference)
</td>
<td>
<input type="number" id="Quantity#item.ProductID" data-idUser = "#item.UserID" style="width:60%" min="0" step="1" max="#item.Quantity"/>
<button click="AddItem(#item.ProductID)">Click to add</button>
</td>
</tr>
}
<script>
function AddItem(id){
var quantity = $('Quantity' + id).val();
window.location = "/Add/Add?idProduct" + id + "&idUser=" + $('Quantity' + id).data("idUser") + "&quantityWanted=" + quantity;
}
</script>

Display Details for Individual Items inside Tooltip on Mouse Hover

I am trying to display the details within a tooltip for each item in my index view. I would like the tooltip to appear when the mouse hovers over an items name. Currently I have some javascript and an view to go along with it. Any help or recommendations would be greatly appreciated!
Details Javascript:
$(document).load(function () {
for (var count = 0; count < 10; count++) {
$(document).tooltip({
items: "#j" + count,
content: function () {
return $("#i" + count).text();
}
});
};
});
Index View:
<table class="table">
<tr>
<th>
#Html.ActionLink("Software Name", "Index", new { sortOrder = ViewBag.SoftNameSort, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("License Type", "Index", new { sortOrder = ViewBag.LicenseType, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("End Date", "Index", new { sortOrder = ViewBag.EndDateSort, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<noscript id="i#(count)">#Html.Partial("_SoftwareDetails", (WBLA.Models.SoftwareLicense)item)</noscript>
<td id="j#(count)">
#Html.DisplayFor(modelItem => item.SoftwareName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LicenseType)
</td>
<td>
#Html.DisplayFor(modelItem => item.EndDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.SoftwareID }) |
#Html.ActionLink("Details", "Details", new { id = item.SoftwareID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.SoftwareID })
</td>
</tr>
count++;
}
</table>
** EDIT **
I forgot to mention what I would like to show inside the tooltip. I would like to load a partial, which displays the relevant information for each item in my index view.
Partial Details View:
#model WBLA.Models.SoftwareLicense
<table>
<tr>
<th>
#Html.LabelFor(model => model.SoftwareName)
</th>
<td>
#Html.DisplayFor(model => model.SoftwareName)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.SoftwareKey)
</th>
<td>
#Html.DisplayFor(model => model.SoftwareKey)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.Price)
</th>
<td>
#Html.DisplayFor(model => model.Price)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.DepartmentName)
</th>
<td>
#Html.DisplayFor(model => model.DepartmentName)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.LicenseFilePath)
</th>
<td>
#Html.DisplayFor(model => model.LicenseFilePath)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.LicenseType)
</th>
<td>
#Html.DisplayFor(model => model.LicenseType)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.StartDate)
</th>
<td>
#Html.DisplayFor(model => model.StartDate)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.EndDate)
</th>
<td>
#Html.DisplayFor(model => model.EndDate)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.NotifyTime)
</th>
<td>
#Html.DisplayFor(model => model.NotifyTime)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.ConsumerEmail)
</th>
<td>
#Html.DisplayFor(model => model.ConsumerEmail)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(model => model.EntryEmail)
</th>
<td>
#Html.DisplayFor(model => model.EntryEmail)
</td>
</tr>
</table>
* EDIT 8/03/2016 *
The title for the tooltip-tagged displays, however, my partial will not load within the tooltip.
Updated SoftwareDetails.js:
$(function () {
var url = '#Url.RouteUrl(new{ action="SoftwareDetails", controller="SoftwareLicense"})';
$(document).tooltip({
items: "td.myToolTips",
content: function (callback) {
$.get(url + "?id=" + $(this).data("id"))
.done(function (r) {
callback(r);
});
}
});
});
Updated Index View:
<table class="table">
<tr>
<th>
#Html.ActionLink("Software Name", "Index", new { sortOrder = ViewBag.SoftNameSort, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("License Type", "Index", new { sortOrder = ViewBag.LicenseType, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("End Date", "Index", new { sortOrder = ViewBag.EndDateSort, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td class="myToolTips" data-id="#item.SoftwareID" title="Loading in a second..">
#item.SoftwareName
</td>
<td>
#Html.DisplayFor(modelItem => item.LicenseType)
</td>
<td>
#Html.DisplayFor(modelItem => item.EndDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.SoftwareID }) |
#Html.ActionLink("Details", "Details", new { id = item.SoftwareID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.SoftwareID })
</td>
</tr>
//count++;
}
</table>
Updated SoftwareDetails Action:
public ActionResult SoftwareDetails(int id)
{
SoftwareLicense temp = db.SoftwareLicenses.Find(id);
return PartialView("SoftwareDetails", temp);
}
Result from URL Test (For Partial):
Partial Test
You do not need to render the tool tip partial view for all items when the page loads. You may get it on as needed basis. You can do this by making an ajax call and passing a unique id for the record user is hovering on currently.
Start by keeping a data attribute in your tr for the unique id.
#foreach (var item in Model)
{
<tr class="myToolTips" data-id="#item.SoftwareID" title="#item.SoftwareName">
<td>#item.SoftwareName</td>
</tr>
}
and you can enable tooltip for the table rows with the css class myToolTips.
$(function () {
$(document).tooltip({
items: "tr.myToolTips",
content: function (callback) {
$.get('/Home/SoftwareDetails/' + $(this).data("id"))
.done(function (r) {
callback(r);
});
}
});
});
Assuming you have an action method called SoftwareDetails which accepts the id and return the partial view
public ActionResult SoftwareDetails(int id)
{
return Content("Toolip for "+id);
// to do : Return the partial view for the markup you want (for the id)
}

Query Database Using JavaScript

I am fairly new to JavaScript and never used Ajax before. I want to add an OnClick to the Index.cshtml, so when a row is clicked, my code will query database (MSSQL)and return results.
I have two tables in database, User and Contact. The primary key in User, UID, is the foreign key in Contact. Here's my code:
Controller
private UserInfoEntities db = new UserInfoEntities();
public ActionResult Index(){
var users = from u in db.User orderby u.UID select u;
return View(users.ToList());
}
View
#<Info.Model.User>
<script type="text/javascript">
function showEmail() {
var tb = document.getElementById("users");
var rows = tb.rows;
for (var i = 1; i < rows.length; i++) {
rows[i].onclick = (function() {
//some code that query Contact table using UID
// and return Contact.Email in a popup windows or something
});
}
}
</script>
<table class="table" id="users" onclick="showEmail()">
<tr>
<th>
#Html.DisplayNameFor(model => model.NAME)
</th>
<th>
#Html.DisplayNameFor(model => model.UID)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.UID)
</td>
</tr>
Any help is appreciated!
try this;
<script type="text/javascript">
function showEmail() {
//some code that query Contact table using UID
// and return Contact.Email in a popup windows or something
}
</script>
<table class="table" id="users" >
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstOrDefault().NAME)
</th>
<th>
#Html.DisplayNameFor(model => model.FirstOrDefault().UID)
</th>
</tr>
#foreach (var item in Model) {
<tr onclick="showEmail()">
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.UID)
</td>
</tr>
}

Categories

Resources