I'm trying to do something that seems very simple: create a form that submits to same URL it was requested from, with an id.
If I didn't care about the id, I could do:
<% using(Html.Form()) { %>
<!-- stuff -->
<% } %>
But since I want the id, I have to use a different overload.
I would like something along the lines of:
<% using(Html.Form(some, args, new {id="myAwesomeForm"})) { %>
<!-- stuff -->
<% } %>
I can't just hardcode the action and controller because the form is used in a couple of different places. Sometimes the URL will have parameters (/items/edit/1, and other times it will not /items/create)
There must be some incredibly simple way of doing this that is going to make me feel like an idiot when I see it. So, what is it?
Clarification: I mean an id on the HTML element, as in <form action="/my/action[/possible arguments]" id="myAwesomeForm"></form>
Use null for the action and controller; they will be filled in from the current action and controller.
<% using (Html.BeginForm( null, null, null, FormMethod.Post, new { id = 3 } )) { %>
<% } %>
Just use the first overload (routeValues As Object)
It will assume the current, Area Name, Controller Name and Action Name parameters. Post is the default form method.
<%
Using Html.BeginForm(New With {.id = 3})
End Using
%>
Related
My classes are a DataModel, which uses ID as its PK, and a Map, which also has ID as a PK. Map has a FK to DataModel (DataModelID).
I have a partial view that I use from my DataModel list view as follows:
<% foreach (var map in Model.Map)
{ %>
<% Html.RenderPartial("MapEdit", map); %>
<% } %>
My MapEdit partial view looks like:
Before: <%= Html.Encode(Model.ID) %>
<% using (Html.BeginForm()) {%>
<label for="ID">ID:</label>
<%= Html.TextBox("ID", Model.ID) %>
<%= Html.ValidationMessage("ID", "*") %>
<% } %>
When I run this, I would expect to see ([ ] represent a textbox):
Before: 4
ID: [ 4 ]
Before: 5
ID: [ 5 ]
etc...
Where each number is the actual ID from the record. What I actually get is:
Before: 4
ID: [ 10 ]
Before: 5
ID: [ 10 ]
10 in this case happens to be the ID from the DataModel! I have no idea where this is coming from, because stepping thru the code shows that Model.ID has the correct value - at some point however it's getting replaced.
Can anyone explain this?
If Model.Map is null, Model will be passed to the partial view instead. That's how partial views work.
Also, model values are copied to the ModelStateDictionary, which can have only one key called ID. This makes sense since any form you submit would use the keys as the form field name.
ModelStateDictionary values supercede model values so that the form can be re-rendered with invalid user input when necessary. Usually, model and model state values are the same on initial (non-error) display. But this isn't the same if you have duplicate keys.
I use RenderAction to render a partial that is used all over my site.
It is a partial where the user can search for an entity. It depends on the Controller / Action that rendered the parent main view what is done once the entity is found.
Lets say I have the controllers:
HireController, FireController with
Action ActOnPerson and
PeopleController with Action FindPerson which renders the partial
FindPerson
The Views are Hire/SearchPerson.aspx and Fire/SearchPerson.aspx
Each View contains the helper:
<%Html.RenderAction("FindPerson ", "People"); %>
The form that posts to HireController/FireController is contained in the partial.
It needs to be this way, because there are actually a couple of steps (form posts) involved in finding a person.
Is there a way to decide inside the partial FindPerson if the form needs to be posted to FireController or HireController? I guess I am looking for something like public properties of WebControls but for RenderAction.
Just add parameter ("PostTo" or "Next") to People.FindPerson Action:
<% Html.RenderAction("FindPerson ", "People", new { next = Url.Action("ActOnPerson", "HireController") }); %>
<!-- or -->
<% Html.RenderAction("FindPerson ", "People", new { nextaction = "ActOnPerson", nextcontroller = "HireController" }); %>
In FindPerson PartialView:
<form method="post" action="<%= ViewData["next"].ToString() %>">
<!-- or -->
<% using (Html.BeginForm(
ViewData["nextaction"].ToString(), ViewData["nextcontroller"].ToString() ) { %>
I'm with a problem, I have a ajax link that pass a parameter, but, the page that it opens does not need that parameter. The page only load 2 partial views, one of those need that parameter passed to the page to load the data correctly, and the other just need to load a form, so, don't need that parameter. How can i acheive this?
In order to do what you want, you will need to add the id to the ViewData construct.
var sysfunctions= UnisegurancaService.FunctionsRepository.All();
ViewData["NeededID"] = id
return View(sysfunctions);
then in your view where you render the partial
<%= Html.RenderPartial("GridFunction", (int)ViewData["NeededID"]) %>
Cast as required of course.
Whatever gets pushed in as the second param becomes the .Model in the partial. I would suggest also strongly typing your partials.
Try this:
<% Html.RenderPartial("GridFunction", new ViewDataDictionary {{"Id", ViewData["Id"]}}); %>
UPDATED:
And add this in your controller action:
ViewData["Id"] = Id;
UPDATED:
And in your GridFunction partial View you can access Id as:
<%= ViewData["Id"] %>
//Controller
public ActionResult EditFunctions(int id)
{
var sysfunctions= UnisegurancaService.FunctionsRepository.All();
return View(sysfunctions);
}
// This is the controller (it does no need the parameter "ID")
//This is the view "EditFunctions"
<div id="formFunction">
<% Html.RenderPartial("FormFunction"); %>
</div>
<div id="gridFunction">
<% Html.RenderPartial("GridFunction"); %> // The grid needs the ID to work correctly but its in the parent page not in the partial call....and the call is an ajax call
</div>
If some dependency of the page needs the parameter, then the page needs to know enough to pass the data in, so the page should be able to provide the data. Or, more simply, just add the parameter to the Page's viewdata and be done with it.
I have a database menu structure which I would like to add to the site.master file.
I’ve looked at other questions on StackOverflow but cannot get this to work on my website.
How do I add a User Control to the Site.Master file?
Menu.ascx
<%foreach (MainMenuSort mainMenuSort in (List<MainMenuSort>)ViewData["MainMenuSortListDisplay"])
{ %>
<li><%= Html.Encode(mainMenuSort.MainMenuId.MainMenuName)%></li>
<%foreach (SubMenuSort subMenuSort in (List<SubMenuSort>)ViewData["SubMenuSortListDisplay"])
{%>
<%if (mainMenuSort.MainMenuId.Id == subMenuSort.SubMenuId.MainMenu.Id)
{ %>
<li><%= Html.Encode(subMenuSort.SubMenuId.SubMenuName)%></li>
<%} %>
<%} %>
<%}%>
You need to use the Html.RenderPartial method in your master page.
You will need to set the MainMenuSortListDisplay and SubMenuSortListDisplay view data keys in whatever action is calling the view that uses your master page.
In your master use this
<% Html.RenderPartial("~/Views/Shared/Menu.ascx");
The path needs to be the app relative path to the control's folder. Typically these go under Shared. You can make the structure how you want below the Shared folder.
To make this technique stronger, use a strongly typed partial. In the question you would perhaps make a new class (MenuModel) with two generic collections as properties and place it in the models folder of the application. Then in the model's constructor call a method that populates the lists.
public class MenuModel
{
public IEnumerable<MainMenuSort> OuterList {get; set;}
public IEnumerable<SubMEnuSort> InnerList {get; set;}
public MenuModel()
{
VoidThatFillsTheInnerAndOuterList();
}
This will mean that you can do this in your controller
public ActionResult ShowAForm()
{
ViewData["MenuPartialData"] = new MenuModel();
return View();
}
Having set this key, your master page can use the overload of RenderPartial, like this
<% Html.RenderPartial(
"~/View/Shared/Menu.ascx",
(MenuModel)ViewData["MenuPartialData"]); %>
This assumes that your partial is strongly typed to the MenuModel class. Then in the partial you can use the model which rewrites your code slightly
<% foreach (MainMenuSort mainMenuSort in Model.OuterList) { %>
<li><%= Html.Encode(mainMenuSort.MainMenuId.MainMenuName)%></li>
<% foreach (SubMenuSort subMenuSort in Model.InnerList) {%>
<%if (mainMenuSort.MainMenuId.Id == subMenuSort.SubMenuId.MainMenu.Id)
{ %>
<li><%= Html.Encode(subMenuSort.SubMenuId.SubMenuName)%></li>
<%} %>
<%} %>
<%}%>
Hope that helps
Try something like
<% Html.RenderPartial("Menu") %>
EDIT: Corrected a typo
You could also do it as a HTMLHelper and in the MasterPage just call <%= Html.Menu() %>. Then in your HTMLHelper you have the code to get the database records and loop through them. Here is a link I found to get you started. Note my comments as there is a bug in the code example provided. I'm still having issues handling subitems of menus, I guess I need a recursive function or something??
With the help of this link. I was able to display a menu in the site.master page.
Inside of an asp.net mvc partial view, I have an Ajax form that posts a value and replaces the contents of its parent container with another instance of the form.
Index.aspx view:
<div id="tags">
<% Html.RenderPartial("Tags", Model); %>
</div>
Tags.ascx partial view:
<% using(Ajax.BeginForm("tag", new AjaxOptions { UpdateTargetId = "tags" }))
{ %>
Add tag: <%= Html.TextBox("tagName")%>
<input type="submit" value="Add" />
<% } %>
The controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Tag(string tagName) {
// do stuff
return PartialView("Tags", ...);
}
The problem is when the new instance of the form returns, the posted value is already stored in the input field. As in, whatever I posted as the 'tagName' will stay in the textbox. Firebug shows that the value is hardcoded in the response.
Is there any way to clear the input textbox's value when returning the partial view?
I've tried:
<%= Html.TextBox("tagName", string.Empty)%>
and
<%= Html.TextBox("tagName", string.Empty, new { value = "" })%>`
neither of which do anything.
EDIT:
I realize there are js solutions, which I may end up having to use, but I was wondering if there were any ways of doing it in the backend?
I'm not sure if this solution is "good enough" for you, but couldn't you just empty the form in a JS callback function from your ajax call? If you're using jQuery on your site, the callback function could look something like this:
function emptyFormOnReturn() {
$(':input').val();
}
I am not entirely sure if it will, but in case the above code also removes the text on your submit button, change the selector to ':input[type!=submit]'.
yes you should use jquery to set values on response
if you change your code to use jquery for ajax operations, you can call you settingvalues function on success callback...example:
http://docs.jquery.com/Ajax/jQuery.ajax#options