ASP.NET MVC 2 - ViewModel Prefix - asp.net

I want to use RenderPartial twice in my view with different models associated. The problem is that some properties are present in both models (nickname, password). They have no prefix, so even the id's or names are equal in the output. Now, if I have model errors for nickname or password, both fields get highlighted.
Main View:
<div>
<% Html.RenderPartial("Register", Model.RegisterModel); %>
</div>
<div>
<% Html.RenderPartial("Login", Model.LoginModel); %>
</div>
Login PartialView:
<% using (Html.BeginForm("Login", "Member")) { %>
<fieldset>
<legend>Login</legend>
<p>
<%= Html.LabelFor(x => x.Nickname) %>
<%= Html.TextBoxFor(x => x.Nickname) %>
</p>
<p>
<%= Html.LabelFor(x => x.Password) %>
<%= Html.PasswordFor(x => x.Password) %>
</p>
<input type="submit" value="Login" />
</fieldset>
<% } %>
Register PartialView:
<% using (Html.BeginForm("Register", "Member")) { %>
<fieldset>
<legend>Register</legend>
<p>
<%= Html.LabelFor(x => x.Nickname) %>
<%= Html.TextBoxFor(x => x.Nickname) %>
</p>
<p>
<%= Html.LabelFor(x => x.Email) %>
<%= Html.TextBoxFor(x => x.Email) %>
</p>
<p>
<%= Html.LabelFor(x => x.Password) %>
<%= Html.PasswordFor(x => x.Password) %>
</p>
<p>
<%= Html.LabelFor(x => x.PasswordRepeat) %>
<%= Html.PasswordFor(x => x.PasswordRepeat) %>
</p>
<input type="submit" value="Register" />
</fieldset>
<% } %>
How can I change this?

If you can't do an EditorTemplate for some reason, you can do this in your View:
var dataDict = new ViewDataDictionary();
dataDict.TemplateInfo.HtmlFieldPrefix = "myPrefixHere";
Html.RenderPartial("myPartialViewName", myPartialViewModel, dataDict);
Lo and behold, all inputs in your PartialView will be prefixed.
Kudos to R0MANARMY for pointing this out.

Instead of using Html.RenderPartial you could use editor templates which will handle prefixes.
So in your main view:
<div>
<%-- See below what does the second argument mean --%>
<%= Html.EditorFor(x => x.RegisterModel, "RegisterModel") %>
</div>
<div>
<%= Html.EditorFor(x => x.LoginModel, "LoginModel") %>
</div>
And then create a folder Views/Shared/EditorTemplates/RegisterModel.ascx (The name of this file is used in the EditorFor helper method). Also notice that this partial should be strongly typed to the type of the RegisterModel property:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Ns.Models.RegisterModel>" %>
<% using (Html.BeginForm("Register", "Member")) { %>
<fieldset>
<legend>Register</legend>
<p>
<%= Html.LabelFor(x => x.Nickname) %>
<%= Html.TextBoxFor(x => x.Nickname) %>
</p>
<p>
<%= Html.LabelFor(x => x.Email) %>
<%= Html.TextBoxFor(x => x.Email) %>
</p>
<p>
<%= Html.LabelFor(x => x.Password) %>
<%= Html.PasswordFor(x => x.Password) %>
</p>
<p>
<%= Html.LabelFor(x => x.PasswordRepeat) %>
<%= Html.PasswordFor(x => x.PasswordRepeat) %>
</p>
<input type="submit" value="Register" />
</fieldset>
<% } %>
You could define a different partial for the login model in Views/Shared/EditorTemplates/LoginModel.ascx

Looks like there's an overload for TextBoxFor that allows you to specify extra HTML attributes. It isn't an ideal solution, but it should let you change the id (and possibly name?) of the rendered textboxes. Of course changing the name would probably screw things up when you try to post the form.

First of all, you could use Html.TextBox("input form name", ...) and set the name to whatever you wish. There's a bigger issue how would you provide a prefix on Html.RenderPartial() level? You are already providing a model instance. So without changing their view models, there's just one more possibility: to write your own overloads for RenderPartial() that would take the prefix and pass it on to others.
Check this one out. Someone's written a whole bunch of overloads that support setting prefixes. TextBoxFor rendering to HTML with prefix on the ID attribute
If any is missing you can see the pattern how to extend these with additional ones you may need.

