MVC C# foreach Loop passing button selection - c#

I have a listing view which shows the jobs extracted from the database. Each Job has a button next to it. When I move to the next page, i need to carry the specified job, display it and later save it to my database.
This is inside my Controller class.
I extracted the jobs in the index and after clicking the button i want to move to the "Apply" method
public ActionResult Index()
{
var jobs = (from Jobs in db.Jobs
orderby Jobs.Id descending
select Jobs);
List<CareersClasses.Jobs> job = jobs.ToList();
return View(job);
}
[HttpPost]
public ActionResult Apply(){
return View();
}
This is The Index View:
<table>
#using (Html.BeginForm("Apply", "Jobs", FormMethod.Post))
{
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Desc)
</td>
<td>
<button id="Apply" name="Apply" value="#item.Title">Apply</button>
</td>
</tr>
}
}
</table>
This is the Apply View
#using (Html.BeginForm("Submit", "Jobs", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<fieldset>
<legend>Applicants</legend>
<div class="editor-label">
#Html.LabelFor(model => model.JobId)
</div>
<div class="editor-field">
#Html.DisplayFor(model=> model.JobId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FName)
#Html.ValidationMessageFor(model => model.FName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LName)
#Html.ValidationMessageFor(model => model.LName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNb)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNb)
#Html.ValidationMessageFor(model => model.PhoneNb)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Country)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
<div class="editor-label">
Curriculum Vitae
</div>
<div class="editor-field">
<input type="file" name="file"/>
</div>
<div class="editor-label">
#Html.EditorFor(model => model.JobId)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
I also want to add a document to my database:
I used this method in the "submit" method is it correct?
Submit Method:
[HttpPost]
public ActionResult Submit(FormCollection formCollection, HttpPostedFileBase file)
{
CareersClasses.Applicants Applicants = new CareersClasses.Applicants();
if (ModelState.IsValid)
{
Applicants.FName = formCollection["FName"];
Applicants.LName = formCollection["LName"];
Applicants.Email = formCollection["Email"];
Applicants.Country = formCollection["Country"];
Applicants.PhoneNb = int.Parse(formCollection["PhoneNb"]);
if (file != null && file.ContentLength > 0)
{
byte[] data = GetDocument(file);
Applicants.CV = data;
}
db.Applicants.Add(Applicants);
db.SaveChanges();
return RedirectToAction("ListApps");
}
return View();
}
[HttpPost]
public byte[] GetDocument(HttpPostedFileBase file)
{
//Get file info
var fileName = Path.GetFileName(file.FileName);
var contentLength = file.ContentLength;
var contentType = file.ContentType;
//Get file data
byte[] data = new byte[] { };
using (var binaryReader = new BinaryReader(file.InputStream))
{
data = binaryReader.ReadBytes(file.ContentLength);
}
return data;
}
The Classes Model:
public class CareersClasses
{
public class Applicants
{
[Key]
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public int PhoneNb { get; set; }
public string Email { get; set; }
public string Country { get; set; }
public byte[] CV { get; set; }
public int JobId { get; set; }
[ForeignKey("JobId")]
public virtual Jobs Jobs { get; set; }
}
public class Jobs
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
}
}
Note: I am still new to MVC and I did a lot of research before asking these questions but i'm still lost, so your help will be much appreciated

The Index view should have links (not forms) to an Apply() method for the Job. The link passes the Id of the Jobs to the method, which initializes a new instance of CareersClasses and sets its JobId property. The method then returns a view to edit the CareersClasses and the submit button posts back the model to the POST method.
Index.cshtml
<table>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Title)</td>
<td>#Html.DisplayFor(modelItem => item.Desc)</td>
<td>#Html.ActionLink("Apply", "Apply", new { ID = item.Id})</td>
</tr>
}
</table>
Controller
public ActionResult Apply(int ID)
{
CareersClasses model = new CareersClasses();
model.JobID = ID;
return View(model);
}
[HttpPost]
public ActionResult Apply(CareersClasses model, HttpPostedFileBase file)
{
// save the model and redirect
}
Apply.cshtml
#model CareersClasses
....
#Html.BeginForm())
{
// controls for properties of CareersClasses
....
<input type="submit" value="Create" />
}

