delete rows of table on checking of checkboxes - asp.net-mvc

I have table containing data . In every row there is a checkbox plus a checkbox to select all checkbox at the headers.
Upon checking this checkboxes,corresponoding rows are to be deleted from database table.Plus,on chiecking the checkbox at the header,all rows will be deleted from the database table.How can i achieve this asp.net mvc.

As always start with a model:
public class ProductViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Then a controller:
public class HomeController : Controller
{
// TODO: Fetch this from a repository
private static List<ProductViewModel> _products = new List<ProductViewModel>
{
new ProductViewModel { Id = 1, Name = "Product 1" },
new ProductViewModel { Id = 2, Name = "Product 2" },
new ProductViewModel { Id = 3, Name = "Product 3" },
new ProductViewModel { Id = 4, Name = "Product 4" },
new ProductViewModel { Id = 5, Name = "Product 5" },
};
public ActionResult Index()
{
return View(_products);
}
[HttpPost]
public ActionResult Delete(IEnumerable<int> productIdsToDelete)
{
// TODO: Perform the delete from a repository
_products.RemoveAll(p => productIdsToDelete.Contains(p.Id));
return RedirectToAction("index");
}
}
And finally the Index.aspx view:
<% using (Html.BeginForm("delete", "home", FormMethod.Post)) { %>
<table>
<thead>
<tr>
<th>Name</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<%= Html.EditorForModel()%>
</tbody>
</table>
<input type="submit" value="Delete selected products" />
<% } %>
And the product editor template (~/Views/Home/EditorTemplates/ProductViewModel.ascx):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ToDD.Controllers.ProductViewModel>" %>
<tr>
<td>
<%: Model.Name %>
</td>
<td>
<input type="checkbox" name="productIdsToDelete" value="<%: Model.Id %>" />
</td>
</tr>

I would use AJAX. On changing the checked state, I would submit a request to delete all the selected IDs and refresh the table data.

Use jQuery, some other javascript library, or just hand code an AJAX request on check of checkbox. Then alter the DOM on success.
Using jQuery you could do something like:
<table>
<tr>
<td><input type="checkbox" class="check" id="1" /></td>
</tr>
<tr>
<td><input type="checkbox" class="check" id="2" /></td>
</tr>
<tr>
<td><input type="checkbox" class="check" id="3" /></td>
</tr>
</table>
$('.check').click(function() {
var tableRow = $(this).parent().parent();
var id = $(this).attr('id');
$.ajax({
url: 'http://www.YOURDOMAIN.com/Controller/Action/' + id,
success: function(data) {
$(tableRow).remove();
}
});
)};
This is very basic implementation, you could dress it up with some animation in the removal of the row. You also need to pass data and return data with some error handling. Check out here for a jQuery AJAX tutorial.

Related

.NET MVC JQuery function is not getting fired in table row click event