Related

Problems with rails helper link_to concerning class

I'm having difficulties with rails. In fact, I wrote these lines :
<%= link_to :controller => "offers", :action => "get_offer", :offer_slug => offer.friendly_id, {:class => "media"} do %>
.
.
.
<% end %>
My problem is that everything that is inside link_to is getting the css effects of a hyperlink (no padding, gets underlined when hover), instead of custom properties.
It's like the :class property isn't being taken into account.
Just in case, here's the full part :
<<%= link_to :controller => "offers", :action => "get_offer", :offer_slug => offer.friendly_id, {:class => "media"} do %>
<li id="<%= offer.id %>" class="media" style="border: 1px solid #696969">
<div class="col-lg-3" style="margin-bottom:0px; font-size:12px; text-align:center; margin-right:10px;">
<% if offer.subcategory.nil? %>
<img class="media-object" src="<%= asset_path "other-icon.png" %>" style="margin-bottom:5px;">
<% elsif offer.subcategory.category.icon.empty? %>
<% else %>
<img src="<%= asset_path offer.subcategory.category.icon %>" style="margin-bottom:5px; width:110px;">
<% end %>
<br/>
<% if offer.subcategory.present? %>
<b><%= offer.subcategory.category.name %></b><br/> <%= offer.subcategory.name %>
<% else %>
<b>Autres</b><br/> <%= offer.subcategory_other %>
<% end %>
</div>
<div class="media-body">
<!--Titre annonce + type contrat-->
<div style="text-align:right; margin-bottom: 10px;">
<% if offer.id >= #new_limit %>
<span class="label label-warning">New</span>
<% end %>
<span class="label label-success"><%= (offer.max_price * 0.85).ceil %> euros</span>
<span class="label label-success" style="background-color: grey"><%= (offer.customer_objective) %>
succès </span>
</div>
<h4 class="media-heading">
<%= raw(offer.name) %>
</h4>
<p>
<% if offer.description %>
<%= offer.description.split[0..60].join(" ") %>
<% if offer.description.split[0..60].count >= 59 %>
<% end %>
<% end %>
</p>
<% if offer.company_context.present? %>
<p>
<%= offer.company_context.split[0..60].join(" ") %>
<% if offer.company_context.split[0..60].count >= 59 %>
<% end %>
</p>
<% end %>
</div>
<div class="offer-tags">
<% offer.offer_tags.each do |offer_tag| %>
<span class="badge"><%= offer_tag.tag.name %></span>
<% end %>
</div>
</li>
<% end %>
Try to wrap the class in curly braces:
<%= link_to :controller => "offers", :action => "get_offer", :offer_slug => offer.friendly_id, { :class => "media" } %>
The Rails link_to helper is pretty flexible and allows a few different call signatures, which can lead to confusion. You are needing this one:
link_to(body, url_options = {}, html_options = {})
Without the wrapping braces, Rails is not clear that :class is in fact an HTML option.
Docs here. I should mention I also dropped your trailing do which implied a block that didn't seem to be there (nor was it needed).
UPDATE
I did not understand that the block was intended as the link body. In that case, the right call signature would be:
link_to(options = {}, html_options = {}) do
# name
end
So, your body is fine, but in your link_to, you want to group the URL options, followed by the HTML options. Plus I think you may need parentheses around the whole call for it to work correctly:
<%= link_to({ :controller => "offers", :action => "get_offer", :offer_slug => offer.friendly_id }, { :class => "media" }) do %>

Ruby on Rails - adding CSS to text_field

