how to have two forms in one View, working separately and well, in ASP.NET MVC 3? - asp.net-mvc-3

I have two action methods. One of them submits the inserted data of a "new product", and the other form must upload the photos of that product. Each one has it's own Model, View, and each one calls it's own Action from controllers, which are completely separate.
But I need to have the forms both in just one view.
I've done this by using #html.action() to render the "Upload" action's View in the "Insert New Product" action's View.
The problem is, both of the submit buttons call the same "Insert New Product" action :|
Take a look. Here's the first View:
#using (Html.BeginForm("Insert_New_Product", "Admin", FormMethod.Post))
{
// Inputs, Validation Messages and all those stuff ...
<input type="submit" name="Insert_New_Product" value="Add New Product" />
// Here, I render the "Upload" View :
#Html.Action("Upload", "UploadImage")
}
The "Upload" View looks like this :
#using (Html.BeginForm("Upload", "UploadImage", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
// Inputs and stuff ...
<input type="submit" value="Upload" name="Upload"/>
}
So how is this possible to have two (or more) forms, each one calling it's own ActionResult on submit?
I'd appreciate your help.

I think this #Html.Action("Upload", "UploadImage") is the problem. You're essentially rendering the second form inside of the first one. That's not going to work. Try changing it to this:
#using (Html.BeginForm("Insert_New_Product", "Admin", FormMethod.Post))
{
// Inputs, Validation Messages and all those stuff ...
<input type="submit" name="Insert_New_Product" value="Add New Product" />
}
// Here, I render the "Upload" View :
#Html.Action("Upload", "UploadImage")
Also, you should really be using Html.RenderAction instead of Html.Action as it writes directly to the response stream. See here for more information. Like so:
#{ Html.RenderAction("Upload", "UploadImage"); }

Related

Update partial view after edit

I have the following index:
<div id='addProduct'>
#{ Html.RenderPartial("Create", new BoringStore.Models.Product()); }
</div>
<div id='productList'>
#{ Html.RenderPartial("ProductListControl", Model.Products); }
</div>
The partial Create view contains an invisible div which is used to create a new product.
After doing so the partial view ProductListControl is updated.
Now I want to do so with an edit function.
Problem: It's not possible to integrate the edit page while loading the index because at this moment I don't know which product the user wants to edit.
My thought:
I'd like to call my existing edit view in an jquery modal (not the problem) so the user can perform changes.
After saving the modal is closed (still not the problem- I could handle this) and the ProductListControl is updated (here's my problem ... :().
How am I able to do so?
I've seen some tutorials but I'd like to keep it as clean & easy as possible.
Most of them are using dom manipulating and get feedback from the server (controller) by a JsonResult.
If possible I'd like to stick to the razor syntax, no pure JavaScript or jquery and if possible I'd like to avoid JsonResults.
One way might be to use the Ajax.BeginForm for your create product view.
The Ajax.BeginForm accepts a number of AjaxOptions, one being the UpdateTargetId (your DOM id, in this case your productlist div), more info here.
Then in your product controller code you can return a partial view, with the product list. So for example:
Index.cshtml
#using (Ajax.BeginForm("AjaxSave", "Product", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "productList", InsertionMode = InsertionMode.Replace }))
{
// your form
<p>
<input type="submit" value="Save" />
</p>
}
...
<div id="productList">...
</div>
ProductController.cs
[HttpGet]
public ActionResult AjaxSave(Product product)
{
if (ModelState.IsValid)
{
// save products etc..
}
var allProducts = _productService.GetAllProducts();
return PartialView("ProductListControl", allProducts);
}
There is a nice article on about this here.

MVC3: Button action on the same view

i wish to change the inner html of a view on button click but maintain the view. I know how to change the html content of a div in javascript, but how can I have the action of the button not return a different view?
My buton looks like
<input type="submit" value="submit" onchange="myfunc()"/>
where myfunc() is the function in Javascript changing the div content.
Assuming you want a link to render content using ajax (and hopefully using razor) you can do something like the following:
First, setup the action to render the content partially. this can be done a few ways, but I'll keep with the logic in the action (and make it callable directly or by ajax):
[HttpPost]
public ActionResult Save(SomeModel model)
{
/* build view */
return Request.IsAjaxRequest() ? PartialView(model) : Wiew(model);
}
Next, setup a container in your page where the content will be populated along with the form you're looking to submit. If you want the form to disappear on a save, wrap it in the container. Otherwise, keep the container separated. In the below example, the from will submit and on success it'll come back, otherwise the new content will appear in its place:
<div id="ajaxContentPlaceholder">
#using (Ajax.BeginForm("Save", new AjaxOptions { UpdateTargetId = "ajaxContentPlaceholder" })) {
<!-- form elements -->
<input type="submit" value="save" />
}
</div>

Ajax.BeginForm not updating target div