I have table data in UI. I want to display data in a div in the same page when I click the Details link in the row. The JQuery function is not getting fired in when I click on details link in any row.
Below is my code:
Model view class:
public class ItemViewModel
{
public Item item { get; set; }
public IEnumerable<Item> items { get; set; }
}
UI Code:
#model Medhub.Models.ItemViewModel
#{
ViewBag.Title = "View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>View</h2>
<p>
#Html.ActionLink("Create New", "CreateEdit", new { controller = "Item" }, new { #class = "btn btn-primary" })
</p>
<table align="center" height="10%" width="90%">
<tr>
<td>
<div id="Items">
<table style="vertical-align:top; height:200px" width="100%">
<tr style="height:20px">
<th>
#Html.DisplayName("Name")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th>
#Html.DisplayName("Item Type")
</th>
</tr>
#if (Model != null)
{
foreach (var item in Model.items)
{
<tr style="height:15px">
<td>
#Html.HiddenFor(model => item.ItemId)
#Html.DisplayFor(model => item.Name)
</td>
<td>
#Html.DisplayFor(model => item.Description)
</td>
<td>
#Html.DisplayFor(model => item.Type)
</td>
<td>
#Html.ActionLink("Edit", "CreateEdit", new { id = item.ItemId }) |
#Html.ActionLink("Details", "Item", new { id = item.ItemId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ItemId })
</td>
</tr>
}
}
</table>
</div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="ItemDetails">
#if (Model.item != null)
{
Html.RenderPartial("Details", Model.item);
}
</div>
</td>
</tr>
</table>
<script type="text/javascript">
$(function () {
$("div.Items a").click(function (e) {
//e.preventDefault();
var url = this.ref;
$("#ItemDetails").load(url);
});
});
</script>
Controller code:
List<Item> items = new List<Item>();
// GET: Item
public ActionResult Item(int id = 0)
{
ItemViewModel itemVM = new ItemViewModel();
itemVM.items = GetItems();
if (id > 0)
itemVM.item = itemVM.items.FirstOrDefault(u => u.ItemId == id);
return View(itemVM);
}
Any clues?
First of all, you are waiting for clicks on a class called Items. This is the reason the jquery code is not being fired. You should have
$("div#Items a").click(function (e) {
Secondly, you need to check the attribut href, not ref. Also, prevent default needs to be there, otherwise you just reload your page
e.preventDefault();
var url = this.href;
You don't need the renderpartial in the page, just leave it empty:
<div id="ItemDetails">
</div>
While your logic kind of works, the way the url is loaded causes the entire page to be loaded into the ItemDetails section. I'd suggest that in your controller, you'd create a separate method for the details:
public ActionResult Details(int id) {
Item item = GetItem(id);
return View(item);
}
private Item GetItem(int id) {
return new Item() { Details = "details here" };
}

Issue with mvc, partial view dispaying

I have a question about partial view. I want to display in header Login form which i created. In HomeController I have 2 actions: one is Login and other is Login with httppost method.
In partial view (_Layout.cshtml) I have a code - only send footer div:
<td style="text-align:center">
<h3>Bookstore</h3>
#Html.Partial("_LoginPartial")
</td>
In Login view I have:
#using(Html.BeginForm("Login", "Home", FormMethod.Post)){
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<td>#Html.LabelFor(a=>a.Username)</td>
<td>#Html.TextBoxFor(a=>a.Username)</td>
<td>#Html.ValidationMessageFor(a=>a.Username)</td>
</tr>
<tr>
<td>#Html.LabelFor(a=>a.Password)</td>
<td>#Html.PasswordFor(a=>a.Password)</td>
<td>#Html.ValidationMessageFor(a=>a.Password)</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" />
</td>
</tr>
</table>}
Controller
public ActionResult Login()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Users u)
{
if (ModelState.IsValid) {
using (DatabaseLoginEntities dl = new DatabaseLoginEntities()) {
var v = dl.Users.Where(a => a.Username.Equals(u.Username) && a.Password.Equals(u.Password)).FirstOrDefault();
if (v != null) {
Session["LogedUserId"] = v.UserAccountID.ToString();
Session["LogedUserFullName"] = v.FullName.ToString();
return RedirectToAction("AfterLogin");
}
}
}
return PartialView("_LoginPartial", u);
}
When press Login button, mvc switches me to separate page in which Login form is shown. I don't want that to happen. It must stay in header. Functionality is ok but I have issue how to show that only in header. Has anyone have idea where I'm wrong?
you must use ajax
#using (Ajax.BeginForm("Login", "Home",
new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace
,
UpdateTargetId = "div_id"
}
)){
<table>
<tr>
<td>#Html.LabelFor(a=>a.Username)</td>
<td>#Html.TextBoxFor(a=>a.Username)</td>
<td>#Html.ValidationMessageFor(a=>a.Username)</td>
</tr>
<tr>
<td>#Html.LabelFor(a=>a.Password)</td>
<td>#Html.PasswordFor(a=>a.Password)</td>
<td>#Html.ValidationMessageFor(a=>a.Password)</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" />
</td>
</tr>
</table>
}

Post collection of selected values to server action

