Adding another form to a view on button clicked - c#

I have a Create view which contains a form. I want to give the user two options, save which simply saves the form and redirects to Index or add more tickets which will show another identical form in the view. I am unsure where to start with this, should I save the first ticket details then refresh the page? Or is there a way to have a second form hidden until add more tickets is selected then save all forms at once? I know this is quite vague but I've no idea where to start, but any advice would be great
Here is my model;
public class Ticket
{
public int TicketID { get; set; }
[Required]
[ForeignKey("Event")]
//foreign key
public int EventID { get; set; }
[Required]
public string Description { get; set; }
[Required]
public float Price { get; set; }
//navigation property
public virtual Event Event { get; set; }
//navigation property
public ICollection<OrderDetails> OrderDetails { get; set; }
}
Here is my view so far;
#model GeogSocSite.Models.Ticket
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Ticket</h4>
<hr />
#Html.HiddenFor(model => model.EventID)
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Price, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Price, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Price, "", 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>
#Html.ActionLink("Back to List", "Index")
</div>

My choice in this situation is using appropriate view model(as #StephenMuecke ) sugested) and using Bootsrtaap modal(here) to show hidden fields.

Related

Insert data into database from another models view

I have two model classes for my project,
public class BookModel
{
public Int64 ISBN { get; set; }
public DateTime AddedDate { get; set; }
public bool isActive { get; set; }
public int Quantity { get; set; }
public int? FormatID { get; set; }
public virtual FormatModel Format { get; set; }
}
and
public class FormatModel
{
public FormatModel()
{
Books = new HashSet<BookModel>();
}
public int ID { get; set; }
public string Value { get; set; }
public virtual ICollection<BookModel> Books { get; }
}
I want to create a modal in my Create.cshtml file to add a new format if the specified format doesn't exist.
How can I create a Submit button for my modal to add the format in FormatModel?
This is my view:
#model RookBookMVC.Models.BookModel
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.ReturnUrl = "/Book/Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create", "Book", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>BookModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.FormatID, "FormatID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="input-group col-md-10">
#Html.DropDownList("FormatID", null, "Select Book Format", htmlAttributes: new { #class = "form-control" })
<div class="input-group-append">
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#exampleModalCenter">
Add New
</button>
</div>
</div>
#Html.ValidationMessageFor(model => model.FormatID, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.ISBN, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ISBN, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ISBN, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Quantity, "", 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>
}
#using (Html.BeginForm("Create", "Format", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Add New Format</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
#Html.LabelFor(model => model.Format.Value, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Format.Value, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Format.Value, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<input type="submit" value="Create Format" class="btn btn-default" />
</div>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
after I click on the 'Create Format' button. it returns false for ModelState.IsValid and doesn't add any data to my database
What should I do for making 'Create Format' Button make a new Entity for Format and save it in my database?
for Additional I need to create two models via a single page
You might have to create a View Model and pass the view model property as parameter to the Action - Format/ Create post.
ViewModel property:
public string FormatValue { get; set; }
Modal view:
#Html.EditorFor(model => model.FormatValue, new { htmlAttributes = new { #class = "form-control" } })
Controller code with parameter as the same name as the view model property being passed from the modal form:
[HttpPost]
public ActionResult Create(string formatValue)
{
using (var dataContext = new YourDbContextModel())
{
FormatModel fmtModel = new FormatModel();
fmtModel.Value = formatValue;
// rest of your code to save data
}
}
public class MYViewModel{ public string FormatValue { get; set; } }
Create.cshtml
#model MYViewModel
<div>
#Html.EditorFor(model => model.FormatValue, new { htmlAttributes = new { #class = "form-control" } })
</div>
Do You Mean something Like that?
OR
public class MYViewModel{
public string FormatValue { get; set; }
Public BookModel Book {get; set;}
}

How to Bind ViewModel's object with the controller [duplicate]

