why checkbox wont check on page load? - asp.net-mvc-4

i have the following database table for the Compounds table (chemical compounds/elements in the periodic table) there are typos in table data so ignore them
the data is :
the controller :
public class CheckboxController : Controller
{
//
// GET: /Checkbox/
testdbEntities db = new testdbEntities();
[HttpGet]
public ActionResult Index()
{
var comps = db.Compounds.Select(c => new CompoundModel { Id=c.Id, CompoundName=c.Name, IsSelected=c.IsSelected}).ToList();
CheckboxVM cvm = new CheckboxVM { checkboxData=comps};
return View(cvm);
}
[HttpPost]
public string Index(IEnumerable<CheckboxVM> collection)
{
return "";
}
}
Model class CompoundModel is:
public class CompoundModel
{
public int Id { get; set; }
public string Code { get; set; }
public string CompoundName { get; set; }
public bool IsSelected { get; set; }
}
and the ViewModel CheckBoxVM:
public class CheckboxVM
{
public string Id { get; set; }
public string CompoundNmae { get; set; }
public bool IsSelected { get; set; }
public IEnumerable<CompoundModel> checkboxData { get; set; }
}
When the page loads it should display check boxes with names and if db table has checked on them (IsSelected=1) then they should be checked.In the post back i need to receive the id, of the user checked checkboxes. At the moment my code does meet the first requirement to check the checked checkboxes based on IsSelected on page load. Is there a way to fix this?
If you need a video with debugging please ask i will be happy to post : )
THE VIEW: (UPDATE)
#model recitejs1.Models.CheckboxVM
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
foreach (var item in Model.checkboxData)
{
#Html.CheckBoxFor(x=>x.IsSelected, (item.IsSelected)?new{#checked="check"}:null)#item.CompoundName
#Html.HiddenFor(x=>x.Id, item.Id)
#Html.HiddenFor(x=>x.CompoundNmae, item.CompoundName)
}
<br><br>
<input type="submit" name="name" value="Send" />
}