Related

Display checkbox Data value from database using mvc

I need to create a form to register.
the example of form will look like this
how do I display the value in the red circle in the form? (the value is from database)
My controller
namespace Insurance.Controllers
{
public class FlexiPAController : Controller
{
//
// GET: /FlexiPA/
public ActionResult RegisterFlexiPA()
{
return View();
}
public ActionResult RegisterFire()
{
return View();
}
public ActionResult RegisterMotor()
{
return View();
}
}
}
My ViewModel
namespace Insurance.ViewModels
{
public class RegisterInfoPA
{
public register reg { get; set; }
public infoPA infoFlexiPA { get; set; }
public personalInfo pinfo { get; set; }
public List<maritalInfo> minfo { get; set; }
public childInfo cInfo { get; set; }
}
}
My view
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<!--TITLE-->
<div class="editor-label">
Title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.reg.title)
#Html.ValidationMessageFor(model => model.reg.title)
</div>
<!--NAME-->
<div class="editor-label">
Name
</div>
<div class="editor-field">
#Html.EditorFor(model => model.reg.registerNm)
#Html.ValidationMessageFor(model => model.reg.registerNm)
</div>
<!--IC NO-->
<div class="editor-label">
IC No
</div>
<div class="editor-field">
#Html.EditorFor(model => model.reg.identityNo)
#Html.ValidationMessageFor(model => model.reg.identityNo)
</div>
<!--GENDER-->
<div class="editor-label">
Gender
</div>
<div class="editor-field">
#Html.EditorFor(model => model.pinfo.gender)
#Html.ValidationMessageFor(model => model.pinfo.gender)
</div>
<!--Marital Status-->
<div class="editor-label">
**Marital Status**
</div>
<div class="editor-field">
</div>
Wanted to make the checkbox here for marital status eg :single,widowed,married
I am new to mvc, really appreciate your helps.
Try this
Let's try one controller first
Your Controller
namespace Insurance.Controllers
{
public class FlexiPAController : Controller
{
//
// GET: /FlexiPA/
DATABASENAME db = new DATABSENAME (); //ESTABLISHING CONNECTION TO DATABASE
public ActionResult RegisterFlexiPA()
{
using (var dataBase = new DATABASENAME ())
{
var model = new RegisterInfoPA()
{
minfo = dataBase.maritalInfoes.ToList(),
//IF YOU WISH TO ADD MORE
};
return View(model);
}
}
Your ViewModel
change you marital info to IEnurumerable instead of List
public IEnumerable<maritalInfo> minfo { get; set; }
Your View
I would like to suggest you to make radiobutton instead of checkbox, because surely you can only choose one,eg: either single or married. Thus, it is highly preferred to use radiobutton
<div>
Marital Status
#foreach (var item in Model.minfo)
{
#Html.RadioButtonFor(model => model.pinfo.maritalId, item.maritalId)#Html.Label(item.maritalStatNm)
}
</div>
This is how you display, then in the controller you just need to save it.
You can use :
#foreach(var item in Model.minfo)
{
#Html.EditorFor(o => item)
}
Create a partial view called maritalInfo.cshtml. Put this partial in Views/Shared/DisplayTemplates.
In the partial :
#model maritalInfo
<!--Marital Status Name and Value depend on your maritalInfo Model-->
<div class="editor-label">
#Html.LabelFor(o => Model.Name)
</div>
<div class="editor-field">
#Html.CheckBoxFor(o => Model.Value)
</div>

ASP.NET MVC4 IEnumerable empty on post

I have read several answers on this issue but despite this, it would appear I have developed code blindness.
I have the following view model:
public class IndividualProductVm
{
public virtual Products Products { get; set; }
public ProductSummary ProductSummary { get; set; }
public virtual IEnumerable<ProductSimpleResponse> ProductSimpleResponse { get; set; }
}
This is then passed into a view and then a partial view:
#model Websites.ViewModels.IndividualProductVm #{ ViewBag.Title = "Edit"; }
<h2>Edit</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { name = "form", id = "mainForm" })) { #Html.AntiForgeryToken() #Html.ValidationSummary(true, "", new { #class = "text-danger" }) #Html.HiddenFor(model => model.Products.Id) #Html.HiddenFor(model
=> model.ProductSummary.SupplierId) Html.RenderPartial("_IndividualProduct", Model);
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index", new { id = Model.ProductSummary.SupplierId }, new { #class = "btn btn-default" })
</div>
#section Scripts { #Scripts.Render("~/bundles/jqueryval") }
#model Websites.ViewModels.IndividualProductVm
<div>
#Html.LabelFor(model => model.Products.ProductCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div>
#Html.DisplayFor(model => model.Products.ProductCode, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div style="clear:both;"></div>
<div>
#Html.LabelFor(model => model.Products.ProductDescription, htmlAttributes: new { #class = "control-label col-md-2" })
<div>
#Html.DisplayFor(model => model.Products.ProductDescription, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<table class="table">
<tr>
<th>
Present
</th>
</tr>
#foreach (var item in Model.ProductSimpleResponse)
{
<tr>
#Html.HiddenFor(modelItem => item.Id)
#Html.HiddenFor(modelItem => item.SupplierId)
#Html.HiddenFor(modelItem => item.ProductCode)
<td>
#Html.EditorFor(modelItem => item.Present)
</td>
</tr>
}
</table>
However, when I enter the edit post, my viewmodel is null for the IEnumerable<ProductSimpleResponse> but fine for the other two classes.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(IndividualProductVm model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index", new { id = model.ProductSummary.SupplierId });
}
return View(model.Products);
}
If someone can explain what I'm doing wrong, I'd be most grateful.
Your property name is ProductSimpleResponse, alhtough the type is ProductSvhcSimpleResponse, so to iterate through it you should have.
#foreach (var item in Model.ProductSimpleResponse)
NOT
#foreach (var item in Model.ProductSvhcSimpleResponse)
use List because
IEnumerable is suitable just for iterate through collection and you can not modify (Add or Remove) data IEnumerable bring ALL data from server to client then filter them, assume that you have a lot of records so IEnumerable puts overhead on your memory.
public class IndividualProductVm
{
public virtual Products Products { get; set; }
public ProductSummary ProductSummary { get; set; }
public virtual List<ProductSvhcSimpleResponse> ProductSimpleResponse { get; set; }
}
More help click here