I created a form in Rails and when I add a CSS class to a text_field the form will not submit.
I am still new to rails so any help would be much appreciated.
This is my form:
<% #page_title = "Contact" %>
<hr>
<div class="col-lg-12">
<h1 class="page-header">
BK Legal Courier Corp <br />Call BK # <span style="color:#47B224">613-286-8265</span>
</h1>
</div>
<hr>
<div class="container">
<h2>Contact Us</h2>
<%= form_for :fc, :url => {:action => 'create'} do |f| %>
<div class="form-group">
<%= f.label :first_name %>
<%= f.text_field (:first_name, :class => 'form-control')%>
</div>
<div class="form-group">
<%= f.label :last_name %>
<%= f.text_field (:last_name, :class => 'form-control') %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field (:email, :class => 'form-control') %>
</div>
<div class="form-group">
<%= f.label :comment %>
<%= f.text_area (:comment, :class => 'form-control') %>
</div>
<div class="form-group">
<%= f.label :referral %>
<%= f.select (:referral, [['Friends', 1], ['News', 2], ['Online', 3], ['Other', 4]], :class => 'form-control')%>
</div>
<%= submit_tag ("Submit") %>
</form>
</div>
<% end %>
</body>
</html>
The problem is that my form will only submit without the :class => "form-control" in it. I must have brackets around each of the form field variables.
This is my routes.rb file:
Rails.application.routes.draw do
root "home#index"
match ':controller(/:action(/:id))', :via => [:get, :post]
end
This is my controller:
class HomeController < ApplicationController
def home
render("home/index")
end
def new
#fc = FeedbackCustomer.new
end
def create
# Instantiate a new object using form parameters
#fc = FeedbackCustomer.new(feedbackcustomer_params)
if #fc.save
redirect_to(:action => "home")
end
end
def application
end
private
def feedbackcustomer_params
params.require(:fc).permit(:first_name, :last_name,
:email, :comment, :referral)
end
end
Any help would be much appreciated. Thanks!
If you're using Ruby 1.9+ This should work:
<%= f.text_field :last_name, class: 'form-control' %>
If you're using a version that's older than 1.9 then this should work:
<%= f.text_field :last_name, :class => 'form-control' %>
For more information on this you can use the ActionView::Helpers::FormTagHelper API Documentation
The Form Helpers Rails Guide might be helpful to you as well.
For the most recent version of Ruby you can now also do:
<%= f.text_field :last_name, class: 'form-control' %>

Rails & Bootstrap Make button inline with text field

I'm working on a front end of web app. I would like to know how to make the button and textfield in line. Another question is how to make the error message displayed just below the textfield?
Picture:
https://www.dropbox.com/s/vsdy3730flraes3/Screen%20Shot%202013-12-01%20at%204.47.20%20PM.png
Here is the code:
<div class="input-group" align="center" >
<%= form_tag(location_search_path,method: "get" ) do %>
<%= text_field_tag('location', params[:location], :size => 150, :placeholder=> "Enter city or zip code") %>
<%= button_tag(type: "submit", class: "btn btn-success ") do %>
Search
<i class="icon-search"></i>
<% end %>
<% end %>
</div>
<% [:notice, :error, :alert].each do |level| %>
<% unless flash[level].blank? %>
<div data-alert="alert" class="alert-message <%= flash_class(level) %> fade in" align="center">
<%= content_tag :p, flash[level] %>
</div>
<% end %>
<% end %>
Add the <div class="form-inline"> to your form element to get the button and field onto the same line, and I guess you could us a <p> to make the message appear below it, though I would probably set up the input group in a row with columns to center it rather than the align tag you are using, and then put the messages into a new <row> below it in the same column.
<div class="input-group" align="center" >
<div class="form-inline">
<%= form_tag(location_search_path,method: "get" ) do %>
<%= text_field_tag('location', params[:location], :size => 150, :placeholder=> "Enter city or zip code") %>
<%= button_tag(type: "submit", class: "btn btn-success ") do %>
Search
<i class="icon-search"></i>
<% end %>
<% end %>
</div>
</div>
<p>
<% [:notice, :error, :alert].each do |level| %>
<% unless flash[level].blank? %>
<div data-alert="alert" class="alert-message <%= flash_class(level) %> fade in" align="center">
<%= content_tag :p, flash[level] %>
</div>
<% end %>
<% end %>
bootstrap 3 has input groups... which are nice. http://getbootstrap.com/components/#input-groups
Try this in your code...
<%= form_tag location_search_path, method: 'get' do %>
<%= text_field_tag :location, params[:location], size: 150, placeholder: "Enter city or zip code" %>
<span class='input-group-btn'>
<%= submit_tag 'Search', class: 'btn btn-success' %>
</span>
<% end %>

