Microsoft's jQuery Validate Unobtrusive makes other validators skip validation - asp.net-mvc

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.

Related

Bootstrap date picker not working on on my form using Grails site mesh main.gsp - but works for standalone form

I'm trying to see if I can get the Bootstrap datePicker (datePicker)to work in Grails v3.3.9/fields plugin 2.2.10
I've done a standalone page, that is I create a controller, and give it an action called 'ldt'.
I create grails view called ldt.gsp like this. When I hit trigger my controller in the browser - this simple page renders fine and datePicker works
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap datepicket demo</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script type='text/javascript' src='//code.jquery.com/jquery-1.8.3.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
<script type='text/javascript'>
$(function(){
//$('.input-group.date').datepicker({
$('#datepicker').datepicker({
calendarWeeks: true,
todayHighlight: true,
autoclose: true
});
});
</script>
</head>
<body>
<div class="container">
<h1>Bootstrap datepicker</h1>
<div class="input-group date" id="datepicker">
<input type="text" class="form-control">
<span class="input-group-addon">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</div>
</body>
</html>
You can see that here. This is not using normal Grails site mesh etc
So I tried to put the same into views/layouts/main.gsp
So here is the head section of my revised main.gsp. (I've not included Bootstrap nor jQuery as them come with grails application.js).
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>
<g:layoutTitle default="Grails"/>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<asset:link rel="icon" href="favicon.ico" type="image/x-ico"/>
<asset:stylesheet src="application.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
<script type='text/javascript'>
$(function(){
$('#datepicker').datepicker({
calendarWeeks: true,
todayHighlight: true,
autoclose: true
});
});
</script>
<g:layoutHead/>
<%-- header assets --%>
</head>....
Now I am trying to render a specific field in the domain class - which is of type LocalDateTime. To try and do this I have created a _fields/localDateTime/_wrapper.gsp that looks like this in which I setup the input control (as I did for the standalone page), but I give the input a start date time for now.
localDateTime/_wrapper.gsp
<%# page import="java.time.LocalDateTime; java.time.format.DateTimeFormatter" %>
<g:set var="localDateTimePattern" value="${message(code: 'default.localDateTime.format',default: 'yyyy-MM-dd HH:mm')}"/>
<div class="fieldcontain" >
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class="input-group date" id='datetimepicker1' >
<label for=${this.pageScope.property}> ${this.pageScope.getVariable("label")} </label>
<input type='text' class="form-control" value="${java.time.LocalDateTime.now().toString()}"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
When I go this page in the browser it gets rendered, but the clickable field behaviour etc does not fire and the field has no calendar icon on the right hand side (this may be because Grails is loading Bootstrap 4, and when I tried the standalone with v4.3.1 the icon didn't render - but the click event still worked).
See rendered form here - using the 'edit' action which in turn is using standard scaffolds with <f:all which calls my _wrapper.gsp.
The string value of the date gets rendered fine (not formatted), but I get no click action and calendar doesn't pop up - no action at all. I've included a snip of the browser page inspection in the browser opened for the contractSignedDate property.
So if a standalone page gsp works just fine (albeit with Bootstrap 4 as loaded by Grails bau) does my click action not fire
So why can't the gsp action action fire when using the main.gsp/normal fields plugin/and _wrapper.gsp for java LocalDateTime? It worked for standalone gsp example so I know the datePicker works
How can I get the Bootstrap datepicker as described here working in a Grails scaffolded form?
PS it's not missing jqueryUI library - I've included 1.12.1 in both standalone and main.gsp see this image from inspector. Works fine on standalone but not using main.gsp and scaffolded forms
PS if I click into the scaffolded form property as shown in the _widget.gsp, the outer text box is highlighted in blue (which the bau grails rendered elements don't - so some form of click action is happening - just not getting a calendar to pop up.
This is very odd. When referenced on standalone gsp and link JS/CSS from CDN, the page worked.
If I add <meta name="layout" content="main" /> and had the page rendered via site mesh in main.gsp it would fail.
I tried many different combinations in the standalone page <head>, and basically the date picker doesn't seem to need the bootstrap js to work - but it does need the jQuery and it must be in the head section.
If you want the styles you need to include the bootstrap.css and the bootstrap-datepicker3 CSS.
<head>
<%--<meta name="layout" content="main" />--%>
<title>Bootstrap datepicket demo</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<%--<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script> --%>
<script type='text/javascript' src='//code.jquery.com/jquery-3.3.1.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
</head>
However if you uncommented the meta tag it would all stop. In the end to get this to work I had to edit the /assets/application.js and remove the entries for Bootstrap and jQuery using the local copies in /assets/javascripts, and instead reference these directly from the cdn in main.gsp.
So my working application.js looks like this - where I include my own LCM-app JS:
// This is a manifest file that'll be compiled into application.js.
//
// Any JavaScript file within this directory can be referenced here using a relative path.
//
// You're free to add application-wide JavaScript to this file, but it's generally better
// to create separate JavaScript files as needed.
//= require LCM-app
//= require popper.min
//= require_self
My LCM-app js just looks like this where my selector is using class selector - note you seem to have add the dot between group and date '.input-group.date' - but that becomes a space in your markup
// used by bootstrap date picker - matching class selector is for class class='.input-group date'
$(function(){
$('.input-group.date').datepicker({
calendarWeeks: true,
todayHighlight: true,
autoclose: true
});
});
I then went to main.gsp and edited in the cdn references that I had in the standlone page (asset plugin is now disabled for jQuery and Bootstrap)
main.gsp (head section) - you dont need jqueryUI for this to work
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>
<g:layoutTitle default="Grails"/>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<asset:link rel="icon" href="favicon.ico" type="image/x-ico"/>
<asset:stylesheet src="application.css"/>
<%-- <script type='text/javascript' src='//code.jquery.com/jquery-1.12.1.js'></script>--%>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script type='text/javascript' src='//code.jquery.com/jquery-3.3.1.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
<g:layoutHead/>
<%-- header assets --%>
</head>
Now when you uncomment out the <meta> tag in the standalone page and remove the direct refs - then the main.gsp site mesh adds these back exactly as they were in the standalone page
Point your browser at the test page and it all works as normal.
It even works when I put the basic code into a taglib (you have to stop the escaping using the static encodeAsForTags and set to 'none' for your tag).
JdtDateTimeTagLib
class JavaDateTimeTagLib {
static defaultEncodeAs = [taglib:'html']
//static encodeAsForTags = [tagName: [taglib:'html'], otherTagName: [taglib:'none']]
static encodeAsForTags = [ jdtScaffoldField:'none']
static namespace = "jdt" //java8 date time name space for tags
GrailsNameUtils grailsNameUtils = new GrailsNameUtils()
def jdtScaffoldField = {attrs, body ->
assert grailsNameUtils
String propertyName = attrs.propertyName ?: "unknown"
String property = attrs.property ?: "unknown"
String value = attrs.value
String naturalName = grailsNameUtils.getNaturalName(propertyName)
String label = attrs.label ?: 'unknown'
String ldtStr = attrs.ldt
String page = """
<g:set var="localDateTimePattern" value="${message(code: 'default.localDateTime.format',default: 'yyyy-MM-dd HH:mm')}"/>
<div class="fieldcontain" >
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group form-inline">
<label class='control-label' for="$propertyName"> ${label} </label>
<div class="input-group date" >
<input type='text' class="form-control" value="${ldtStr?.toString()}"/>
<span class="input-group-addon">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
"""
out << page
}
}
I can then simplify the _fields/localDateTime/_wrapper.gsp to use that tag like so
<%# page import="java.time.LocalDateTime; java.time.format.DateTimeFormatter" %>
<g:set var="localDateTimePattern" value="${message(code: 'default.localDateTime.format',default: 'yyyy-MM-dd HH:mm')}"/>
<jdt:jdtScaffoldField propertyName="xyc" label="my label"></jdt:jdtScaffoldField>
Now when you go to a normal grails edit action my field is rendered and the calendar actions.
I've lost variables in this version as I'm not getting the values passed to the wrapper and putting them forward into my tag - but I think that's not too hard. See working screen shot 'as-is'
Sadly the lest of the Grails scaffolding is using its own rendering so the CSS styles don't match, alignment is a bit out etc - but its an improvement if I can just get the submit action etc to take the selected date and convert pack to LocalDateTime to persist in the database.
Basically it would be better if the grails <g:datePicker could be 'fixed' to work with new Java time formats and use the Bootstrap picker - because the fields plugin invokes the <g:datePicker for ordinary Java Date but completely doesn't handle the Java 8 temporal stuff.
I have tried to 'find' where the grails <g: taglib is implemented (thought it was going to be in the GSP plugin or core projects - but I can't find it in either.
However whilst it's not ideal - its good enough for the mini demo using scaffolds I was going to show people - just looks a little clunky as it's not consistent.

How to get form data in Java Spark using Thymeleaf template engine?

I've built a simple application and now I'm trying to host attach it to a web server. I'm attempting to have a HTML form (using Thymeleaf) that the user enters their location in as text, and then my server will take and produce a result using that string. So to get started, I'm attempting to make a simple spark application that makes a home page with a "enter your location" form, that then gets the users input and does something with it. I can get the "entryMessage" displayed, as tutorials show, but how to get user data is proving difficult.
However, there is very little documentation on how this can be done with these two framworks. My attempt at what the code should look like is as follows. Note the middle post is just me trying to find ways to get the form data - none proved succesful
ThymeleafTemplateEngine engine = new ThymeleafTemplateEngine();
HashMap<String, String> userLocationMap = new HashMap<>();
get("/home", (request, response) -> {
userLocationMap.put("entryMessage", "Please enter your location");
return new ModelAndView(userLocationMap, "home");
}, engine);
post("/home", (request, response) -> {
System.out.println(request.toString());
//System.out.println(request.body());
//System.out.println(userResponse.location);
//response.redirect("/locationAccepted");
return userLocationMap.get("userLocation");
});
get("/locationAccepted", (request, response) -> {
String location = request.queryParams("userLocation");
return new ModelAndView(userLocationMap, "locationAccepted");
}, engine);
with the following thymeleaf templates
home.html
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p> <span th:text="${entryMessage}"> default message </span> </p>
<form action="/locationAccepted" method="post">
<input type="text" th:field="userLocation"/>
<div class="button">
<button type="submit">Send your message</button>
</div>
</form>
</body>
</html>
and locationAccepted.html
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p> <span th:text="${userLocation}"> default message </span> </p>
</form>
</body>
</html>
You have two bugs in your code, both in the HTML form:
In your Java code you're defining the route "/locationAccepted" as GET, but your form method attribute is POST => Change your form to GET.
If you want to get the form's input data it should have a name with value userLocation. th:field isn't translated to name (it's translated to field attribute which I'm not sure what it means).
So your form (after Thymeleaf) should look like this:
<form action="/locationAccepted" method="GET">
<input type="text" name="userLocation"/>
<div class="button">
<button type="submit">Send your message</button>
</div>
</form>
And then request.queryParams("userLocation") will work like you wanted.

Sammy.js and Knockout.js => Templating without templates?

I am fairly new to the concept of javascript client side development. I am running into an issue, though it may be I just don't understand how to accomplish something with the mash of frameworks.
I know I want to use Knockout for it's rich client side goodies. I also wanna use Sammy.js to allow for routing and passing data to the knockout views (I come from an MVC background where I stuff a model with data, then return view(model), and MVC binds it nice and good for me).
So now I am trying to do something similar client side...
Here is my Index.html :
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>The EClassifieds Mobile</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<!-- <script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>-->
<script type="text/javascript" charset="utf-8" src="./scripts/cordova-1.8.1.js"></script>
<script type="text/javascript" charset="utf-8" src="./scripts/knockout.js"></script>
<script type="text/javascript" charset="utf-8" src="./scripts/templ.js"></script>
<script type="text/javascript" charset="utf-8" src="./scripts/sammy.js"></script>
<script type="text/javascript" charset="utf-8" src="./scripts/sammy.tmpl.js"></script>
<script type="text/javascript" charset="utf-8" src="./services/RouteManager.js"></script>
<script type="text/javascript" charset="utf-8" src="./services/ApplicationManager.js"></script>
<link rel="stylesheet" href="./style/site.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
<!-- <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />-->
</head>
<body>
<div id="main">
<h1>HELLO WORLD!</h1>
<!--Sammy should update the content of this div dynamically, creating a SPA (single page application)-->
</div>
</body>
</html>
Here is my Sammy Configuration.
(function ($) {
alert('Building Routes');
var app = $.sammy('#main', function () {
this.use('Tmpl', 'html');
this.get('#/', function (context) {
alert('Rendering Partial for Login page');
context.app.swap('Loading...');
this.render("/views/Login.html");
});
});
$(function () {
app.run('#/');
});
})(jQuery);
Here is my Login.html
<!--Model File Goes Here -->
<script type="text/javascript" charset="utf-8" src="../models/Login.js"></script>
<fieldset title="Please Login to Begin :">
<div data-role="content" style="padding: 15px">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-mini="true">
<label for="txtUsername">
Username
</label>
<input id="txtUsername" data-bind="value: username" placeholder="Stevie" value="" type="text" />
</fieldset>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-mini="true">
<label for="txtPassword">
Password
</label>
<input id="txtPassword" data-bind="value: password" placeholder="yep!" value="" type="password" />
</fieldset>
</div>
<a id="btnLogin" data-role="button" data-transition="fade" href="#page1" >
Login
</a>
</div>
<div id="errorText">
<h1></h1>
</div>
<p id="deviceProperties">Loading device properties...</p>
</fieldset>
<script type="text/javascript">
$(document).ready(function () {
ko.applyBindings(new LoginDataModel(0, "Stevie", "theTV", true));
});
</script>
I also need some way to pass the data from the sammy get handler, to the knockout page. Is there a way to do this, or am I attempting the impossible?
UPDATE 1 :
I would really love to be able to do something like :
var app = $.sammy('#main', function () {
this.use('Tmpl', 'html');
this.get('#/', function (context) {
alert('Rendering Partial for Login page');
context.app.swap('Loading...');
var data = getLoginData();
this.render("/views/Login.html", data);
});
Sammy does this same exact thing using other template frameworks, however, I don't see how I would bind the $data in the Knockout view to the data passed from Sammy.
Not sure if you saw this, but the webmail tutorial on the knockoutjs website uses sammy.js for routing:
http://learn.knockoutjs.com/#/?tutorial=webmail
Here's a link to the finished product (so you can view source if you don't want to follow the whole tutorial)
http://learn.knockoutjs.com/WebmailExampleStandalone.html
the Knockout.js-External-Templates plugin will help you in achieving this behavior. A good starting point will be from here
EDIT: The "starting point" link now goes to malware.
Even John Papa endorses it here
The above solution is useful only when you frequently reuse your templates. Use inline templating whenever possible. Inline templating – and using foreach binding, performs around 1/3 faster than applying template from a separate DOM element, the so-called named template binding. More info on this here

javascript with MVC 3 Razor view engine

I have following code :
<html> <head>
<!-- Required CSS --> <link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/2.9.0/build/treeview/assets/skins/sam/treeview.css"> <!-- Optional CSS for for date editing with Calendar--> <link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/2.9.0/build/calendar/assets/skins/sam/calendar.css"> <!-- Dependency source file --> <script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"
></script> <!-- Optional dependency source file --> <script src="http://yui.yahooapis.com/2.9.0/build/animation/animation-min.js" type="text/javascript"></script> <!-- Optional dependency source file for date editing with Calendar--> <script src="http://yui.yahooapis.com/2.9.0/build/calendar/calendar-min.js"
></script> <!-- Optional dependency source file to decode contents of yuiConfig markup attribute--> <script src="http://yui.yahooapis.com/2.9.0/build/json/json-min.js" ></script> <!-- TreeView source file --> <script src="http://yui.yahooapis.com/2.9.0/build/treeview/treeview-min.js"
></script>
</head> <body class="yui-skin-sam">
#model IEnumerable< ESimSol.BusinessObjects.MenuTreeNode>
<input type="button" id="btnAdd" value="Refresh" /> <label id="lblTest"> </label> <div id="treeDiv1"> <ul>
#foreach (var item in Model)
{
if (item.ParentID == 0)
{
<li>
#Html.DisplayFor(modelItem => item.MenuName)
<ul>
#Html.Partial("TreeViewControl", item)
</ul>
</li>
}
} </ul> </div> </body> </html>
<script type="text/javascript">
$(document).ready(function () {
treeInit();
});
var tree;
function treeInit() {
tree = new YAHOO.widget.TreeView(document.getElementById("treeDiv1"));
}
</script>
When I want to execute my script i face following Exception:
Microsoft JScript runtime error: Object expected
any one give me a complete reference for javascript execute with MVC3 RAZOR View engine?
Keep in mind that using javascript with MVC3/Razor is no different than using it with any other page - JS is a client-side language, so it's always working with the rendered HTML.
I don't see anything standing out as an error in your JS code, but your <script> element should be inside the <body> element. Most browsers handle it OK, so I doubt that's your issue.
I'd recommend that you check your script references to verify that they're correct, then look into the script further. The script error you're getting in IE should reference a line #, which you can use to look at the page source (the rendered page, not the razor page) to try and locate the source of the error.

Rails 3 Form Helpers: UTF8 and other hidden fields

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

Resources