You cannot use a foreach loop to generate form controls. It generates duplicate name attributes (that have no relationship to your model) and duplicate id attributes (invalid html).
Create a custom `EditorTemplate for your model
In /Views/Shared/EditorTemplates/CompoundModel.cshtml
#model recitejs1.Models.CompoundModel
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.CompoundName)
#Html.CheckBoxFor(m => m.IsSelected)
#Html.LabelFor(m => m.CompoundName)
Then in the main view
#model recitejs1.Models.CheckboxVM
....
#using (Html.BeginForm())
{
#Html.EditorFor(m => m.checkboxData)
<input type="submit" name="name" value="Send" />
}
The EditorFor() method will generate the correct html for each item in your collection
Note: You should inspect the html before and after you make this change to better understand how model binding works.
Note also that your POST method parameter needs to be
public string Index(CheckboxVM model)
since that's what the view is based on. However the only property of CheckboxVM that you use in the view is IEnumerable<CompoundModel> checkboxData in which case your view should be
#model IEnumerable<CompoundModel>
...
#Html.EditorFor(m => m)
and keep the POST method as it is (but change the GET method)

Related

Partial Views with different model in Asp.net MVC

i have two class as below
Model:-
public class RegisterViewModel
{
public string Email { get; set; }
public AddressPropertyVM AddressProperty { get; set; }
}
public class AddressPropertyVM
{
public string StreetNo { get; set; }
}
Main Form
#model Application.Models.RegisterViewModel
{
#Html.TextBoxFor(m => m.Email)
#Html.TextBoxFor(m => m.FirstName)
#Html.Partial("_AddressPropertyPartial",Model.AddressProperty)
<button type="submit">Register</button>
}
Partial View Form
#model Application.Models.AddressPropertyVM
{
#Html.TextBoxFor(m => m.StreetNo)
}
I am creating asp.net mvc application.
I have create a partial view for AddressPropertyVM.
but we i post form(main form) at that time data of AddressProperty is null.
As per my understanding you want to use one partial view with more than one pages I mean multiple usage of one page in many pages.
Read this article and understand how it works.
Change your code as per article like below.
#Html.Partial("_AddressPropertyPartial",Model.AddressProperty)
To
#Html.Partial("_AddressPropertyPartial", Model.AddressProperty, new ViewDataDictionary() { TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = "AddressProperty" } }

Passing Model via dropDownListFor() from view to controller

I am trying to pass a Model from my view to my controller using dropDownListFor.
After choosing something from the list it sends the model to my controller but it's content NULL.
This is what i have for the Model
public class Model
{
public int ModelId { get; set; }
[Required]
public string Name { get; set; }
}
This is what my ViewModel looks like
public class ModelVM
{
public List<Model> Models;
public Model SelectModel { get; set; }
public IEnumerable<SelectListItem> ModelItems
{
get { return new SelectList(Models, "ModelId", "Name"); }
}
}
The controller when i put data in the ViewModel looks like this
public ActionResult Index()
{
ModelVM modelVM= new ModelVM()
{
Models = manager.GetAllModels().ToList()
};
return View(modelVM);
}
Finally this is what i have in the View for the dropDownList
#using (Html.BeginForm("Home", "Home", FormMethod.Post))
{
#Html.DropDownListFor(model => model.SelectModel, Model.ModelItems)
<input type="submit" value="Go" />
}
So this is supposed to send Model to my controller.
But when i check the content of the passed Model in the controller, everything is NULL which isn't supposed to be because when i debug the view and check for the content of ModelItems, everything in the ModelItems is there.
Here is when i check the content of the passed Model
public ActionResult Home(Model model) <<<<<<<<<< Content == NULL
{
return View();
}
A <select> element on posts back a single value. Html has no concept of what your c# Model class is so you cannot bind to a complex object. You need to bind to the ModelId property of Model. Your view model should be
public class ModelVM
{
[Display(Name = "Model")]
public int SelectedModel { get; set; }
public SelectList ModelItems { get; set ;}
}
and in the controller
public ActionResult Index()
{
ModelVM modelVM = new ModelVM()
{
ModelItems = new SelectList(manager.GetAllModels(), "ModelId", "Name")
// SelectedModel = ? if you want to preselect an item
};
return View(modelVM);
}
and in the view
#Html.LabelFor(m => m.SelectedModel)
#Html.DropDownListFor(m => m.SelectedModel, Model.ModelItems)
and in the post method your model will be correctly bound with the ID of the selected model
Trying passing in type ModelVM to the Home action as that is the type being passed to Index view.
Instead of model.SelectModel in the drop-down declaration, you only need an int ID to capture which ID is selected.

MVC4 pass model values from view (for-each) to controller

Hello dear i am trying to pass my model values from view to controller. when i am trying to do that i receive only null value in controller my view is given below
I also have used #html.hadden but still received only null value in contoller after button click. please someone help me and tell me the solution of this problem.
My VIEW IS THIS WHERE I AM TRYING TO PASS VALUE TO CONTOLLER:
#model IEnumerable<onlinebookstore.entityframwork.book>
#using (Html.BeginForm("AddToCart", "ShopingCart", FormMethod.Post))
{
foreach (var item in Model)
{
<img src="#Url.Content(item.book_img)" alt="Image" width="170px"; height="230px" />
<br />
#Html.DisplayFor(modelItem => item.book_name)
<br />
<label>Author:</label>
#Html.DisplayFor(modelItem => item.author)
<br />
<label>Pk.</label>#Html.DisplayFor(modelItem => item.price, new { id = "price" })&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp
#Html.ActionLink("For Detail..", "Detail", "Book", new { id = item.inventory_id }, null)
<br />
<input type="submit" class="btnreg" id="btnaddcart" value="Add to Basket"/>
<br />
}
}
My Controller where i am trying to receive values from view and here i received only null values
[HttpPost]
public ActionResult AddToCart(book model)
{
var cartitem =
db.shoping_cart_item
.FirstOrDefault(u => u.inventory_id == model.inventory_id);
if (cartitem == null && Session["userid"] != null)
{
cartitem = new shoping_cart_item();
cartitem.inventory_id = model.inventory_id;
cartitem.price = Convert.ToDecimal(model.price.ToString());
db.shoping_cart_item.Add(cartitem);
}
return View();
}
My Model (BOOK)
public string inventory_id { get; set; }
public string book_name { get; set; }
public string author { get; set; }
public string book_type { get; set; }
public Nullable<int> no_book { get; set; }
public Nullable<decimal> price { get; set; }
public string book_img { get; set; }
public string book_description { get; set; }
Please help me how we will pass model value using for-each loop in view to Controller
You have no inputs for your form. You aren't submitting anything. Try #Html.TexboxFor() or some other helper.
So what will be the remedy of this problem where i can display my all values in view and on button click all the values of model will be pass on to controller.
I think you are doing it wrong.
Your view is looping through the list of onlinebookstore.entityframwork.book to display the details AND one button for EACH of them inside one big form. When you submit that, all inputs that can be submitted will be posted (a collection of books at best). But on your controller, you are just receiving one instance of onlinebookstore.entityframwork.book
You might want to rethink your view by creating the loop first then inside it, have the #using (Html.BeginForm("AddToCart", "ShopingCart", FormMethod.Post)) markup inside. This creates a form for each onlinebookstore.entityframwork.book. Just make the necessary adjustments for multi-form on a single page to work.

ASP.NET MVC editor template containing submit form, values are null when reaching controller

I have a parent Endowment that has many Criterion in a collection called Criteria. I am building an edit form where I want to edit the parent attributes as well as add/remove a criterion.
Endowment.cs, Criterion.cs and EndowmentEditViewModel.cs
public class Endowmment {
public int ID {get; set;}
public string Description {get; set;}
...
public virtual ICollection<Criterion> Criteria {get; set;}
}
public class Criterion {
public int ID {get; set;}
public int EndowmentID {get; set;}
public string Description {get; set;}
public string SortOrder {get; set;}
}
public class EndowmentEditViewModel {
public Endowment Endowment {get; set;}
...
}
In the Endowment Edit view, I have referenced an editor template for the criterion collection called criteria, since there are many for one endowment. The editor template is outside of the form for the Endowment.
Views/Endowment/Edit.cshtml
#model EndowmentEditViewModel
#using (Html.BeginForm("Edit", "Endowment")
{
#Html.HiddenFor(m => m.Endowment.ID)
#Html.TextBoxFor(m => m.Endowment.Description)
<input type="submit" value="Save endowment" />
}
#Html.EditorFor(m => m.Endowment.Criteria)
In the Criterion editortemplate, I want to be able to save or delete a Criterion row.
Views/Shared/EditorTemplates/Criterion.cshtml
#model Criterion
#using (Html.BeginForm("Edit", "Criterion"))
{
#Html.TextBoxFor(m => m.Description)
#Html.TextBoxFor(m => m.SortOrder)
<input type="submit" value="Save" />
}
#using (Html.BeginForm("Delete", "Criterion", new { #id = Model.ID }))
{
#Html.Hidden("ID", Model.ID)
<input type="submit" value="Delete" />
}
The delete action works fine, however, when I click "Save", the values are posted in the browser request, but the Edit action on the Criterion controller receives them as null values.
Controllers/CriterionController.cs
[HttpPost]
public ActionResult Edit(Criterion model)
{
if (ModelState.IsValid)
{
repository.SaveCriterion(model);
// insert happy message
TempData["message"] = string.Format("Criterion {0} was saved", model.Description);
}
else
{
// there is something wrong with the data values
// inesrt fail message
}
return RedirectToAction("Edit", "Endowment", new { id = model.EndowmentID });
}
This is what I did to get it to work:
In my view, Views/Endowment/Edit.cshtml
#*#Html.EditorFor(m => m.Endowment.Criteria)*#
#foreach (var criterion in Model.Endowment.Criteria)
{
#Html.EditorFor(m => criterion)
}
....
In the controller /Controllers/CriterionController.cs
[HttpPost]
public ActionResult Edit([Bind(Prefix = "criterion")] Criterion model)
{
...
No change in the editor template.
Strange. I thought foreach was boo-hooed in a view, but it worked for this particular purpose. Well, I guess any parent/child in the same view is boo-hooed too, but it works for me. If there is a better way, I'd love to know.
There is a slightly better way. MVC will enumerate model objects for you and display your editor template once for each item in a list. For example, this:
#Html.EditorFor(m => criterion) //Assumes criterion is is a list or collection
Does the same thing as this:
#foreach (var criterion in Model.Endowment.Criteria)
{
#Html.EditorFor(m => criterion)
}

post complex viewmodels using ajax.beginForm MVC4 only getting null

im very new to mvc, lest say i have a viewmodel that cotains objects like
public class vm_set_rol
{
public IEnumerable<SelectListItem> roles { get; set; }
public Rol_User rol { get; set; }
}
rol is an object like:
public class Rol_User
{
public int idUser { get; set; }
public int Role { get; set; }
public int GrantedBy { get; set; }
public bool canGrant { get; set; }
public DateTime ExpirationDate { get; set; }
}
so i have a form on a view to let the user select 1 role from a roles dropdown and select a date and a checkbox somthing like:
<div class="ModalContainer">
#using (Ajax.BeginForm(new AjaxOptions
{
UpdateTargetId = "gestionRolContainer",
Url = "Permiso/Test",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
}
)
)
{
<fieldset>
<legend>#Res_String.RolLabel</legend>
<span>ROL:</span><br />#Html.DropDownListFor(m => m.rol, Model.roles, new {#id="AdmPermUserRolesDropDown" })
<br />
#Html.CheckBoxFor(m => m.rol.conceder ,Model.rol.conceder) <span>Delegate?</span>
<br />
<input type="submit" class="buttonClass" value="OK" />
</fieldset>
}
</div>
the problem is that i only get null values, if i create some other property on the model like a string or int, those are posted back ok,
i kind of understad why objects are not posted back, bust is there any workaround??? or put a object on the modes is just wrong and i shuld declare the propertis on the viewmodel instead of an object???
Your dropdown is incorrectly bound. It should be bound to a scalar property to hold the selected value:
#Html.DropDownListFor(
m => m.rol.Role,
Model.roles,
new { id = "AdmPermUserRolesDropDown" }
)
As far as the Roles collection property is concerned, it will always be null in your controller action because this list is never sent to the server when you submit a form. Only the selected value is sent. So if you need to redisplay this view once again you will have to populate the Roles collection property in your HttpPost action the same way you did in your GET action.
Also your checkbox is bound to some m => m.rol.conceder property which doesn't exist in the view model you have shown. I guess you meant using the canGrant boolean property. Also you don't need to provide as second parameter to the CheckBoxFor helper the value. It will be inferred from the lambda expression:
#Html.CheckBoxFor(m => m.rol.canGrant) <span>Delegate?</span>
Last but not least, since you are using an Ajax.BeginForm make sure that you have referenced the jquery.unobtrusive-ajax.js script in your view.