How to perform edit function in MVC4 without using entity framework?

I just want to edit my old data using mvc4. For eg, the city name needs to be changed from chennai
(dropdownlist which is populated from model) to pune. Can anyone guide me pls?
Below is my code:
Controller:
[HttpGet]
public ActionResult display(Create model)
{
List<Create> city = new List<Create>();
using (connectionstring pcs = new connectionstring())
{
city = pcs.grp.OrderBy(a => a.cityname).ToList();
}
ViewBag.cityname = new SelectList(city, "cityname", "cityname");
return View(model);
}
[HttpPost, ActionName("display")]
[ValidateAntiForgeryToken]
public ActionResult display1( Create cg)
{
List<Create> city = new List<Create>();
using (connectionstring pcs = new connectionstring())
{
city = pcs.grp.OrderBy(a => a.cityname).ToList();
}
ViewBag.cityname = new SelectList(city, "cityname", "cityname");
if (ModelState.IsValid)
{
string oldgcityname = cg.cityname.ToString().Trim();
using (NpgsqlConnection conn = new NpgsqlConnection(ConfigurationManager.ConnectionStrings["portalconnectionstring"].ConnectionString))
{
using( NpgsqlCommand cmd=new NpgsqlCommand("update tblcity set cityname='$1' where cityname='"+oldcityname+"'",conn))
cmd.ExecuteNonQuery();
}
}
return View(cg);
}
View:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<table>
<tr> <td>
<div class="editor-label">
#Html.Label("Select old cityname")
</div> </td>
<td>
<div class="editor-field">
#Html.DropDownListFor(model => model.cityname,#ViewBag.cityname as SelectList,"select")
#Html.ValidationMessageFor(model => model.cityname)
</div>
</td></tr>
<tr> <td>
<div class="editor-label">
#Html.Label("Enter new cityname")
</div> </td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.cityname)
#Html.ValidationMessageFor(model => model.cityname)
</div>
</td></tr>
<tr><td>
<p>
<input type="submit" value="Create" />
</p>
</td></tr>
Create a view model that contains properties for the old and new names
View model
public class CreateVM
{
[Display(Name = "Old name")]
[Required]
public string OldName { get; set; }
[Display(Name = "New name")]
[Required]
public string NewName { get; set; }
public SelectList CityList { get; set; }
}
Controller
[HttpGet]
public ActionResult Edit(CreateVM model)
{
CreateVM model = new CreateVM();
...
model.CityList = new SelectList(city, "cityname", "cityname");
return View(model);
}
[HttpPost]
public ActionResult Edit(CreateVM model)
{
// the model now contains the selected old name and its new name
}
View
#model CreateVM
#using(Html.BeginForm())
{
#Html.LabelFor(m => m.OldName)
#Html.DropDownListFor(m => m.OldName, Model.CityList, "-Please select-")
#Html.ValidationMessageFor(m => m.OldName)
#Html.LabelFor(m => m.NewName)
#Html.TextBoxFor(m => m.NewName)
#Html.ValidationMessageFor(m => m.NewName)
<input type="submit" />
}
And as Jon Skeet has noted, use parameterized SQL!