This question already has answers here:
Asp.Net MVC: Why is my view passing NULL models back to my controller?
(2 answers)
Closed 6 years ago.
In my MVC application, I have a model class like below
public class PROJECT
{
[Display(Name = "Project No.")]
public string PROJECT_NO { get; set; }
[Display(Name = "Title")]
[DataType(DataType.MultilineText)]
[Required]
public string TITLE { get; set; }
[Display(Name = "Description")]
[DataType(DataType.MultilineText)]
public string DESCRIPTION { get; set; }
[Display(Name = "Remarks")]
public string REMARKS { get; set; }
}
And I have a ViewModel like this
public class ProjectViewModel
{
public PROJECT Project { get; set; }
public bool IsSelected { get; set; }
public COMPANY Companies { get; set; }
public CLIENT Clients { get; set; }
}
The ViewModel is the one I am creating the controller and views for. I have created the Index, Details, Delete and Create Views as well. Index, Details and Delete Views just work fine but Create controller model binding does not seem to be working. The ProjectViewModel object that comes in as input to the controller Create is null. How do I bind the ViewModel as a parameter to this object?
// POST: /Project/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ProjectViewModel project)
{
if (ModelState.IsValid)
{
db.PROJECTs.Add(project.Project);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CLIENT_ID = new SelectList(db.CLIENTs, "ID", "NAME", project.Project.CLIENT_ID);
ViewBag.COMPANY_ID = new SelectList(db.COMPANies, "ID", "NAME", project.Project.COMPANY_ID);
return View(project);
}
And here is the Create View
#model IMCCBluePrints.Models.ProjectViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PROJECT</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Project.PROJECT_NO, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Project.PROJECT_NO)
#Html.ValidationMessageFor(model => model.Project.PROJECT_NO)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Project.TITLE, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Project.TITLE)
#Html.ValidationMessageFor(model => model.Project.TITLE)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Project.DESCRIPTION, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Project.DESCRIPTION)
#Html.ValidationMessageFor(model => model.Project.DESCRIPTION)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Project.REMARKS, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Project.REMARKS)
#Html.ValidationMessageFor(model => model.Project.REMARKS)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Project.COMPANY_ID, "COMPANY_ID", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("COMPANY_ID", String.Empty)
#Html.ValidationMessageFor(model => model.Project.COMPANY_ID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Project.CLIENT_ID, "CLIENT_ID", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("CLIENT_ID", String.Empty)
#Html.ValidationMessageFor(model => model.Project.CLIENT_ID)
</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>
#Html.ActionLink("Back to List", "Index")
</div>
In your GET action instantiate your project class and try:
...
ProjectViewModel.project = new PROJECT();
...
return View(ProjectViewModel);
The Issue that when form submit project conflict with type Project as it is complex type, Just rename it to be model for example
public ActionResult Create(ProjectViewModel model)
try this and it will work, i've tried by myself.

Asp.Net MVC 5 Html.DropDownList is not validating

I've been stuck on this problem for a while now and can't seem to find anything online that helps.
I have a Html.DropDownList in an Editor Template. I use that template in my form and don't select anything for the dropdownlist. When I click submit, I expect the form to notify me that the required dropdownlist doesn't have a value selected, but it doesn't. What am I doing wrong?
Here are the View Models:
public class RequestCreateViewModel
{
public int ID { get; set; }
public TesterLocationCreateViewModel TesterLocationCreateViewModel { get; set; }
....
public RequestCreateViewModel()
{
}
}
public class TesterLocationCreateViewModel
{
public int ID { get; set; }
[Required]
[UIHint("OEM")]
public string OEM { get; set; }
[Required]
[DisplayName("City")]
public string LocationCity { get; set; }
public TesterLocationCreateViewModel()
{
}
}
Here's a snippet of the Create.cshtml
#model WdcTesterManager.Models.Request
#{
ViewBag.Title = "Create Request";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create Request</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.EditorFor(model => model.TesterLocationCreateViewModel)
</div>
</div>
}
Here's the TesterLocationCreateViewModel.cshtml (Editor Template):
#model WdcTesterManager.Models.TesterLocationCreateViewModel
<div class="col-md-6">
<h4>Tester Location</h4>
<div class="container-fluid">
<div class="form-group">
#Html.LabelFor(model => model.OEM, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("OEM", (SelectList)ViewBag.OemList, "Choose one", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.OEM, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LocationCity, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.LocationCity, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LocationCity, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
When I submit the form without filling anything out, I get a validation error for the City but nothing for the OEM. Any ideas?
#StephenMuecke pointed out that something looked wrong with the code, since the code seemed to be referencing the Request model rather than the Request View model.
So, I took a second look at the code and realized that the Create.cshtml was using the Request model rather than the RequestCreateViewModel.
I'm getting the correct validation errors after changing the Create.cshtml to use the RequestCreateViewModel:
#model WdcTesterManager.Models.RequestCreateViewModel

