Rails 3 Form Helpers: UTF8 and other hidden fields - ruby-on-rails

The view:
<%= form_for :blog_post do |f| %>
<ul>
<li>
<%= f.label :title %>
<%= f.text_field :title, :type => 'text', :id => 'title', :size => '', :limit => '255' %>
</li>
</ul>
<% end %>
<!DOCTYPE html>
<html>
<head>
<title>LevihackwithCom</title>
<script src="/javascripts/prototype.js?1285902540" type="text/javascript"></script>
<script src="/javascripts/effects.js?1285902540" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1285902540" type="text/javascript"></script>
<script src="/javascripts/controls.js?1285902540" type="text/javascript"></script>
<script src="/javascripts/rails.js?1285902540" type="text/javascript"></script>
<script src="/javascripts/application.js?1285902540" type="text/javascript"></script>
<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="UnhGSHHanJHfgJYhnksqJ1bfq3W+QEU2GJqLAMs2DmI="/>
</head>
<body>
<form accept-charset="UTF-8" action="/blog_post/new" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="UnhGSHHanJHfgJYhnksqJ1bfq3W+QEU2GJqLAMs2DmI=" />
</div>
<ul>
<li>
<label for="blog_post_title">Title</label>
<input id="title" limit="255" name="blog_post[title]" size="" type="text" />
</li>
</ul>
</form>
</body>
</html>
I'm messing around with form helpers. The above code shows my view file as well as the HTML it generates. What is with the terrible div full of inline CSS stuffed with hidden fields I didn't explicitly ask for? What settings cause these fields to be generated? Is there a way for me to remove the inline CSS?

These fields are generated in rails forms for robustness:
utf8=✓
The utf8 hidden field ensures that the form values are submitted as UTF8. It does this by ensuring that at least one UTF8 character in the form gets submitted. Most browsers respect the document's encoding and treat the form values the same, but there's one browser that has a problem. Hence, utf8 gets a checkmark.
The authenticity_token is there to prevent cross-site request forgery.
Similar hidden fields get generated for checkboxes. Since unchecked checkboxes don't get submitted to the server, a hidden field ensures that a "0" (false) value gets submitted: this is helpful when you have an array of checkboxes.
These fields get wrapped in a div with inline styles to ensure that they don't break the layout. You could poke around in the form helper source code and override this, but I wouldn't recommend it: it's minimally intrusive, and it's there for a reason.

If you want to get rid of the utf8=✓ you may be interested in this gem, which adds it only to non-complying browsers:
https://github.com/softace/utf8_enforcer_workaround

Related

Ruby on rails CSRF protection forms

I understand that rails add CSRF tokens to the forms created with its custom functions like form_with etc. BUT does it also generate CSRF tokens (a.k.a authenticity_token in rails terms) for general HTML
I am seeing mixed answers for this. Anyone with hands-on experience on Rails help me here?
I figured I should make this into a full fledged answer.
No, manually creating a <form></form> in Rails will not automatically insert the authenticity token. The token is only inserted when using a Rails form helper. These helpers allow you to specify the fields for a form without specifying the authenticity token; it will put the token field into the form automatically. For example:
<%= form_for #person do |f| %>
<%= f.label :first_name %>:
<%= f.text_field :first_name %><br />
<%= f.label :last_name %>:
<%= f.text_field :last_name %><br />
<%= f.submit %>
<% end %>
Generates the following HTML with the hidden authenticity_token field:
<form action="/people" class="new_person" id="new_person" method="post">
<input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
<label for="person_first_name">First name</label>:
<input id="person_first_name" name="person[first_name]" type="text" /><br />
<label for="person_last_name">Last name</label>:
<input id="person_last_name" name="person[last_name]" type="text" /><br />
<input name="commit" type="submit" value="Create Person" />
</form>
But if you manually generate the HTML, for example using HAML:
%html
%head
%body
%form
The generated HTML looks like:
<html>
<head></head>
<body>
<form></form>
</body>
</html>
...without any authenticity_token field.
In the article you linked to, it says "A typical form generated in Rails..." meaning generated using a Rails form helper. Manually created forms are not "generated" in the sense used in this context.