How to POST a form containing Editor Templates for an ICollection?

I'm working with ASP.NET MVC 4 and I have the following models:
public class MultiLanguageText
{
[Key] public int Id { get; set; }
[Required] public string Name { get; set; }
public virtual ICollection<LocalizedText> LocalizedTexts { get; set; }
}
public class LocalizedText
{
[Key] public int Id { get; set; }
[ForeignKey("Language")] public int LanguageId { get; set; }
public virtual Language Language { get; set; }
[ForeignKey("MultiLanguageText")] public int MultiLanguageTextId { get; set; }
public virtual MultiLanguageText MultiLanguageText { get; set; }
public string Text { get; set; }
}
I'm trying to create an Edit view for MultiLanguageText which will also contain an editor for every item in the LocalizedTexts property. The form goes like this:
#using (Html.BeginForm("Edit", "MultiLanguageText", FormMethod.Post)) {
#Html.ValidationSummary(true)
<fieldset>
<legend>MultiLanguageText</legend>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
#Html.EditorFor(model => model.LocalizedTexts)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
The editor template I've created (in the file ~/Views/Shared/EditorTemplates/LocalizedText.cshtml) is the following:
<fieldset>
<legend>LocalizedText</legend>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.LanguageId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LanguageId)
#Html.ValidationMessageFor(model => model.LanguageId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MultiLanguageTextId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MultiLanguageTextId)
#Html.ValidationMessageFor(model => model.MultiLanguageTextId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Text)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Text)
#Html.ValidationMessageFor(model => model.Text)
</div>
</fieldset>
I'm testing with some pre-existing values and all the data is shown properly in the parent and in the child editors, when the page is shown. However, when I submit the form, all changes done inside any of the child editors are ignored.
My HttpPost method is this:
[HttpPost]
public ActionResult Edit(MultiLanguageText multilanguagetext)
{
if (ModelState.IsValid)
{
db.Entry(multilanguagetext).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(multilanguagetext);
}
My question is: How do I make it so that all values are posted, from both the parent model and its children model editors? (I've seen that other similar questions exist, but I've tried their solutions and they didn't seem to fix my problem.)
I'm testing your question. I think it's done and all values posted. But I think you need provide more information to fix your problem
After some trying, this is the solution that I found to work:
[HttpPost]
public ActionResult Edit(MultiLanguageText multilanguagetext)
{
if (ModelState.IsValid)
{
db.Entry(multilanguagetext).State = EntityState.Modified;
foreach (var local in multilanguagetext.LocalizedTexts) db.Entry(local).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(multilanguagetext);
}

Model not Binding to Action passing Null as value

I don't know why, the Model is not binding to the Create Action:
ViewModel:
public class AddressContactViewModel
{
// Primary properties
public int Id { get; set; }
public string Contact { get; set; }
// Navigation properties
[Display(ResourceType = typeof(HeelpResources), Name = "AddressContactViewModelNameLabel")]
[Required(ErrorMessageResourceName = "ErrorMsgRequiredField", ErrorMessageResourceType = typeof(HeelpResources))]
public int ContactType_Id { get; set; }
public int Address_Id { get; set; }
// ViewModel dropdownlists
public IEnumerable<SelectListItem> ContactTypeList { get; set; }
}
View:
#model Heelp.ViewModels.AddressContactViewModel
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Address_Id)
<fieldset>
<legend>AddressContactViewModel</legend>
<div id="year">
#Html.DisplayNameFor(m => m.ContactType_Id)
#Html.DropDownListFor(m => m.ContactType_Id, Model.ContactTypeList, HeelpResources.AddressContactViewModelContactTypesListDropDownFirstRecord)
#Html.ValidationMessageFor(m => m.ContactType_Id)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Contact)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Contact)
#Html.ValidationMessageFor(m => m.Contact)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Action Post:
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult ContactCreate(AddressContactViewModel contact)
{
var contactDto = Mapper.Map<AddressContactViewModel, AddressContactDto>(contact);
_addressContactService.Create(contactDto);
return RedirectToAction(MVC.Address.ContactList());
}
EDIT: Get:
public virtual ActionResult ContactCreate(int addressId)
{
var model = new AddressContactViewModel
{
Address_Id = addressId,
ContactTypeList = ContactTypeDropDownList()
};
return View(model);
}
When I submit the Form, I receive "null" in the contact parameter of the ContactCreate action, why is this happening?
Thanks
Unbelievable, I found the problem, the parameter of the action has the same name of a field in the ViewModel, a change of the parameter name and everything works find:
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult ContactCreate(AddressContactViewModel addressContact) // HERE I CHANGE FROM contact TO addressContact AND THE PROBLEM GET SOLVED
{
var contactDto = Mapper.Map<AddressContactViewModel, AddressContactDto>(addressContact);
_addressContactService.Create(contactDto);
return RedirectToAction(MVC.Address.ContactList(addressContact.Address_Id));
}
I ran into this same problem on my last app. try encompassing the button and the field you want to submit into the same div:
#model Heelp.ViewModels.AddressContactViewModel
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Address_Id)
<fieldset>
<legend>AddressContactViewModel</legend>
<div id="year">
#Html.DisplayNameFor(m => m.ContactType_Id)
#Html.DropDownListFor(m => m.ContactType_Id, Model.ContactTypeList, HeelpResources.AddressContactViewModelContactTypesListDropDownFirstRecord)
#Html.ValidationMessageFor(m => m.ContactType_Id)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Contact)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Contact)
#Html.ValidationMessageFor(m => m.Contact)
<input type="submit" value="Create" />
</div>
</fieldset>
}

Categories

Resources