I have a form with a product-warranty list.
Each list item has checkbox.
How can I post a list of SelectecSources (warranties) to the server?
What do I have to change in that code?
The WarrantyPlusViewModel object is posted to the server. It contains a list SelectedSources which should contain the selected warranty articles.
Is it possible at all to use a complex object for the selected list?
Consider I have to post the WarrantyPlusViewModel to the server which includes
the SelectedSources property with the selected warranty objects.
#model WarrantyPlusViewModel
<div class="row">
<div class="col-md-10 col-md-offset-1">
#using (...)
{
<table class="table table-striped">
<tr>
<th></th>
<th>#Html.DisplayFor(m => m.ProductSelected.Name)</th>
<th>#Html.DisplayFor(m => m.ProductSelected.Description,l)</th>
<th>#Html.DisplayFor(m => m.ProductSelected.Price)</th>
</tr>
#foreach (var product in Model.ProductList)
{
<tr>
<td><input type="checkbox" name="SelectedSources" value="#product" /></td>
<td>#product.Name</td>
<td>#product.Description</td>
<td>#product.Price</td>
</tr>
}
</table>
<input type="submit" value="Save" />
#Html.HiddenFor(p => p.SerialNumber)
}
</div>
[HttpPost]
public virtual async Task<ActionResult> Save(WarrantyPlusViewModel viewModel)
{
return View(MVC.WarrantyPlus.WarrantyPlus.Views.OverviewWarrentyPlus, viewModel);
}
public class WarrantyPlusViewModel
{
// other properties
public List<WarrantyPlusProductViewModel> ProductList { get; set; }
public IEnumerable<WarrantyPlusProductViewModel> SelectedSources { get; set; }
}
It's really hard to bind this way. If you want to do it you should override Model Binder.
If i were on your place i will just use ProductId with some knowlege of list binding and come up with this solution:
#for (var i = 0; i < Model.ProductList.Count(); i++)
{
<tr>
<td><input type="checkbox" name="ProductList[" #i "].Id" value="#Model.ProductList[i].Id" /></td>
<td>#Model.ProductList[i].Name</td>
<td>#Model.ProductList[i].Description</td>
<td>#Model.ProductList[i].Price</td>
</tr>
}

fiil a list with values of a table