Controller:
public ActionResult Edit(string temp)
{
ViewBag.Time = DateTime.Now.ToString("hh:mm:ss");
return PartialView("Edit");
}
Partial View:
#using (Ajax.BeginForm("Edit", "Home", new AjaxOptions{UpdateTargetId = "mydiv"}))
{
<input type="submit" value="Save" />
}
Index View (part of contents)
<div id="mydiv">
<span>The Time is: #ViewBag.Time</span>
</div>
#Html.Partial("Edit")
ClientValidationEnabled and UnobtrusiveJavaScriptEnabled are true
jquery.validate.min.js, jquery.validate.unobtrusive.min.js, jquery.unobtrusive-ajax.min.js, MicrosoftMvcAjax.js and MicrosoftAjax.js are added
At first, the time is shown correctly. When the Save button is clicked for the first time, time disappears and Save button is shown twice and then nothing happens except calling the Action on clicking on both buttons.
You have things kind of backwards. Try this:
Controller
public ActionResult Edit(string temp)
{
ViewBag.Time = DateTime.Now.ToString("hh:mm:ss");
return PartialView("Edit");
}
Index View
#using (Ajax.BeginForm("Edit", "Home", new AjaxOptions{UpdateTargetId = "mydiv"}))
{
<input type="submit" value="Save" />
}
#Html.Action("Edit")
Partial View (Edit)
<div id="mydiv">
<span>The Time is: #ViewBag.Time</span>
</div>
The ViewBag is only accessable at runtime (when the page initially loads) so this means if you fetch data via ajax, the viewbag in the controller action is only accessable to the partial view of that controller action (and not index.cshtml which called the action via ajax). In short (tl;dr) to be able to use the viewbag which you set in Edit action, you need to use it in the returning partialview. (and not anywhere else, because the content isnt re-rendered by the razor engine)
I set things up like so.
Very simple, but I noticed the person posting the
question and the answer had no insertion mode so I posted this lame bit of code :)
{
HttpMethod = "post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "the div youwant to update / replace"
}

Redirection in controller in MVC 3 with Razor

I need a little help. I'm trying to make a little project in MVC 3 with Razor. A page with 2 buttons: Button 1 and Button 2. When I click on Button 1 I want to go at Page 1. The same with Button 2 ( to Page 2). It's not difficult, BUT I want the redirection to be made in Controller, not in View (cshtml). I know that I need to use ActionName and RedirectToAction, but I don't know how. Please help me!
What you'll need to do is check which button was pressed in the HttpPost part of the controllers action then redirect accordingly.
As a very basic example you could add two
<input type="submit" name="submit" value="<val>">
controls into your forms view each having the same name and a different value (instead of ) then add a string parameter called submit to the HttpPost action. Assuming the buttons have values "button1" and "button2" Then in your action's code you could use:
if(submit == "button1") {
RedirectToAction("Page1");
} else {
RedirectToAction("Page2");
}
to redirect based on which button was pressed
This is a simplified example, but I think you will get my meaning. You simply need to name your buttons and check the formcollection to see which exists in the collection thus indicating which what clicked. see code below:
#using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
<input type="submit" value="Go 1" name="go-1" />
<input type="submit" value="Go 2" name="go-2" />
}
and now the Action implementation.
[HttpPost]
public ActionResult Test(FormCollection collection)
{
if (collection.AllKeys.Contains("go-1")) return View("Page1");
if (collection.AllKeys.Contains("go-2")) return View("Page2");
return View("Index");
}
and thats it.
In your controller action for page 1, you can use RedirectToAction:
public ActionResult Process()
{
// do processing
// redirect to page 2
return this.RedirectToAction("Index", "Page2");
}
You can invoke the Process action from the Page 1 button using either a GET or POST request, depending on if the Process action is idempotent. E.g your page 1 view:
#Html.BeginForm("Process", "Page1", FormMethod.Post)
{
<input type="submit" name="button" value="Submit" />
}
Alternatively, you could use an ActionLink:
#Html.ActionLink("Redirect to Page 2", "Process", "Page1")

MVC 3 View with partial view and Ajax form

Here is my quandary. I have an MVC 3 web site, and I have a page that needs to contain a sub-form, if you will, to collect some data related to my model. I have successfully created a partial view that contains the markup and I am rendering this properly. However, the input button in the partial view doesn't seem to be doing much of anything. Here is the form in the partial view:
#using (Ajax.BeginForm("AddProductCustomField", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "addCustomFieldView" }))
{
#Html.DropDownListFor(m => m.SelectedCustomFieldId, new SelectList(Model.CustomFields, "FieldId", "FieldName"), "-- Select One --", new { #class = "int_std_select" })<text> </text>
#Html.TextBoxFor(m => m.CustomFieldValue, new { #class = "int_std_textbox" })
<input type="submit" value="Add Custom Field" /><br />
}
"AddProductCustomField" is the name of my controller method that I want to handle this form post. However, clicking the submit button does nothing. I even popped open Fiddler to see if a request was getting eaten and nothing. I've included all the appropriate JavaScript files for this page (MicrosoftAjax, MicrosoftMvcAjax and the unobtrusive JavaScript). I'm stumped.
Please let me know if I need to provide more info. Thanks much, this has been stumping me for days!
You mentioned sub-form. Do you literally mean you are nesting forms? This is not supported in HTML, so I would think that's probably the source of your problem.

Resources