I am using the rails 3 gem nested_forms and would like to change how the default blueprint for insertion is generated. I can not figure out how/where this code would comes from, and how/where I would add code to modify it.
I am currently using a partial for my form:
/app/views/units/_unit.html.haml
%tr
%td=f.text_field :units
%td=f.text_field :dispatched
%td=f.text_field :onscene
%td=f.text_area :actions
The code snippet that calls the partial:
/app/vies/reports/_form.html.haml
...
%table.units
%th Unit
%th Dispatched%th On Scene
%th Actions
=f.fields_for :units
%p= f.link_to_add "Add a unit", :units
...
I have all of the core functionality working, except for the template. That is auto created at run time by the gem. This template results in very simple HTML markup being used for the template.
Which is similar to the following:
<div id="units_fields_blueprint" style="display:none">
<p class="fields">
<input id="report_units_attributes_new_units_unit" name="report[units_attributes][new_units][unit]" size="30" type="text">
<input id="report_units_attributes_new_units_dispatched_1i" name="report[units_attributes][new_units][dispatched(1i)]" type="hidden" value="2011">
...
</p>
</div>
I would like the blueprint to have the tabular format that is in the partial, I just don't know how to get there.
Any help would be appreciated.
A partial which contains only a table row, such as listed above will not be valid markup when placed within the blueprint div.
The following code is not valid markup.
<div>
<tr>
<td>Content</td>
</tr>
</div>
Certain browsers (chrome for example) will attempt to correct this bad markup, which is done by stripping out the tr and td markup.
To get this type of code to work with nested_form would be complex requiring that the blueprint be created in a javascript string, and would require a modification to the builder to stop automatically surrounding inserted code in a block of code.
These changes are addressed in issue #73 for nested_form which refers to a branch created by the github user elmatou.
Another option to get a similar look and feel is to use divs and spans and create a grid structure using CSS. This is a CSS intensive process, but allows nested_form to be used without requiring alteration.
Related
#model Task3.Models.NewUser
<form action="" method="post">
<label>first Name </label>
<input type="text" placeholder="enter name" name="firstName"/>
<input type="text" placeholder="enter last name" name="lastName"/>
<button type="submit">Submit</button>
</form>
This code works even without asp-controller and asp-action. Why should I use those then?
The tag helpers asp-controller and asp-action can be used to automatically generate a target URL but you don’t have to use them. All they do is automatically generate the href attribute for links and action attributes for forms. If you want to fill in thos values manually, there is nothing that’s stopping you from doing that.
However, using the tag helpers has a clear benefit: The actual URL that you have to use depends on various things that affect your application’s routing. So if you use manual values, you have to take that into account. And if your routing changes (for whatever reason), you have to manually update the URLs throughout your templates.
By using the tag helpers, you are attaching the target location to something that is usually rather static: A controller action. So that way, you decouple the template from your routing configuration.
One more note for form actions specifically: If you do not specify a form action, the browser will automatically post to the current URL. So if you have a POST handler on the same route as the form, then you can totally omit the action and depend on that behavior.
I cannot find any answer on this seemingly easy question. In my rails5 app some links do use turbolinks for loading new page. But some just launch full page reload.
There is no js attached to that links, turbolinks is not disabled on that links.
This link uses turbolinks:
= link_to qm_input_path('hour') do ...
<a class="navbar-brand" href="/qimen/hour/input"> ...
In the action it has
render layout: 'input'
And this link doesn't:
= link_to qm_chart_path(#foo, #bar), class: 'btn btn-default pull-right next' do ...
<a class="btn btn-default pull-right next" href="/qimen/hour/chart/foo/bar"> ...
In the action it has
render layout: guess_layout
So, nothing explicitly blocking turbolinks to work.
Why?
The issue is that the hrefs in your links contain periods (.).
Turbolinks will only handle links that it considers to be HTML. That is, those that have no extension (e.g. /post/1234), or those which have an html/htm/xhtml after the last period (e.g. /post/1234.html). In your case, the links which are performing a full page load end with something like: /30.335098600000038. Turbolinks will not consider this to be an HTML resource and so will not handle it.
To solve this, I'd recommend using query strings for parameters that may contain periods. For example to tidy up one of your links, you could try:
qimen/hour/chart?time=2017-06-03T15:27:48+03:00&city=St.%20Petersburg&longitude=30.335098600000038
I just come across a good write up for a new ASP.NET Core feature called Tag helpers.
From there, I understood that one can replace the following code:
#model MyProject.Models.Product
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(m => p.Name, "Name:")
#Html.TextBoxFor(m => p.Name)
</div>
<input type="submit" value="Create" />
}
with:
#model MyProject.Models.Product
#addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<form asp-controller="Products" asp-action="Create" method="post">
<div>
<label asp-for="Name">Name:</label>
<input asp-for="Name" />
</div>
<input type="submit" value="Save" />
</form>
There's some new syntax such as asp-controller, asp-for, etc. But what does it do? And what's the advantage of this new approach?
The most important improvement I've seen so far is the control it guarantees over your HTML elements. While convenient, the Html helpers used by MVC create problems when you try to do things they weren't built for.
A simple example can be seen when using the TextBox in MVC5:
#Html.TextBoxFor(m => p.Name)
The resulting HTML markup looks like:
<input class="form-control" id="Name" name="Name" type="text" value="">
Nice and simple. But what if you want to add a placeholder attribute? What if you want to use bootstrap's validation states? What if you have some 3rd party super cool javascript library which needs custom attributes. None of these things were possible in the initial release of MVC5. Though they were eventually added via update in the form of htmlAttributes. Even now adding custom attributes is kludgey at best.
#Html.TextBoxFor(m => p.Name,
new {#class="form-control has-error", placeholder="Enter Name",
superCoolFeature="Do something cool"})
While you could argue this is still less code that straight HTML, it is no longer a significant advantage. Worse, this solution still doesn't cover dashes in attributes which are fairly common. If you need them you are stuck with a workaround such as ActionLink htmlAttributes
I've gone down the route of fixing these deficiencies with custom editors, and tried building my own TextBox controls. It became obvious pretty quickly that replacing the included TextBox templates would require a lot of work. Worse, your templates have to have knowledge of any extensions you are adding to use them.
It seems like the inclusion of Bootstrap and other 3rd party tools into MVC have made it more obvious that the current design has problems with extending HTML which need to be fixed. Hopefully the tag helpers implementation is complete enough that we can avoid them in the future.
Not to mention, your Web Designers will have real HTML tags to edit that they recognize to re-design your pages. Designers shouldn't have to be coders and there's enough for these sharp folks to keep up with, studying the moving targets of HTML5 and CSS3 specs.
A few things come to mind:
As #ChrisWalter points out, these tag helpers give HTML tags an Open/Closed quality. Rather than just letting you write extension methods for common HTML patterns, you can extend an HTML element. This lets you pick-and-mix multiple extensions per component, rather than having to choose between them.
HTML Helpers tend to not work super well for elements that need to have inner HTML provided as an argument. They came up with a clever pattern so you can say:
#using (Html.BeginForm(...)){
{
<input ... />
}
But there's nothing about BeginForm() that would force you to put it in a using statement, and there's nothing to prevent you from using incorrect HTML structure. (<input> technically isn't allowed to be directly inside a <form> tag.)
This gives us a really easy transitional stepping stone into the Web Components world of HTML5. A component that you write today for jQuery or Bootstrap to pick up and enhance may make more sense as an Angular 2 or Polymer component in a few years. Using HTML syntax makes it possible to write your HTML the way you want it to look when it's a web component, and have it automatically translated into the structure it has to take on for now (or for specific browsers, later).
Accepted answer is correct but just a correction.
Html Helpers cover dashes in attributes by use of underscore. for example if you want html like
my-attr=value
then you can use html helpers like
#Html.TextBoxFor(m=>m.id,
new { my_attr = value })
then it will convert accordingly.
I know the original question asks about advantages but for the sake of completeness I have to mention one disadvantage:
With tag-helpers enabled you cannot inject C# code inside tag attributes.
I.e. this code will break:
<!-- this won't work -->
<input class="#GetMyClass()">
<!-- this won't work too -->
<input type="checkbox" #(condition ? "checked" : "") >
To work around this problem you can use custom tag helpers or just disable tag helpers altogether like described in this answer: https://stackoverflow.com/a/65281018/56621
P.S. My humble opinion that can be safely ignored: tag helpers are "magic". And "magic" is always bad in programming. If something looks like an HTML tag, walks like a tag and quacks like a tag - then it should probably be an HTML tag. Without me knowning "oh, it's not *really* a tag".
From building a basic web app from the ground up in .NET 7/Razor pages, I haven't encountered a single instance where a tag helper has an advantage over simply coding the HTML. I don't come from an MVC background so maybe that is where the advantage lies but as seen before...Microsoft has released yet another version of wheel-reinvention that instead of making things easier for some simply adds more confusion to others.
I am using ASP.NET MVC 4 HTML.BeginForm and it creates a validation-summary-errors class as
below. This doesn't fit with my layout. Is there a way that I can make it put the
validation div class in a different place?
<form action="/User/Account/Login" method="post" novalidate="novalidate">
<div class="validation-summary-errors">
<ul>
<li>The user name or password provided is incorrect.</li>
</ul>
</div>
<fieldset>
<legend>Local Login</legend>
<ol>
<li>ation-summary-errors in a different position?
Well, sure, it's up to you to put the #Html.ValidationSummary() helper call which generates this markup wherever you want. As far as controlling the exact markup that this helper spits, that would be much more difficult because this helper offers you almost no control over the generated markup.
If you need to have more control you could write a custom helper.
You can use #Html.ValidationMessage("validation-errors") and put it in any HTML tag and then can use CSS to give it a style.
I'm having real troubles passing form data from a posting page made up of User Controls.
I posted this question before, here, Getting form field names on Submit when form is user control but the answers have not solved my problem, or I have mis-understood them.
Let me try explaining what I am doing more clearly.
I have a page which displays a form to the user. The form is made of several sections, but for simplicity we'll say there are two. Each of these sections is a User Control, thus the actual markup for newSale.aspx is just:
<%# Page Language="VB" MasterPageFile="~/MasterPage.master" CodeFile="newSale.aspx.vb" Inherits="newSale_Default"%>
<%# Register TagPrefix="controls" TagName="customerForm" Src="~/Controls/customerForm.ascx" %>
<%# Register TagPrefix="controls" TagName="itemList" Src="~/Controls/itemList.ascx" %>
<asp:content id="content1" ContentPlaceHolderID="mainContent" runat="server">
<div class="content">
<form id="newSale" method="post" action="saveSale.aspx">
<h1>--- New Sale ---</h1>
<div class="section" id="customerSection">
<controls:customerForm ID='customerForm1' showBankDetails="false" runat='server' />
</div>
<div class="section" id="saleSection">
<controls:itemList ID='itemList1' showShipping="false" showDeposit="false" runat='server' />
<div class="row submitRow">
<div id="submitSale">Submit</div>
</div>
</div>
</form>
</div>
</asp:content>
So you see my two main Controls tags with the IDs "customerForm1" and "itemList1" respectively.
The submit button is deliberately a clickable div and submission is done by jQuery, thus:
$('#submitSale').live('click', function () { $('#newSale').submit(); });
As the User Controls are rendered into the browser, the IDs and Names of the elements are messed about (I understand the reason why) by ASP.NET, so taking one field as an example:
A field named "name" contained within the customerForm control becomes m$mainContent$customerForm1$name
'm' - being the ID of my MasterPage
'mainContent' - being the ID of the PlaceHolder
'customerForm1' - being the ID of the User Control and
'name' being the element's actual name.
I wish to submit this form to a separate file (saveSale.aspx) as per the action attribute of my Form tag declared above.
Within the Code-Behind of saveSale.aspx I need to save the data passed from the form into a dataBase and return it in the aspx file as an HTML page.
How do I reliably get the value of the submitted form fields in saveSale.aspx(.vb)?
<%= request.form("m$mainContent$customerForm1$name") %>
Works, but naturally is a pain to use, especially when I want to replicate this to other purposes.
m.mainContent.customerForm1.name.selectedValue()
tells me that 'm' is not declared
and from the other replies to my previous question I have tried registering the controls at the top of the (saveSale.aspx) page, and explicitly posting the Control into the page again with
<controls:customerForm ID='customerForm1' showBankDetails="false" runat='server' />
Which doesn't work, but even if it did, it makes no sense anyway as I don't want to use the Control anymore, I just want to get the data from it.
I do apologise if I'm being dumb here, but I have tried so many different variations of code and Googled ideas, but I can't seem to make this work in any scalable fashion beyond the Request.Form example above.
I am using .NET 2.0 so can't use the Static Client feature that I've seen mentioned for .NET 4.0
Also, please, I am using VB.NET, so if you can help, please help with a VB example.
Many thanks.