Creating unique id for <fieldset> when using form_for Rails Nested Model Form

I have a nested model form in the style of this Railscast
http://railscasts.com/episodes/196-nested-model-form-revised?view=asciicast
I need to give each tag a unique ID. Currently, each field generated has a unique ID and name given by a helper method that assigns a unique ID to every association record. So that is taken cared of. However, this form has "fieldset" tags which isn't assigned an ID. I need a unique ID for each fieldset for jQuery manipulation purposes.
Specifically, how do I do give each fieldset generated for an "Activity" record a unique CSS tag ID?
Posted below is how my form is created. Thank you
_form.html.erb
<%= form_for(#trip) do |f| %>
<%= f.fields_for :days do |builder| %>
<%= render 'day_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Day", f, :days %>
_day_fields.html.erb partial
<fieldset>
<%= f.label :summary, "Day Summary" %><br />
<%= f.text_area :summary, :rows => 1 %><br />
<%= link_to "remove", '#', class: "remove_fields" %>
<%= f.fields_for :activities do |builder| %>
<%= render 'activity_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Activity", f, :activities %>
</fieldset>
_activity_fields.html.erb
<fieldset>
<%= f.label :title, "Activity" %><br />
<%= f.text_field :title, :rows => 1 %><br />
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>
If you are using ryanb nested_form gem :
Use f.index instead. And make sure that you pass every different form_builder in your partials.
For example if you do
<%= main_form.fields_for :nested1_items do |nested1_form| %>
<%= render partial 'main/nested1_fields', nested1_form: nested1_form %>
<% end %>
_nested1_fields
<fieldset id="nested1-<%= nested1_form.index %>-items">
See my answer in this question.
Why not just use the f.object passed in to both partials?
<% fieldset_id = "#{f.object.class.underscore}_#{f.object.id}" %>
<fieldset id='<%= fieldset_id %>'>
...
I had a similar issue, and I solve it using the time in seconds, and pass it to every where I needed.
For example:
in the controller
def something
# First idea
#dynid = Time.now.to_i
...
# Second idea: store it in the session
session[:dynid] = Time.now.to_i
...
end
in your view
<fieldset id="#{#dynid}">
<!-- or in case #dynid is out of reach, then use the session[:dynid] -->
<fieldset id="#{session[:dynid]}">
The session[:dynid} will still works even with ajax rendered code.
I hope this helps you.

How to check if all checkboxes in an editor template is checked

I have a form using an editor template showing a series of checkboxes pertaining to a child list inside the form model. On form submit I need to check if all the checkboxes are checked for all child items and if not display a modal dialog to make sure that the user purposely decided to leave some of the checkboxes unchecked. I know that I can use the JQuery dialog to show the modal dialog, but I have no idea how to see if all the checkboxes in the editor templates are checked. My code is similar to the following:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Test.Models.ModelList>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
ShowPropReturn
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>ShowPropReturn</h2>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></script>
<% using (Html.BeginForm()) { %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>ModelList</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.MyProperty1) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.MyProperty1) %>
<%: Html.ValidationMessageFor(model => model.MyProperty1) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.MyProperty2) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.MyProperty2) %>
<%: Html.ValidationMessageFor(model => model.MyProperty2) %>
</div>
<table>
<%: Html.EditorFor(model => model.MyProperty3) %>
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
and for the editor template:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Test.Models.ColumnList>" %>
<tr>
<td>
<%= Html.CheckBoxFor(x => x.value) %>
</td>
</tr>
Any help would really be appreciated, thanks.
Add a CSS class to you editor template for the checkboxes that you want to validate
<%= Html.CheckBoxFor(x => x.value, new { #class = "chk" }) %>
And then you can use the jQuery :checked and :checkbox selectors to do a size() comparison.
if ($('input.chk:checkbox').size() == $('input.chk:checked')) {
}
add a class to your checkboxes like
<%= Html.CheckBoxFor(x => x.value,new{#class="chk"}) %>
and then hook in using jquery on submit event
$("#form").live('submit', function(e){
$(".chk").each(function(){
if($(this).attr("checked") == false)
{
//show modal dialogue here
}
});
});

Resources