How to create or render a List of entity for another entity in ASP.NET MVC 5?

How can I render (Scaffold) list of Tags for a Location having this model in my application:
I'm using Entity Framework 6.1.
I want to save a list of Tags against a location and render it back in View and I'm not able to do that!
public class Tag
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
// Navigation
public virtual Location Location { get; set; }
}
public class Location
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int LocationId { get; set; }
public virtual string LocationName { get; set; }
// Navigation
public virtual List<Tag> Tags { get; set; }
}
Right now the view just contains the Location name for input:
View -Create Location
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Location</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.LocationName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LocationName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LocationName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tags, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Tags, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Tags, "", 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>
}
It renders fine but doesn't save any tag in database:
Here is the problem
When I'm trying to render back the tags in edit view, it shows like this:
Appreciate any help!
What you're looking for is a custom view/edit templates for your "Tags" property. Refer to this: http://buildstarted.com/2010/09/10/overriding-displayfor-and-editorfor-to-create-custom-outputs-for-mvc/

MVC 5 Razor - Label isn't updated from class annotation

I have a simple example.
Two class. User and Company like :
public class User() {
public int UserID { get; set; }
[Display(Name = "User name")]
public string Name { get; set; }
[Display(Name = "Company")]
public int CompanyID { get; set; }
public virtual Company Company { get; set; }
}
public class Company() {
public int CompanyID { get; set; }
[Display(Name = "Company")]
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
My problem is in the Create and the Edit views of the User.
The label for "Name" is displayed correctly in "User name" but the label for "CompanyID" stay displayed at "CompanyID" (the drop down list is created correctly with all Companies). I want the label display "Company" like I make it in the class.
I've try to change my view but all I do block compilation so I'm lost.
I'm begginer in MVC so excuse me if it easy to do but I don't see it.
Edit (add Create View code) :
#model Intranet3.Models.User
#{
ViewBag.Title = "Add a user";
}
#using (Html.BeginForm(null, null, FormMethod.Post, htmlAttributes: new { #class = "form-horizontal form-bordered" })) {
#Html.AntiForgeryToken()
<div class="row-fluid">
<div class="span12">
<div class="box">
<div class="box-title">
<h3>
<i class="icon-table"></i>
New
</h3>
</div>
<div class="box-content nopadding">
<div class="form-horizontal">
#Html.MyValidationSummary()
<div class="control-group #Html.ClassErrorFor(model => model.Name)">
#Html.LabelFor(model => model.Name, new { #class = "control-label" })
<div class="controls">
#Html.EditorFor(model => model.Name)
#Html.MyValidationMessageFor(model => model.Name)
</div>
</div>
<div class="control-group #Html.ClassErrorFor(model => model.CompanyID)">
#Html.LabelFor(model => model.CompanyID, "CompanyID", new { #class = "control-label" })
<div class="controls">
#Html.DropDownList("CompanyID", String.Empty)
#Html.MyValidationMessageFor(model => model.CompanyID)
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create</button>
<button onclick="location.href='#Url.Action("Index","User")'" type="button" class="btn">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
}
Edit 2 :
Problem solved by delete the string force in Labels.
So this :
#Html.LabelFor(model => model.CompanyID, "CompanyID", new { #class = "control-label" })
Need to be
#Html.LabelFor(model => model.CompanyID, new { #class = "control-label" })
Why have u passed parameter CompanyId
#Html.LabelFor(model => model.CompanyID, "CompanyID", new { #class = "control-label" })
Should be
#Html.LabelFor(model => model.CompanyID, new { #class = "control-label" })
#Html.TextBoxFor(c => c.CompanyID, new { data_bind = "text:Contacts.FirstName", #class = "form-control" })
If you have knockoutjs binding

Categories