I'm new in learning asp.net MVC. I am writing because I am stubborn to a problem. Indeed, I have an application that should allow me to create an XML file that will be added to a database. At this point, I created my Model, and my view that allows me to create my XML tags.
I saw on this site that could add lines in my table via Javascript. What I have done just as you can see in the code.
I can not recover what is the value of each line that I can insert. Passing my view a list I created myself. I can recover both inputs I inserted in my controller.
My question is, there's another way to create a dynamic lines via javascript, then all the entries that the user has entered the recover and fill in my list? Then I know myself how I can play with my list. But I just want to recover all the different lines that my user has inserted. I am new in ASP.NET MVC. Any help , please
This is my code.
Model
public class XMLFile
{
public string TypeDoc { get; set; }
public string Type { get; set; }
public string Contenu { get; set; }
public string DocName { get; set; }
}
This is my controller :
public class XMLFileController : Controller
{
List<XMLFile> file = new List<XMLFile>();
[HttpGet]
public ActionResult Save()
{
file.AddRange( new XMLFile[] {
new XMLFile (){Type = "Titre", Contenu = "Chef de Service"},
new XMLFile (){Type = "Item", Contenu="Docteur Joel"}
});
return View(file);
}
[HttpPost]
public ActionResult Save(List<XMLFile> formCollection)
{
try
{
if (formCollection == null)
{
return Content("la liste est nulle");
}
else
{
return RedirectToAction("Create", "Layout");
}
}
catch
{
return View();
}
}
}
My view with a script for adding a new Row :
#using (Html.BeginForm("Save", "XMLFile", FormMethod.Post,new { #class = "form-horizontal", #role = "form", #id = "FormCreateXML" }))
{
<table class="table table-bordered" id="XMLFileTable">
<thead>
<tr>
<th>Type</th>
<th>Contenu</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#for (int i = 0; i<Model.Count; i++)
{
<tr>
<td>#Html.TextBoxFor(model=>model[i].Type, new {#class="form-control help-inline", #placeholder="type" })</td>
<td> #Html.TextBoxFor(model=>model[i].Contenu, new {#class="form-control help-inline", #placeholder="contenu" })</td>
<td> <input type="button" class="BtnPlus" value="+" /> </td>
<td> <input type="button" class="BtnMinus" value="-" /> </td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td> <button type="submit" class="btn btn-success" >Save</button> </td>
</tr>
</tfoot>
</table>
}
</body>
<script type="text/javascript">
$(document).ready(function () {
function addRow() {
var html = '<tr>' +
'<td><input type="text" class="form-control" placeholder="type"></td>' +
'<td> <input type="text" class="form-control" placeholder="contenu"></td>' +
'<td> <input type="button" class="BtnPlus" value="+" /> </td>' +
'<td> <input type="button" class="BtnMinus" value="-" /></td>' +
'</tr>'
$(html).appendTo($("#XMLFileTable"))
};
function deleteRow() {
var par = $(this).parent().parent();
par.remove();
};
$("#XMLFileTable").on("click", ".BtnPlus", addRow);
$("#XMLFileTable").on("click", ".BtnMinus", deleteRow);
});
</script>

How to bind a List of ViewModel in ASP MVC?

Does anyone know how to get POST values for MODELVIEW Pattern below. I can display the MenuItem as Checkboxes and Radio buttons,
but when user submits the form i.e. POST, ModelViewTest is null. I'm expecting List of MenuItems that user have selected.
public class ModelViewTest
{
public IEnumerable<MenuItem> MenuItemList { get; set; } //Will be displayed as listboxes and checkboxes
public Restaurant restaurant {get;set;}
}
ACTIONS:
public ActionResult Edit()
{
//some code here
}
return View(new ModelViewTest());
}
[HttpPost]
public ActionResult Edit(ModelViewTest model)
{
//I'm not getting List of MenuItems
return View();
}
MenuItem Class:
public class MenuItem
{
public string MenuItemCode{get;set;}
public string MenuItemDescription{get;set;}
public string UIType {get;set;} //This determines whether it's radio or checkbox
public string UIGroupType {get;set;} //Determines the Group for radio/checkbox.
}
public class Restaurant
{
public string restaurantName{get;set;}
public MenuItem MenuItem{get;set;}
}
Update
Please see my View code snippet below:
<table>
#foreach (var menu in Model.MenuList)
{
if (menu.UIType == "Radio")
{
<tr>
<td align="left">
<input id="MenuCheckboxRadio" name="#Menus.UIGroup" value="#Menu.MenuItemCode" type="radio" />
<label>#Menu.MenuItemDescription</label>
</td>
</tr>
}
else
{
<tr>
<td align="left">
<input id="MenuCheckbox" name="#Menus.UIGroup" value="#Menus.#MenuItem" type="checkbox" />
<label>#Menu.MenuItemDescription</label>
</td>
</tr>
}
i++;
}
</table>
In order to get the list of menu items in the POST action you need their corresponding values must be included in the html <form> and because this is a collection follow the standard naming convention so that the default model binder can parse them.
First you should show us your view to know how you render your ViewModel.
However try this:
make partial view to be editor template for your MenyItem
<%# Control Inherits="ViewUserControl<MenyItem>" %>
<%: Html.TextBoxFor(m => m.MenuItemCode) %>
<%: Html.TextBoxFor(m => m.MenuItemDescription) %>
.......
then in your view make for loop NOT foreach:
<%# Page Inherits="ViewPage<ModelViewTest>" %>
<% using (Html.BeginForm()) {%>
<% for (int i = 0; i < 3; i++) { %>
<%: Html.EditorFor(m => m.MenuItemList[i]) %>
<% } %>
<% } %>
And please see this answer
Please see my View code snippet below:
<table>
#foreach (var menu in Model.MenuList)
{
if (menu.UIType == "Radio")
{
<tr>
<td align="left">
<input id="MenuCheckboxRadio" name="#Menus.UIGroup" value="#Menu.MenuItemCode" type="radio" />
<label>#Menu.MenuItemDescription</label>
</td>
</tr>
}
else
{
<tr>
<td align="left">
<input id="MenuCheckbox" name="#Menus.UIGroup" value="#Menus.#MenuItem" type="checkbox" />
<label>#Menu.MenuItemDescription</label>
</td>
</tr>
}
i++;
}
</table>

Resources