AngularJS ng-change does not work when get request with Ruby on Rails 5

I'm using ...
Ruby on Rails 5
AngularJS 1.3.20
Chrome or FireFox Browser
It seems ng-change event does not work, when I request get method like link from other page. But when I user POST request to next page, it works.
When I change select box value, onchange event is not happen. I expect ng-change
should reach changeHandler function in sample.js and console.log("ChangeHandler!!!") show up.
In addition, I use Ruby on Rails application template. So ng-app and ng-controller is same as index1.html and index2.html.
** Additional Info
I tried Chrome ng-inspector for AngularJS Tool. But There is no angular panel shown up. But once reload same page, it shows up. What happend?
index1.html.erb
<html lang="ja" ng-app="MyApp">
<body ng-controller="MyController">
<!-- For GET Method Request -->
<div>
<%= link_to 'Index2', sample_index2_path %>
</div>
<!-- For POST Method Request -->
<div>
<%= form_tag sample_index2_path do %>
<%= button_tag "Click" %>
<% end %>
</div>
</body>
</html>
index2.html.erb
<html lang="ja" ng-app="MyApp">
<body ng-controller="MyController">
<div>
<form>
<select id="eventTest" ng-model="eventTest" ng-change="changeHandler()">
<option value="1">AAA</option>
<option value="2">BBB</option>
<option value="3">CCC</option>
</select>
</form>
</div>
</body>
</html>
sample.js
angular.module('MyApp',[])
.controller("MyController", ['$scope', function($scope) {
$scope.eventTest;
$scope.changeHandler = function () {
console.log("ChangeHandler!!!");
};
}]);
This works only POST, or Get and reload Browser.
There are any difference between output HTML source code GET and POST.
I'm stack over 3 days.
Please let me know and advice for me.
The reason why Angular Module does not work properly was JavaScript lib turbolinks.
I fixed this by modifying default setting reload -> false, or erasing data-turbolinks-track.
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
                                  ↓↓↓↓
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'false' %>

Capybara & Poltergeist will not find my button

This seems to be a common asked question, but I feel I have tried absolutely everything now. (find, click_button, locate etc. etc). Nothing works (all listed below)
Seems to be consensus that if the css (e.g. divs out of place) it causes problems from Capybara. so I've now stripped back my html to the absolute bare minimum (below). yet nothing seems to find my confirm button.
I am using zurb foundation, but doesn't seem to be anything that suggests this is at fault.
I'm sure its something simple (It always is!) but damned if I can find…. any thoughts much appreciated?
html
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/foundation.css">
</head>
<body>
<form accept-charset="UTF-8" action="/register_user" enctype="multipart/form-data" id="form_wizard2" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="hvDwKcztZ4jS0KNtRMD324EfTo+eNtHfSZVD/yDWVZc=" />
</div>
<input class="button postfix" id="confirm_email_btn" name="commit" type="submit" value="Confirm" />
</form>
</body>
</html>
generated from rails erb
<%= form_tag("/register_user", :method => :post, :multipart => true, :id => "form_wizard2") do -%>
<%= submit_tag "Confirm", :class => "button postfix", :id => "confirm_email_btn" %>
<% end %>
rspec test
it 'asks an anonymous user for their email address and asks to check inbox', :driver => :poltergeist, :js => true do
< find test what ever it is >
end
what I have tried
check html
puts page.html to check outputs
save_and_open_page to check html
Capybara::ElementNotFound Exception
find(:xpath,'//a[#id="confirm_email_btn"]')
all(:xpath,'//a[#id="confirm_email_btn"]').first
find("#confirm_email_btn")
find('input#commit')
breaks poltergeist
scoping (seems to break poltergeist)
within("//form[#id='form_wizard2']") do
find("//input[#type='submit']").click
end
other
prefixing all the above with "page."

AngularJs not working with dynamic html

