This is what I've had in mind but of course it doesn't work.
#{
var textBoxData = form.find('input[name="textboxList"]').val();
}
<input type="button" value="Add" title="Add" onclick="location.href='#Url.Action("Create_Add", "Controller", new { textboxList = textBoxData })'" />
How should I pass this? Controller action name and parameter are correct. Just that I don't know how to get the value entered in textbox...
I have trouble with saving a form within a form, so someone suggested this solution. Proxy code would be:
<firstForm>
textboxfor Name
dropdownfor DType
If DTypeDDL value is "List" then
<secondForm>
textboxfor nameOfItem
submitSecondForm (using that method i mentioned above)
</secondForm>
End If
submitFirstForm
</firstForm>
I've been trying to save 2 forms for quite a while now but no luck. This is basically my last resort.
First of all, you should go with a viewmodel oriented html file since you are using MVC (Model, View, Controller):
Create a viewModel:
public class ExampleViewModel
{
public ExampleViewModel()
{
}
public virtual string TextBoxData { get; set; }
}
After, code your html using the viewmodel as model:
#model Models.Views.ExampleViewModel
#using (Html.BeginForm())
{
<div class="editor-row">
<div class="editor-label">
#Html.LabelFor(model => model.TextBoxData)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TextBoxData)
</div>
</div>
<input type="submit" value="submit" />
}
and your controller:
public ActionResult Example()
{
ExampleViewModel model = new ExampleViewModel();
return This.View(model);
}
[HttpPost]
public ActionResult Example(ExampleViewModel model)
{
string infoEntered = model.TextBoxData;
// Do something with infoEntered
}
Hope this will help you!
If you're using view models, check out this answer: MVC sending data from View to Controller
If you're only interested in sending the data from an input to the action method without view models, you can do that as well:
View:
#using (Html.BeginForm("Edit", "Some", FormMethod.Post))
{
<input type="text" id="myTextBox" name="myTextBox" />
<input type="submit" value="Submit" />
}
Notice the BeginForm line. The first parameter is the Action I want the data to go to, which I named Edit. The next parameter is the Controller I am using, which I named SomeController. You don't add the Controller bit to the name when you're referencing the Controller in BeginForm. The third parameter is telling the form to use the POST method when sending the data to the server.
Controller:
public class SomeController
{
[HttpPost]
public ActionResult Edit(string myTextBox)
{
// Do what you want with your data here.
}
}
If you added more inputs (again, without a view model here), you can add them as parameters to the Edit method. This isn't really the preferred method, though. Look into using a view model. ScottGu has a nice blog post on doing what you need, using view models:
http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx
Related
I want to show one TextBox. In that if give any input string and button clicked it should so like this
hai , what is ur name
[TextBox]
welcome,ur name is "xyz"
I am new in MVC. Please help me to do this.
View
#{
ViewBag.Title = "MyPage";
}
<h2>Mymethod</h2>
<h3>#ViewBag.Message</h3>
#Html.TextBox("Name")
<form method="post">
<input type="submit" value="Submit" name="btn" />
</form>
HomeController.cs
public ActionResult Mymethod()
{
ViewBag.Message = "Hello what is ur name ??? ";
return View();
}
There are many ways to do this to accomplish what you want. I will provide you with a simplistic approach, please modify and change it to fit in with your scenario.
I would normally recommend using a view model above any other way, for example using a single string value or using FormCollection or ViewBag. They can work but I prefer to use view models.
I answered a question on what view models are and what they are supposed to do, please read it:
What is ViewModel in MVC?
First you will create a view model that will handle your input data, like first name, last name, age, etc. You will then pass this view model through to the view. In your example I will only include name:
public class ViewModel
{
public string Name { get; set; }
}
In your Create action method you will instantiate this view model and pass it to the view. And when you click on the button to submit the form then the post action method will receive this view model as input parameter:
public ActionResult Create()
{
ViewModel model = new ViewModel();
return View(model);
}
[HttpPost]
public ActionResult Create(ViewModel model)
{
if (!ModelState.IsValid)
{
// If validation fails send the view model back to the view and fix any errors
return View(model);
}
// Do what you need to do here if there are no validation errors
// In your example we are posting back to the current view to
// display the welcome message
return View(model);
}
And then finally you view will look like this:
#model Project.Models.ViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Name)
<button type="submit">Submit</button>
if (!string.IsNullOrWhiteSpace(Model.Name))
{
<p>welcome, your name is #Model.Name</p>
}
}
Please spend some time reading through the many online tutorials on ASP.NET MVC.
Modify your current view to
#using(Html.BeginForm("ControllerName","Mymethod",FormMethod.Post))
{
<input type="submit" value="Submit" name="btn" />
}
Add another action method in your controller like this :
[HttpPost]
public ActionResult Mymethod(FormCollection form)
{
string Name = form["Name"];
Viewbag.Name = Name;
return View()
}
Then add view to this controller and write this into it.
Hi , Your Name is #Viewbag.Name
You should wrap your form in form tag. It is a form after all. So when you click submit, you are submitting the form.
<form method="post">
<h2>Mymethod</h2>
<h3>#ViewBag.Message</h3>
#Html.TextBox("Name")
#if (!String.IsNullOrEmpty(ViewBag.Name))
{
<h3>
welcome,ur name is #ViewBag.Name
</h3>
}
<input type="submit" value="Submit" name="btn" />
</form>
On the controller, you need to add HttpPost handler for your Mymethod action. This is where your web server is accepting the form you've submitted.
[HttpPost]
public ActionResult Mymethod(string name)
{
ViewBag.Message = "Hello what is ur name ???";
ViewBag.Name = name;
return View();
}
I'm just wondering what does the "For" in the .LabelFor or .EditorFor in the mvc html helper extension mean? I understand the parameter takes in a lambda expression but I can't work out what the "For" means?
Here is my simple cshtml file so you can see what I am looking at
#model MvcTest.Models.Update
#{
ViewBag.Title = "Edit";
}
<h1>Update</h1>
#using (Html.BeginForm()) {
#Html.ValidationSummary()
<fieldset>
<legend>Update profile</legend>
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Html.LabeFor() returns an HTML label element and the property name of the property that is represented by the specified expression.
For means to bind the control with that specific Model Property in strongly typed views.
For Example:
I have a model with only two properties.
public class MyModel
{
public string Name {get;set;}
public int Id { get; set;}
}
Now we create a view which is strongly typed:
#model AppNameSpace.Models.MyModel
#using (Html.BeginForm("MyAction","My",FormMethod.Post))
{
#Html.TextBoxFor(m=>m.Name)
#Html.HiddenFor(m=>m.Id)
<input type="submit" name="Save" value="Save"/>
}
Now in the from the model object will be posted with values of form elements in model properties.
public class MyController : Controller
{
[HttpGet]
public Action Result SomeAction()
{
return View();
}
[HttpPost]
public Action Result SomeAction(MyModel model)
{
string name = model.Name;// here you will have name value which was entered in textbox
return View();
}
}
If i say:
Html.TextBoxFor(x=>x.Name)
now when the from will be posted at the action with model , the text box value will be posted in the Name property whatever we have entered in the textbox. This is how strongly typed views work in asp.net mvc.
The same is the case for other Html helpers like Html.LabelFor(), Html.HiddenFor they are mostly used in strongly typed views, to reflect the values of from elements in action on form post of model.
For furthers detailed study,you might want to read more about Html Helpers here:
http://stephenwalther.com/archive/2009/03/03/chapter-6-understanding-html-helpers
http://www.dotnet-tricks.com/Tutorial/mvc/N50P050314-Understanding-HTML-Helpers-in-ASP.NET-MVC.html
https://www.simple-talk.com/dotnet/asp.net/writing-custom-html-helpers-for-asp.net-mvc/
The for is referring to the property that you're creating it on. #Html.LabelFor(model => model.Title) is a label for the Title field on the model. More specifically, it's for the Expression that you provide it.
I have a list of Objects which I want to modify on my View, I have built a View Model to contain the list of objects:
public class TrainerListViewModel
{
public List<Trainer> Trainers { get; set; }
}
and I send a list of Trainers to the view from the controller:
public virtual ActionResult Social()
{
var Trainers = new TrainerListViewModel();
Trainers.Trainers = (from t in _db.Trainers select t).ToList();
return View(Trainers);
}
and here is my view:
#model XStreamingFitness.ViewModels.TrainerListViewModel
#using (Html.BeginForm("Social", "Participant", FormMethod.Post))
{
for (int i = 0; i < Model.Trainers.Count; i++)
{
<div class="formSep">
<div class="editor-label">
#Html.LabelFor(m => m.Trainers[i].permissionPostFacebook)
</div>
<div class="editor-field">
#Html.EditorFor(m => m.Trainers[i].permissionPostFacebook)
#Html.ValidationMessageFor(m => m.Trainers[i].permissionPostFacebook)
</div>
</div>
}
<input type="submit" value="Save Settings" name="Submit" />
}
now here is the POST controller method:
[HttpPost]
public virtual ActionResult Social(TrainerListViewModel Trainers)
{
return RedirectToAction("Profile");
}
but everytime I submit, the Trainers model is empty and I am not sure why this could be happening.
This question has been asked before here at SO I suggest you check mvc3 submit model empty, its the same principals as the problem you are having.
See the snippet from the post.
I see people writing the following lambda expression modelItem =>
item.SomeProperty in their views very often and asking why the model
binder doesn't correctly bind collection properties on their view
models.
This won't generate proper name for the checkbox so that the default
model binder is able to recreate the Settings collection. I would
recommend you reading the following blog post to better understand the
correct format that the model binder expects.
-By Darin Dimitrov
It is to do with the way you are building your form he goes to suggest you use Property Editor Templates for the Trainer object.
This should then work.
Hope it helps
I have an Action result method that is supposed to add data into a database when a button is clicked. Although, when I click on the button to add the data using the AddDetails Action method I get the following Error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /home/AddDetails
Controller:
namespace //not included
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Details()
{
return View();
}
[HttpPost]
public ActionResult AddDetails(Customer customer)
{
if (ModelState.IsValid)
{
var db = new CustomerContext();
db.Customers.Add(new Customer
{
ItemName = customer.ItemName,
Price = customer.Price
});
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
}
}
View:
#{
ViewBag.Title = "Details";
}
<h2>Add Items</h2>
<div class="container">
<form class="form-signin" role="form">
<h2>Please type in Item Name and price paid</h2>
<input type="text" class="form-control" placeholder="Name" required autofocus />
<input type="number" pattern="[0-9]+([\.|,][0-9]+)?" step="0.01" min="0" class="form-control" placeholder="Price" required autofocus />
<input type="button" class="btn btn-lg btn-primary btn-block" value="Add" onclick="location.href='#Url.Action("AddDetails", "home")'" />
</form>
</div>
You're posting to /Customers/Details but your action is /Customers/AddDetails. You can tell your form to specifically post to /Customers/AddDetails or you can rename your AddDetails action to Details. It's fine to have both a GET and POST action called Details. When you issue a post request, the action with the HttpPost attribute will be hit. When you issue a get request, the action with no attribute or a HttpGet attribute will be hit.
If you want to keep the name 'AddDetails', your form should look like this (I'm using Razor instead of plain HTML):
#using (Html.BeginForm("AddDetails", "Home", FormMethod.Post) {
<h2>Please type in Item Name and price paid</h2>
<input type="text" class="form-control" placeholder="Name" required autofocus />
<input type="number" pattern="[0-9]+([\.|,][0-9]+)?" step="0.01" min="0" class="form-control" placeholder="Price" required autofocus />
<input type="submit" class="btn btn-lg btn-primary btn-block" value="Add" />
}
I guess, I don't type fast enough... As Neil mentioned, use the Html Helper, though I recommend using named parameters so that you don't confuse which is the Action and Controller:
#using (Html.BeginForm(
actionName: "AddDetails",
controllerName: "Customer",
method: FormMethod.Post,
htmlAttributes: new { #class = "myclass" }))
Also, to help keep the routes correct (and not need to rely on "magic strings"), I highly recommend using T4MVC. Then your form will look like this:
#using (Html.BeginForm(MVC.Customer.AddDetails(), ...)
And the Razor view will not even render if the Action does not exist. It is also easier writing the form because Intellisense will help you find the Controller and Action you want.
Make These changes in your code.
namespace //not included
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult AddDetails()
{
Customer newCustomer = new Customer();
return View(newCustomer);
//right click this action and choose addview and use strongly typed
//view by choosing Customer class
}
[HttpPost]
public ActionResult AddDetails(Customer customer)
{
//whatever you want here
}
}
}
You will get a view with all the syntax for form and input textBoxes. Just few minor additions to meet your UI requirement will be needed.
Feel free to ask more doubts if any.
You need to give Action name in Html.BeginForm like this #using (Html.BeginForm("AddDetails", "Home", FormMethod.Post)
Or
change you controller action name to Details instead of AddDetails
I am new to MVC3 and am trying to write a blog application as a learning tool.
I've created a database object for the blog post and generated a controller using the Controller with Read/Write actions and views using Entity Framework to control the entity.
I'm having troubles with the edit commands. There are about 6 properties for a blog post but I only want to allow the edit to modify the title and content of the post. My code is as follows:
public ActionResult Edit(int id)
{
blog_Post blog_post = db.blog_Post.Find(id);
return View(blog_post);
}
//
// POST: /Post/Edit/5
[HttpPost]
public ActionResult Edit(blog_Post blog_post)
{
if (ModelState.IsValid)
{
db.Entry(blog_post).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(blog_post);
}
#model BlogVersion1._0.blog_Post
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>blog_Post</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PostContent)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PostContent)
#Html.ValidationMessageFor(model => model.PostContent)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
The problem that comes about is in the public ActionResult Edit(blog_Post blog_post) method. In the Edit(int id) method, I have put a breakpoint in and I can see that blog_post is being properly passed to the view (including all of its properties populated).
But the blog_post being returned to the [HttpPost] method is missing properties for UserId, DateCreated, etc. An exception is obviously thrown on the db.SaveChanges call as required foreign keys are missing.
How do I ensure that all properties are returned to the second edit method to properly make the update?
Because you are not sending the values of those elements from your form when you do the POST ing. One way to fix this is to keep them inside the form using Hidden Variables
#using(Html.BeginForm())
{
#Html.EditorFor(model => model.Title)
#Html.HiddenFor(model => model.UserId)
<input type="submit" />
}
I think the clean solution is to "Dont use the Domain model in the view, Use a ViewModel with necessary properties for the View. In this case, obviously CreatedDate should not be something the View should supply. It should be something the code will be filled to the object.
So create a ViewModel for this
public class BlogPostViewModel
{
public int ID { set;get;}
public string Title { set;get;}
public string Description { set;get;}
}
and use this for transfering data from View to controller and viceversa
public ActionResult Edit(int id)
{
var domainObject=repo.GetPost(id);
var viewModel=new BlogPostViewModel();
viewModel.ID=domainObject.ID;
viewModel.Title=domainObject.Title;
//map other REQUIRED properties also
return View(viewModel);
}
Your view will be strongly typed to this
#model BlogPostViewModel
#using(Html.BeginForm())
{
#Html.EditorFor(model => model.Title)
#Html.HiddenFor(model => model.Description)
<input type="submit" />
}
In the POST action,map it back to the domain object and save
[HttpPost]
public ActionResult Edit(BlogPostViewModel model)
{
if(ModelState.IsValid)
{
var domainObject=new blog_Post();
domainObject.Title=model.Title;
domainObject.ModifiedDate=DateTime.Now;
//set other properties also
repo.Update(domainObject);
return RedirecToAction("Success");
}
return View(model);
}
Instead of manually mapping properties one by one you can consider using AutoMapper library which does this for you in one line of code!
Just add hidden fields for all other, non-editable properties.
#Html.HiddenFor(model => model.Id)
These field will be included in POST and hence, model binder will correctly put them into your blog_post instance.
On the other side, you should really be using view models - simple POCO classes that will be models for your views. Using entity models directly is not recommended.
Here's some info on that:
ASP.NET MVC ViewModel Pattern
http://stephenwalther.com/archive/2009/04/13/asp-net-mvc-tip-50-ndash-create-view-models.aspx
The model binder will only populate the properties that are POSTed in the HTTP request. Your view only contains Title and PostContent.
You either need to include hidden fields for each of the missing properties. Or just the ID property and then do a database lookup for the rest.
For your case, I think You should rather use the HtmlHelper extension method "EditorForModel" instead of calling "EditorFor" for each property. You are complicating your life using EditorFor on each property (and as gred84 is saying, it doesn't post the non displayed properties in the HTTP request in you context).
In your blog_Post model class you should flag each property that you don't want to be edited with the attribute [HiddenInput(DisplayValue = false)]
Then instead of all your code in the view, you can simply have (simplified - without validation summary)
#using (Html.BeginForm())
{
#Html.EditorForModel()
<input type="submit" value="Save" />
}