I am building an mvc app for reporting. I have a page that has a form on it which contains multiple dropdownlist to choose some criteria for a report. I then have an input button to create the report. This button call a new view from the same controller. The new view gets the values from the page where the criteria is chosen from parameters and uses that to populate it's own view model. This is all working fine.
I would like to open the reports in a new window. When I look at the controller, all of the parameters that are supposed to be coming from the selection page are null. I assume I will have to pass these in via the querystring to be picked up by the controller. Is there a way that I can get the values of the dropdownlists from within my viewpage to construct the querystring?
Is this a good way to accomplish what I am trying to do? Would I be better of using an ActionLink instead of an input button? does it make any difference?
I hope this all makes sense. Thanks for any thoughts.
Just set a target attribute on your form to _blank and it should open the request in a new page/tab depending on the browser being used.
<% using (Html.BeginForm(myAction, myController, FormMethod.Post, new { target = "_blank" })
{ %>
<%-- ... --%>
<% } %>
As NickLarsen says...
You could use the target="_blank" attribute of the form element to display the results in a new window.
<form action="/controller/action" method="post" target="_blank">
Or
<% Html.BeginForm("action", "controller", FormMethod.Post, new { target="_blank" }); %>
//...
<% Html.EndForm(); %>
Related
I am new to ASP.NET MVC 4 and learning my way around an existing MVC 4 code base. I am trying to find the code that processes the the form corresponding to this submit button. I understand that the action link probably says how to process the "submit" button -- but I don't see any constructors that take three strings for an actionlink in the microsoft documentation.
I am confused because there is no action field in the input tag.
How do I find out what happens once the person hits submit?
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data", #class = "disableSubmit" }))
{
...
<div class="buttons">
<input type="submit" value="Upload" /> | #Html.ActionLink("Back to List", "Index", "Admin")
</div>
}
Update When I go to "view source" to see the raw HTML I see
<form action="/Lab/Upload" ...
So that means it goes to the lab/upload controller?
The Javascript for the disable submit looks like this:
// Disable submit button after click
$(function () {
$('.disableSubmit').submit(function () {
if ($(this).valid()) {
$('input[type="submit"]').attr('disabled', 'disabled');
}
});
});
If the submit button performs a regular form submit, then it will be inside of a <form> tag or #Html.BeginForm using block.
BeginForm will submit the form to the action that matches the name of the view, unless there is a parameter being passed that specifies the action name and/or controller name.
IF it is a form tag, then the action="something" attribute of the form tag will indicate the URL being submitted to, which is usually controllerName/ActionName` but could be different depending on what routing is setup.
The ActionLink you see is not related to the form or the submit, it is a regular link which is in effect a way for the user to go back to the previous page instead of submitting the form.
There is also the possibility that there is javascript attached to the submit button. That's harder to find unfortunately due to the many ways that javascript can be wired up to a button.
Edit: Based on your update, I would strongly suspect there's javascript that supports this form. I imagine the submit button is disabled until you meet some conditions that allow it to be displayed. Maybe permissions, maybe filling the form out completely, it's hard to say. Search the javascript for disableSubmit, as I suspect somewhere there is code that removes that class under certain conditions.
Edit 2: What is happening there is it disables the submit button after the first click so that you can't accidentally submit the for twice and cause problems with a duplicate submit(if this is Create form it avoids duplicate records). As far as I can tell there should be an action of the same name as the *.cshtml file that it submits to. Possibly with a [Post] or [HttpPost] attribute on the action.
Check whether the submit buttons in inside a form tag. If yes, what is the action attribute value of that ? That is the place the form will be submitted to.
You may see an HTML helper method called Html.Beginform in the view. This method render a form tag. You can go to the page and check the view source of the page to see what is the form tag looks like and what is the action method attribute value.
Ususally your controller will have an action method marked with HttpPost attribute to handle the form submit. Lets say your mark up is like this
<form action="User/EditUser">
<input type="text" name=Name" />
<input type="submit" />
</form>
Now in your UserController, there may be an action method like this
[HttpPost]
public ActionResult EditUser(SomeModelIfExist model)
{
// TO DO : save and redirect
}
the Html.ActionLink helper method renders an anchor tag. It has nothing to do with the form submit. So your action link helper will return the below markup
Back
I have an ascx control for fruits that contains following code:
<div id = "fruits">
....
Ajax stuff1 UpdateTargetId = "fruits"
Ajax stuff2 UpdateTargetId = "fruits"
<%Html.RenderPartial("PagerAjax", (Pager)ViewData["pager"]); %>
</div>
now this fruit control can appear on a number of webpages and the pager would need to know what page the user is on so that it can pull next set of fruits accordingly. For example, if I am on red-fruit page, then PagerAjax should know I am only pulling out red fruits. So, basically I would need to know ControllerName (assume it's home) and actionName (assume it's redFruits()). (Example may seem inefficient but it makes sense for the real purpose.) Now, I could do something like this:
<%Html.RenderAction("PagerAjax", (Pager)ViewData["pager"], ViewContext.RouteData.Values["action"], controllerFilter = ViewContext.RouteData.Values["controller"] }); %>
However, as you noticed, the above RenderAction is inside the div that is being updated by Ajax callback, which means it will contain action and controller of the Ajax stuff rather than the original URL's.
What should be an efficient workaround?
You could pass the original ViewContext.RouteData.Values["action"] as parameter when calling your AJAX action. This way the action knows what was the original action and store it in the model (or ViewData as in your case I see that your views are not strongly typed). Now your markup could become:
<% Html.RenderPartial(
"PagerAjax",
(Pager)ViewData["pager"],
new ViewDataDictionary() { { "originalAction", ViewData["originalAction"] } }
); %>
ViewData.Model.ExecuteResult does not exist in ASP.NET MVC2, but in MVC1.
What is the alternative in ASP.NET MVC2?
What I want to do, is to update a table after an ajax request. So I put the table in an extra View. How can I update this partial view without loading the whole page again?
ExecuteResult is a method on the System.Web.Mvc.ActionResult class. Are you sure you don't mean to be looking there?
http://aspnet.codeplex.com/SourceControl/changeset/view/23011#266522
The Model property is just an object type, and always has been, AFAIK.
As for updating the table, what I've done in the past, to update a portion of a page after a partial view is to use Ajax.BeginForm like so:
<% using (Ajax.BeginForm("Customers", new AjaxOptions { UpdateTargetId = "customerList"})) { %>
<!-- FORM HERE -->
<% } %>
<div id="customerList">
<% Html.RenderPartial("CustomerList"); %>
</div>
'UpdateTargetId' is the key here, and tells MVC to use the result of the "Customers" action to replace (by default, you can append by setting the InsertionMode AjaxOption to InsertBefore or InsertAfter) everything inside the element withthe Id you specify.
If you want to use the same action to service the full page request and the Ajax request, you can use the IsAjaxRequest extension method to determine what to return:
if (Request.IsAjaxRequest())
return PartialView("CustomerList");
// Not an Ajax request, return the full view
return View();
Hope that helps!
I want to do the following:
1: Add two dropdown list in the register.aspx [Say ddlRole,ddlGender]
2: Fill the dropdown list [ ddlRole should be filled from the database, and ddlRole should have two static field]
3: On submit I want to get the selected value of the two dropdown list.
Please help.
Thanks in advance.
Well, your question is kind of "Can you tell me how to build a shuttle?". But i will try to show you the small example that will help you (I really hope)
First of all,if you want to get dropdowns on the page, you need to create it.
In terms of MVC you need to create a View.
That View is MVC styled aspx page
below is an example:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<h2>Register</h2>
This is a plain empty page.
Let's fill it up with dropdowns.
<h2>Register</h2>
<%= Html.DropDownList("ddlRole") %>
<%= Html.DropDownList("ddlGender") %>
Okay. Now, time to make the system to show our View.
To do that we need a motor. In terms of MVC it calling a Controller.
Create a class with the method:
public class SetupController : Controller
{
public ActionResult Register( )
{
return View();
}
}
If you now will try to launch the page you should see your two dropdowns.
Unfortunately they will be empty.
Obviously they are empty because you did not tell how to fill them.
The main purpose of controllers is to connect model that contains all the data that should be processed and shown with the view side. In other words, the controller takes the data from the model (M), prepares it and sends to the View (V).
So, first of all we need to adjust our controller, so it will tell the view an information about the content for dropdowns.
The easiest way is to use ViewData collection:
public ActionResult Register( )
{
ViewData["ddlRole"] = new[] {
new SelectListItem() {Text = "Customer", Value = "Customer"},
new SelectListItem() {Text = "Supervisor", Value = "Supervisor"},
new SelectListItem() {Text = "Admin", Value = "Admin"},
};
ViewData["ddlGender"] = new[]{
new SelectListItem() {Text = "Male", Value = "Male"},
new SelectListItem() {Text = "Female", Value = "Female"}
};
return View();
}
As you can see from this example i created the content for the dropdowns dynamically.
In your case you can use your database to fill dropdowns as you want.
If you try to open your page now, you will see that your dropdowns are filled with the data now!
Great!
If you ask, how the view knows what content to use for the dropdown, i will answer that MVC is using a lot of conventions. One of that conventions is that when the View is generating its controls its looking for the content for that controls by the key that equals to the name of the control (i.e. "ddlRole", "ddlGender")
Since you put the values for that keys to the ViewData, its easy for MVC to fill your dropdowns with the text!
Cool!
Going forward.
Now, we need to gather the data from the page and send it back to the server.
What we need for that?
Of course, first of all we need a submit button:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<h2>Register</h2>
<%= Html.DropDownList("ddlRole") %>
<%= Html.DropDownList("ddlGender") %>
<input type="submit" value="Register Me" />
Open the page in the broser again.
Cool! We have the button, but, if we try to click on it, nothing will happen.
If you are thinking in terms of classic ASP.NET, you will tell that we forgot to assign an event on the button submit, write codebehind code and bla...bla..bla...
In MVC its a bit different. We just need to send the content to the server.
To do that, normally you should have a "form" tag on your page :
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<% using (Html.BeginForm("DoRegister", null)) { %>
<h2>Register</h2>
<%= Html.DropDownList("ddlRole") %>
<%= Html.DropDownList("ddlGender") %>
<input type="submit" value="Register Me" />
<% } %>
This using code block will just wrap our tags with begin and end "form" tags.
This make the browser to gather an information from all inputs inside the form (in our case its our dropdows) and send them back from the point where they were opened.
Try to open it in the browser and click the button
Oops, we got an exception. The reason of it is that we forgot the rules.
What we intended to do ? We want to send the data to our business model.
Who should be responsible for that ? Of course it should be a controller (C), because its a main and only connector between Model (M) and View (V)
Let's add new action to the same controller :
public ActionResult DoRegister(string ddlRole, string ddlGender)
{
////store our ddlRole and ddlGender in the database
/// ......
/// .....
return RedirectToAction("Welcome");
}
In this example it redirecting to the "Welcome" action once registration has finished.
To finish an example and avoid errors, we need to implement Welcome action and view:
Add this to the controller:
public ActionResult Welcome( )
{
return View();
}
And create new View for the Welcome action (Right click on "Welcome" code and select "Add View..."):
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<h2>Welcome!</h2>
Now you will see that once you click the button it will show you the result of Welcome action execution - Welcome page.
Last trick - let's send selected dropdown values to the welcome page.
To do that, we firstly need to store that values somewhere at the moment when we got it from the server.
In your case you may use the Database, but to make it simpler, i will use special TempData collection:
public ActionResult DoRegister(string ddlRole, string ddlGender)
{
////store our ddlRole and ddlGender in the database
/// ......
/// .....
TempData["SelectedRole"] = ddlRole;
TempData["SelectedGender"] = ddlGender;
return RedirectToAction("Welcome");
}
Next, let make our welcome page to show the values from TempData collection:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<h2>Welcome you, the <%= TempData["SelectedRole"]%> of <%= TempData["SelectedGender"] %>!</h2>
Run it!
Do you see the values ?
Yeah, You made it!
Simple and easy.
I hope this article will help you to start realize how great ASP.NET MVC is.
But the code above is just a top of the iceberg.
Actually the MVC is MUCH MUCH MUCH more fun then this.
If you are interesting in getting more knowledge about it, I would really recommend you to read APress "ASP.NET MVC Framework" by Steven Sanderson.
Really great book that contain everything to start writing your own MVC applications on MVC.
Have a good luck!
This seems like a very simple question, but I'm getting lost, and need a few pointers.
I am using ASP.NET MVC C#, and have an Index page which displays a list of items, which is working fine.
Now I'm trying to add a DropDownList that depending on what the user selects will filter the list of items. But I keep thinking how you would do this in ASP.NET Web with RunAt Server, which I know is wrong.
Any pointers would be welcomed.
Put the select box in a form and make the form post back to a filter method in your controller.
Or
If you want to use ajax, use an Ajax.ActionLink to update the table with the filtered results
<% Ajax.ActionLink("Filter", "FilterMethod", null, new AjaxOptions { UpdateTargetId = "tableId" }, new { Title = "Filter results" }) %>
<table id="tableId"> .... </table>
Where "FilterMethod" is in yo0ur controller
This might help.
Also worth looking at:
http://jerrytech.blogspot.com/2009/06/implement-ajax-form-in-mvc-framework.html