In my cshtml file I have a form named 'ApplyMedicalMain' and I want to show a dynamically loaded division when the form is dirty but its not happening even though the form is dirty ...
Below is my code that i got in Firefox Inspect Element:
<form class="form_section ng-dirty ng-valid ng-valid-required" name="ApplyMedicalMain" method="post" action="/MVC/Quote/ApplyMedical">
<div id="Step1_PartialView" class="QuoteStep1">
<script type="text/javascript" src="/Scripts/Renderings/Presales/ApplyMedical.js">
<div name="Conditions" id="conditions_or_symptoms" ng-hide="ApplyMedicalMain.$dirty">
<div class="generic_error_message select">
<div class="error_icn_message"></div>
</div>
As you can see above, I have mentioned ng-hide for the division name='conditions' but it is not getting hidden even though the form has class 'ng-dirty'.And please note that the the division 'conditions' is loaded dynamically from other partial view.
can someone help me ?
You forgot to wrap everything in a 'ng-app' container, here is a working example (I cleaned a bit the code)
<div ng-app>
<form class="form_section ng-dirty ng-valid ng-valid-required" id="ApplyMedicalMain" method="post">
<div ng-hide="ApplyMedicalMain.$dirty">Hidden when dirty</div>
<div ng-show="ApplyMedicalMain.$dirty">Shown when dirty</div>
</form>
</div>
I'm not entirely sure why your example isn't working, but I would suggest you use css to do your hiding/showing rather than using angular's bindings:
form.ng-dirty .hide-on-dirty{
display:none;
}
And then:
<form class="form_section ng-dirty ng-valid ng-valid-required" name="ApplyMedicalMain" method="post" action="/MVC/Quote/ApplyMedical">
<div id="conditions_or_symptoms" class="hide-on-dirty"> ... </div>
</form>
That's a bit more efficient that creating a binding to the form controller's state. But its just a thought. There might be more of a reason why you're wanting to do the binding.

Microsoft's jQuery Validate Unobtrusive makes other validators skip validation

I'm using unobtrusive validation in an MVC3 application. For one form, I need to do some pretty complex validation. Therefore, I figured I could use the regular jQuery validate plugin. When using a custom validation script and a reference to jQuery.validate.unobtrusive.js is included in the page, the custom validation scripts will always be valid!
Create an test html file (and include jquery.validate.js, jquery.unobtrusive-ajax.js, and jquery.validate.unobtrusive.js). When the following form is submitted, the validation checks won't be performed. Removing the script reference to jquery.validate.unobtrustive.js makes them work again. Is there a simple way around this?
<!DOCTYPE html>
<html>
<head>
<title>Test Jquery</title>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.4.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.js"></script>
<script type="text/javascript" src="jquery.validate.js"></script>
<script type="text/javascript" src="jquery.unobtrusive-ajax.js"></script>
<script type="text/javascript" src="jquery.validate.unobtrusive.js"></script>
<script type="text/javascript">
$(function ()
{
var result = $("#commentForm").validate({
rules:
{
name: "required",
email: {
required: true,
email: true
},
comment: "required"
}
});
});
</script>
</head>
<body>
<form id="commentForm" method="get" action="">
<fieldset>
<legend>A simple comment form with submit validation and default messages</legend>
<p>
<label for="cname">Name</label>
<em>*</em><input id="cname" name="name" size="25" />
</p>
<p>
<label for="cemail">E-Mail</label>
<em>*</em><input id="cemail" name="email" size="25" />
</p>
<p>
<label for="ccomment">Your comment</label>
<em>*</em><textarea id="ccomment" name="comment" cols="22"></textarea>
</p>
<p>
<input class="submit" type="submit" value="Submit" />
</p>
</fieldset>
</form>
</body>
</html>
When using ASP.NET MVC 3 unobtrusive client side validation you shouldn't write custom rules as you did. Also it seems that you have included the jquery.validate.js script twice and the jquery.unobtrusive-ajax.js script is not necessary for client side validation. You should use DataAnnotations on your model to indicate validation rules and for more complex scenarios when you need custom rules you have the possibility to implement the IClientValidatable interface and attach custom adapters to the jquery validate plugin. You may take a look at the following answers which illustrate this concept: answer 1 and the followup answer 2.

Resources