Working with a series of MVC-driven forms where I would like to leverage the conventional '#using (Html.BeginForm(...' method of generating client-side forms that will be rendered inside Bootstrap-based modals. I've found a technique that binds the modal to an ajax request/response scheme where the form is defined thusly:
<form class="form-horizontal well" data-async data-target="#rating-modal" action="/some-endpoint" method="POST">
I understand how to insert the class attributes ( new { #class="example"} ) but I haven't found samples that show me how to deal with the 'data-async' and 'data-target=xxx'.
Wondering if Darin Dimitrov's answer to this question is partial answer to my need. Or perhaps I need to better understand EditorTemplates as suggested here.
Just as you do with a class:
new { #class="example"}
For a data-atribute can do:
new { #class="example", data_target="#rating-modal"}
data_target output data-target when razor interpret the htmlAttributes parameter
Related
I have a page which uses dijit/form/Form to validate all of the form widgets in it.
Validation works correctly if I put widgets directly under the Form (tag).
Once I surround the widgets with a dojox/mvc/Group (within the form), Form validation stops completely and none of the widgets seem to validate when I call Form::validate().
Debugging the Dojo code shows that nested widgets are never considered validatable in the Form so when I surround widgets with Group they get excluded from validation.
Is there a workaround for this?
AFAICT from dijit/form/_FormMixin#_getDescendantFormWidgets() and dijit/_WidgetBase#getChildren(), the issue can be solved by adding data-dojo-mixins="dijit/_Container" to the element having data-dojo-type="dojox/mvc/Group".
Also (though I'm not sure if it meets your requirement), dojox/mvc/tests/test_mvc_new_loan-stateful.html example shows form validation solution with dojox/mvc.
Hope it helps.
Best, Akira
It seems like there is no easy way to solve this with dijit/form/Form. At the very least, it should be subclassed or monkey-patched to make it consider nested widgets.
However, it seems that dojox/form/Manager handles nested widgets properly, so I have switched to it.
Switching to Manager required some refactoring since it cannot be simply converted into an object with dom-form (dijit/form/Form can be converted).
HTML code before:
<div
id="_pg_detailForm"
data-dojo-type="dijit/form/Form"
encType="multipart/form-data"
action="" method=""
>
... form widgets (surrounded with MVC Groups...etc)
</div>
After:
<form id="_pg_detailForm">
<div
id="_pg_detailFormManager"
data-dojo-type="dojox/form/Manager"
>
... form widgets (surrounded with MVC Groups...etc)
</div>
</form>
I am writing some code where I would like render a MVC BeginForm but to also include additional HTML.
For eg.
#using (Html.BeginMyCustomForm()) {
}
And this spits out
<form action="" etc>
PLUS
<input type="hidden" name="my-additional-field-i-always-want">
#Html.ValidationMessageFor(m => m)
Is this possible?
I know I'll be looking at some kind of extension or something most likely.
Hope this makes sense and thanks in advance!
It's not a good idea to include such things in an extension to BeginForm. The reason is that good design dictates that objects should do one thing. This is called the Single Responsibility Principle.
You now want your form object to also create inputs and validation.
Instead, use the MVC templating system and create a default template to use for your needs. You should also use Html.HiddenFor rather than using an input tag, unless there is some specific reason not to.
Another option is to use MVC Scaffolding to generate what you want.
More about Editor Templates http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html
More about Scaffolding http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/
Maybe you can use something like this?
public static class FormExtensions
{
public static MvcForm BeginMyCustomForm(this HtmlHelper htmlHelper)
{
var form = htmlHelper.BeginForm();
htmlHelper.ViewContext.Writer.write( .... )
return form;
}
}
I'm trying to wrap my head around something; maybe someone here can point me in the right direction.
Currently a have a form that has some controls on it like this:
#Html.ListBoxFor(s => s.SomeListSelection1, new MultiSelectList(Model.SomeList1, "Id", "Text"))
<br />
#Html.ListBoxFor(s => s.SomeListSelection2, new MultiSelectList(Model.SomeList2, "Id", "Text"))
<br />
#Html.ListBoxFor(s => s.SomeListSelection3, new MultiSelectList(Model.SomeList3, "Id", "Text"))
<br />
This form appears in many places with some slight variation on which controls are available.
The "slight variation" makes me not just want to do this as a partial view as I will either need to replicate the controls into many slightly varied partials or code the variation logic into the view.
So I think, "I know, I'll use the cool HTML Helper thingy!!"
But, all the HTML helper samples online are very simple html content. So the question is how can I use other HTML helpers inside an HTML helper? Or, if that is the wrong question is there another cleaner alternative to just making this a partial view with a bunch of conditional rendering logic?
Edit:
While the answer did technically answer my question, I had trouble making use of the blog entries for what I was trying to do. I found a better example (for me anyway) here:
ASP.NET MVC 3 Custom HTML Helpers- Best Practices/Uses
Yes, you can.
Helpers can contain arbitrary Razor markup.
In fact, the direct contents of a helper method is a code block, not markup.
For a more in-depth discussion about how helpers work, see my blog.
I want to create a reusable ajax control in MVC .NET using RAZOR.
my example is a simple ajax text box and list where the user filters the list by typing in the text box. on the first call i would render both the text box and the list using my razor view. on subsequent AJAX calls i would want to ONLY render the (now filtered) list.
idea 1: use #if statement to conditionally render code.
problem: razor does not seem to like conditionally written html. for example it errors when a <div> tag is not followed by a closing </div>.
idea 2: use #section tokens to create portions of my control and then call RenderSection within the same file as needed.
problem: razor does not allow RenderSection to call sections in the same page
i know i can conditionally render html as strings, but i wanted to take advantage of the legibility of the razor markup and keep with development protocols.
You should be able to output <div> tags in a Razor block without the corresponding </div> tag by surrounding it with <text>. The reason is that Razor uses the closing tag to know when to drag back into code-parsing mode:
#if (myCondition)
{
<text>
<div>
</text>
}
As for the Section stuff, you might be able to achieve what you want using Templated Razor Delegates, like this:
#{
Func<dynamic, object> b = #<strong>#item</strong>;
}
// ...
<span>This sentence is #b("In Bold").</span>
See Phil Haack's blog for a little more on this.
I have an MVC3 site using Razor as its view engine. I want my site to be skinnable. Most of the possible skins are similar enough that they can derive from a shared master layout.
Therefore, I am considering this design:
However, I would like to be able to call RenderSection in the bottom layer, _Common.cshtml, and have it render a section that is defined in the top layer, Detail.cshtml. This doesn't work: RenderSection apparently only renders sections that are defined the next layer up.
Of course, I can define each section in each skin. For instance, if _Common needs to call RenderSection("hd") for a section defined in Detail, I just place this in each _Skin and it works:
#section hd {
#RenderSection("hd")
}
This results in some duplication of code (since each skin must now have this same section) and generally feels messy. I'm still new to Razor, and it seems like I might be missing something obvious.
When debugging, I can see the complete list of defined sections in WebViewPage.SectionWritersStack. If I could just tell RenderSection to look through the entire list before giving up, it would find the section I need. Alas, SectionWritersStack is non-public.
Alternatively, if I could access the hierarchy of layout pages and attempt execution of RenderSection in each different context, I could locate the section I need. I'm probably missing something, but I don't see any way to do this.
Is there some way to accomplish this goal, other than the method I've already outlined?
This is in fact not possible today using the public API (other than using the section redefinition approach). You might have some luck using private reflection but that of course is a fragile approach. We will look into making this scenario easier in the next version of Razor.
In the meantime, here's a couple of blog posts I've written on the subject:
http://blogs.msdn.com/b/marcinon/archive/2010/12/08/optional-razor-sections-with-default-content.aspx
http://blogs.msdn.com/b/marcinon/archive/2010/12/15/razor-nested-layouts-and-redefined-sections.aspx
#helper ForwardSection( string section )
{
if (IsSectionDefined(section))
{
DefineSection(section, () => Write(RenderSection(section)));
}
}
Would this do the job ?
I'm not sure if this is possible in MVC 3 but in MVC 5 I am able to successfully do this using the following trick:
In ~/Views/Shared/_Common.cshtml write your common HTML code like:
<!DOCTYPE html>
<html lang="fa">
<head>
<title>Skinnable - #ViewBag.Title</title>
</head>
<body>
#RenderBody()
</body>
</html>
In ~/Views/_ViewStart.cshtml:
#{
Layout = "~/Views/Shared/_Common.cshtml";
}
Now all you have to do is to use the _Common.cshtml as the Layout for all the skins. For instance, in ~/Views/Shared/Skin1.cshtml:
#{
Layout = "~/Views/Shared/_Common.cshtml";
}
<p>Something specific to Skin1</p>
#RenderBody()
Now you can set the skin as your layout in controller or view based on your criteria. For example:
public ActionResult Index()
{
//....
if (user.SelectedSkin == Skins.Skin1)
return View("ViewName", "Skin1", model);
}
If you run the code above you should get a HTML page with both the content of Skin1.cshtml and _Common.cshtml
In short, you'll set the layout for the (skin) layout page.
Not sure if this will help you, but I wrote some extension methods to help "bubble up" sections from within partials, which should work for nested layouts as well.
Injecting content into specific sections from a partial view ASP.NET MVC 3 with Razor View Engine
Declare in child layout/view/partial
#using (Html.Delayed()) {
<b>show me multiple times, #Model.Whatever</b>
}
Render in any parent
#Html.RenderDelayed();
See the answer link for more use-cases, like only rendering one delayed block even if declared in a repeating view, rendering specific delayed blocks, etc.