I need pass data displayed on Razor View page by ViewModel, to Controller. Values entered by user in #Html.EditorFor are passing successfully, but data from #Html.DisplayFor for are not. What I missing?
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<table>
<tr>
<td style="text-align: center; vertical-align: middle;">
<div class="main-container">
<h3 class="main-title" id="bold-title">
#Html.DisplayFor(model => model.EmailReceiver)
</h3>
<h3 class="main-title" id="thin-title">
#Html.DisplayFor(model => model.PurchaseDesc)
</h3>
#Html.EditorFor(model => model.EmailSender, new { htmlAttributes = new { #placeholder = "Your e-mail", #id = "e-mail" } })
#Html.EditorFor(model => model.CardNumber, new { htmlAttributes = new { #placeholder = "Your card number", #id = "card" } })
#Html.EditorFor(model => model.CardValidDate, new { htmlAttributes = new { #placeholder = "MM / YYYY", #id = "date" } })
#Html.EditorFor(model => model.CVV, new { htmlAttributes = new { #placeholder = "CVV", #id = "cvv" } })
<button class="button" id="pay-button" type="submit">
<div id="price">Pay #Html.DisplayFor(model => model.TotalAmount)$</div>
<br>
<div id="ok">Complete!</div>
</button>
</div>
</td>
</tr>
</table>
}
You'll need to add a hidden field to get those read-only values passed back. Use #Html.HiddenFor to generate an equivalent hidden field.
Related
The popup code works just fine when I create it on the other view pages, it only throws an error on the index page, I'm having an issue with the model. I'm new to ASP.NET MVC 5 and Entity Framework 6. Any guidance will be most appreciated.
This is my code:
#model IEnumerable<LogInTest1.Models.Credentials>
I want to create a popup here instead of redirecting it to the create page.
<p>
#Html.ActionLink("Create New", "Create")
</p>
Button code:
<button class="btn btn-default" onclick="AddData()">Click to Create ยป</button>
<script>
function AddData() {
$("#MyModal").modal();
}
</script>
Popup code:
<div class="modal fade" id="MyModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
#*#model LogInTest1.Models.Credentials*#
#*#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Credentials</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.userName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.userName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.userName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.password, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}*#
#*}*#
</div>
</div>
</div>
</div>
Table code at index view:
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.userName)
</th>
<th>
#Html.DisplayNameFor(model => model.password)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.userName)
</td>
<td>
#Html.DisplayFor(modelItem => item.password)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.empId }) |
#Html.ActionLink("Details", "Details", new { id = item.empId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.empId })
</td>
</tr>
}
</table>
Simply, you can use an action link like this:
Create New
Your Index view having Model list but your popup using single model so you have to create the object to your popup model#{var createModel = new LogInTest1.Models.Credentials()} then your all poup codes should look like this #Html.LabelFor(cmodel => createModel.userName, htmlAttributes: new { #class = "control-label col-md-2" })
I am new to MVC having developed in WebForms for a long time and I'm following an online course to update an existing WebForms project to an MVC project. Most of the things are working without a hitch but I have found one thing in my course that I just cannot understand.
In my course the presenter does the following:
CreateEdit.cshtml:
<label>Description</label>
#Html.TextAreaFor(x => x.Desc)
</div>
var list = new List<SelectListItem>()
{
new SelectListItem() { Text="Look at me", Value="1" }
}
<div>
#Html.DropDownListFor(x => x.Category, list, new { #class = "form-control" }
</div>
Regardless of what I do the "var list ..." part doesn't work in my Visual Studio.
Does anyone know what I'm doing wrong or why this way of typing doesn't work??
------ Edited with the full page included: ----------
#model CypherMVC.Models.Task
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">
Create a New Task<br />
<small>These are issues your team members should take care of - ASAP!</span></small>
</h1>
</div>
</div>
<div class="row">
<div class="col-md-12">
#using (Html.BeginForm("CreateEdit", "Task"))
{
<div class="form-group">
#Html.LabelFor(x => x.Title)
#Html.TextBoxFor(x => x.Title, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.Description)
#Html.TextAreaFor(x => x.Description, new { #class = "form-control", rows = 5 })
</div>
var list = List<SelectListItem>()
{
new SelectListItem() { Text="Look at me", Value="1" }
}
<div class="form-group">
#Html.LabelFor(x => x.CategoryId, "Category")
#Html.DropDownListFor(x => x.CategoryId, list, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.DueDate, "Due Date")
#Html.TextBoxFor(x => x.DueDate, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.AssignedToId, "Assigned To")
#Html.TextBoxFor(x => x.AssignedToId, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.AssociatedMessageId, "Associated Message")
#Html.TextBoxFor(x => x.AssociatedMessageId, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.Notes)
#Html.TextAreaFor(x => x.Notes, new { #class = "form-control", rows = 5 })
</div>
<div class="form-group">
#Html.LabelFor(x => x.Completed, "Is Complete")
#Html.CheckBoxFor(x => x.Completed)
</div>
<div class="form-group">
<input class="btn btn-primary pull-right" type="submit" text="Submit">
</div>
}
</div>
</div>
Try to wrap it with
#{
var list = new List<SelectListItem>()
{
new SelectListItem() { Text="Look at me", Value="1" }
};
}
All C# code inside a razor template needs to go inside code blocks (#{ ... }). Here are the official docs on this.
Your example should look like this:
<label>Description</label>
#Html.TextAreaFor(x => x.Desc)
</div>
#{
var list = new List<SelectListItem>()
{
new SelectListItem() { Text="Look at me", Value="1" }
};
}
<div>
#Html.DropDownListFor(x => x.Category, list, new { #class = "form-control" }
</div>
UPDATE: Since Mr.Glaurung says that the code from the course he is following is getting this to work without the code block syntax, I suspect the code is already inside a razor control structure.
The code examples below would also work. Since we don't see the whole template in your example, we can't know for sure.
Inside a loop:
#{
var someList = new List<string>() {"1", "2", "3"};
}
#foreach (var s in someList)
{
<h1>Some HTML</h1>
//C# code
var list = new List<int>() {1, 2, 3};
<h2>More HTML</h2>
}
Or inside a if statement:
#if (true)
{
<h1>Some HTML</h1>
//C# code
var list = new List<int>() { 1, 2, 3 };
<h2>More HTML</h2>
}
I have a scenario where in I need to store multiple rows in a single table.Let me explain it in detail.
I have a table Price which has 4 columns, ID, ModelID, AppSettingID,Amount.
I am looking for inserting multiple values to the table where
ID would be the Primary Key.
ModelID would be same for all the rows.
AppSettingID and Amount will be different for all the rows and would be based on the selection user does on the view.
I have bound the AppSettingID to different combo boxes on the view as I have it categorized in the database.
This is what I am doing right now.
View:
<div class="editor-label">
#Html.LabelFor(model => model.ModelID, "Model")
</div>
<div class="editor-field">
#Html.DropDownList("ModelID", String.Empty)
#Html.ValidationMessageFor(model => model.ModelID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AppsettingID, "Mobile Condition")
</div>
<div class="editor-field">
#Html.DropDownList("Mobile Condition", new SelectList(ViewBag.ConditionID, "Text", "Value"))
#Html.ValidationMessageFor(model => model.AppsettingID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Amount)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Amount)
#Html.ValidationMessageFor(model => model.Amount)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AppsettingID, "Tennure")
</div>
<div class="editor-field">
#Html.DropDownList("Tennure", new SelectList(ViewBag.AppsettingID, "TexT", "Value"))
#Html.ValidationMessageFor(model => model.AppsettingID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Amount)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Amount)
#Html.ValidationMessageFor(model => model.Amount)
</div>
<p>
<input type="submit" value="Create" />
</p>
Controller:
public ActionResult Create()
{
//ViewBag.AppsettingID = db.Appsettings.Select(r => r.ID).Distinct();
ViewBag.ModelID = new SelectList(db.Models, "ID", "Name");
//ViewBag.Tennure = db.Appsettings.Select(s => s.Type == "Tennure").Distinct();
IQueryable<Appsetting>TennureIDs = db.Appsettings.Where(s => s.Type == "Tennure").Distinct();
IQueryable<Appsetting> Conditions = db.Appsettings.Where(s => s.Type == "Mobile Condition").Distinct();
List<SelectListItem> items = new List<SelectListItem>();
foreach (var t in TennureIDs)
{
SelectListItem s = new SelectListItem();
s.Text = t.ID.ToString();
s.Value = t.Value.ToString();
items.Add(s);
}
ViewBag.AppsettingID = items;
List<SelectListItem> conds = new List<SelectListItem>();
foreach (var t in Conditions)
{
SelectListItem s = new SelectListItem();
s.Text = t.ID.ToString();
s.Value = t.Value.ToString();
conds.Add(s);
}
ViewBag.ConditionID = conds;
return View();
}
//
// POST: /Price/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Price price, FormCollection form)
{
if (ModelState.IsValid)
{
int test = Convert.ToInt16(form["Mobile Condition"]);
price.AppsettingID = test;
db.Prices.Add(price);
db.SaveChanges();
return RedirectToAction("Index");
}
//ViewBag.AppsettingID = new SelectList(db.Appsettings, "ID", "Type", price.AppsettingID);
//ViewBag.ModelID = new SelectList(db.Models, "ID", "Name", price.ModelID);
return View(price);
}
I hope this solution will help you
The following is a razor page, here I have displayed the model in table format
#model List<MyModel>
<h2>Create</h2>
#using (Html.BeginForm())
{
<table>
<tr>
<th>
Model ID
</th>
<th>
App Setting ID
</th>
<th>
Amount
</th>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>
#Html.TextBoxFor(x => Model[i].ModelID)
</td>
<td>
#Html.TextBoxFor(x => Model[i].AppsettingID)
</td>
<td>
#Html.TextBoxFor(x => Model[i].Amount)
</td>
</tr>
}
</table>
<input type="submit" />
}
When user clicks the submit button, it will pass the model to the controller
Controller
[HttpPost]
public ActionResult Create(List<MyModel> m)
{
// Do Coding
return View("Create", m);
}
I have created a person register form. In this form I have added one partial view which shows list of persons. I have added a paging on this form. Now I want to implement search functionality.
My form looks like following
Here I want to implement search functionality. but the issue is I have two buttons on a form i.e. Create and search. when I click on search button it gives me required field validation of form register.cshtml.
Here is my code for register.cshtml
#model WebLess.Models.PersonModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.firstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.firstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.firstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.lastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.lastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.lastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
<div class="form-group">
#if (ViewBag.Message != null)
{
<span class="text-success">#ViewBag.Message</span>
}
</div>
<div class="form-group">
#Html.Partial("list", Model.listOfPerson)
</div>
</div>
}
Here is my list.cshtml.
#model PagedList.IPagedList<WebLess.Models.PersonModel>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#using (Html.BeginForm("Register", "Person", FormMethod.Get))
{
<p>
Find by name: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
First name
</th>
<th>
Last name
</th>
<th>
E-mail Address
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.firstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.lastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.email)
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Register",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
How can I implement search functionality?
You can move the list partial view outside of the creation form, then put the search functionality into its own form inside the list partial view (they're completely separate anyway, so should be separate). This should then achieve what you're looking for.
Nesting of forms is not allowed and may result in an undefined behavior between browsers.
Use two seperate form instead of nested form
like steve says "move the list partial view outside of the creation form" would result into two separate form instead of one form inside another form
like
#using (Html.BeginForm())
{
}
#using (Html.BeginForm("Register", "Person", FormMethod.Get))
{
}
instead of (a form in a form is not allowed )
#using (Html.BeginForm())
{
#using (Html.BeginForm("Register", "Person", FormMethod.Get))
{
}
}
I am having a issue passing a variable from a controller to a view. I have created an actionresult that allows users to add meals to a restaurant menu. I need the menuID in a html action link to access the menu details page. But when I run the page ViewData["MenuID"] returns as null even though menuID has a value in the controller action result. Is there another way to send data from a controller to a view?
Create action result
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(MealviewModel model, int? menuID)
{
if (menuID == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
else
{
ViewData["MenuID"] = menuID;
if (ModelState.IsValid)
{
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var currentUser = manager.FindById(User.Identity.GetUserId());
var currentrestaurant = (from r in db.Restaurants
where r.UserID == currentUser.Id
select r).First<Restaurant>().id;
var currentmenu = (from m in db.Menus
where m.Restaurantid == currentrestaurant
select m).First<Menu>().Id;
var meal = new Meal() { Name = model.Name, Description = model.Description, Price = model.Price, MenuID = menuID, Catergory = model.Catergory };
db.Meals.Add(meal);
db.SaveChanges();
return RedirectToAction("Create", new { MenudID = menuID });
}
}
return View();
}
Create CSHTML Page
#model BiteWebsite.Models.MealviewModel
#using BiteWebsite.Models;
#{
ViewBag.Title = "Add Items to Your Menu";
}
<h2>Add Items to Your Menu</h2>
#using (Html.BeginForm())
{
var ID = ViewData["MenuID"];
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Catergory, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Catergory", new SelectList(new[] {"Chef Specials","Deserts","Drinks","Main Courses","Sides",
"Starters" ,"Salads"}))
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { #cols = "80", #rows = "4" })
#Html.ValidationMessageFor(model => model.Description)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Price, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Price)
#Html.ValidationMessageFor(model => model.Price)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Add Item" class="btn btn-default" />
<div class="btn btn-default">
#Html.ActionLink("View Menu", "Menu", "Details", new { Id = ID })
</div>
</div>
</div>
</div>
}
because you are returning a redirecttoaction. you should use tempdata or session variable to save the value in the menuid and that should hold the value when it's a redirecttoaction.
When you do a redirect you lose the contents of ViewData. TempData is preserved though, so you can use that if a redirect is a possibility. I don't know about ViewBag so you might test that.
You already are passing other values through a view model, why not make a new property in that viewmodel and pass it along to the view?