Rails 3 link_to generator for :post, :put, & :delete? - http

I recently ran into this problem: Rails 3 link_to (:method => :delete) not working
In which I was confused why my link_to 'test', test_path(:test => test), :method => :post wasn't working (why it was GETting rather than POSTing). As the post above suggests, it was because I didn't have the Rails javascript files, which handles dynamically making the form on-the-fly for :post, :put & :delete.
I'm not sure I especially like relying on javascript to do this for me, as I'd like my app to be fully functional with javascript disabled; it's how I like to develop (so I know I've got all my Rails programming functionality works correctly), and when I do wire my app up with javascript, I don't have to worry about duplicating this functionality, since I usually wipe the stock javascripts file generated by Rails.
I read somewhere that, technically, hyperlinks (anchor elements) should only really be used for GET requests, and that buttons (as part of form elements) should be used for the other methods.
So, my two questions:
Is there a gem out there that will rewrite any link_to ... :method => in my view to a form element on-the-fly when my views are rendered?
If not, how would I hook into the view parser to write my own? (using HAML, preferrably)
Essentially, what I would like is to write this in my HAML file:
= link_to 'Test Link', some_path(:with => some_resource), :method => :post
... and have my rendered HTML output come out with this:
<form action="some_path?with=some_resource" method="post">
<!-- insert appropriate _method hidden field here -->
<!-- add appropriate csrf token and whatnot -->
<button type="submit">Test Link</button>
</form>
... so that all the link_to helpers with defined methods (thus, will not affect plain links whose verb is GET) will work without javascript?
I'd also appreciate any thoughts about the why part of this question, specifically why the Rails team decided to keep this functionality tied to javascript rather than doing this through pure HTML?

It seems that you really want a single element form (in this case, a button). If so, you want the button_to helper:
button_to 'Test Link', some_path(:with => some_resource), :method => :post
This will generate a form with an input[type=submit] element inside of it.
Without Javascript, you cannot have a hyperlink that will submit using a HTTP verb other than "GET."
If you need more style / control of the form being rendered by button_to, you can do something like this:
module LinksHelper
def link_form(text, destination, options = {})
form_tag(destination, :method => options.delete(:method)) do
<<-HTML
<!-- some HTML code here -->
<button type="submit">#{text}</button>
<!-- some more HTML code here -->
HTML
end
end
end

Related

Rails 4 - Bootstrap themes and crazy CSS

I have a rails 4 app.
I've been struggling for MONTHS to figure out how to incorporate a bootstrap theme. I thought using a design template might help me structure my content, but it is causing me a world of pain. I just can't figure out how to work with it.
Everything has been incorporated into the pipeline, but now I have instances of CSS that isn't in my code, being imposed.
For example, in my new user registration form, I have a submit button that has:
<div class="form-actions">
<%= f.button :submit, "Sign up", :class=>'btn btn-info' %>
</div>
The info button is blue. When I load the page, it shows with now background colour.
When I load localhost and inspect the element, I get this:
<input type="submit" name="commit" value="Sign up" class="btn btn-default btn btn-info">
The btn btn-default is not part of my code, but somehow it is being imposed.
Does anyone know how to solve this problem. I've torn my hair out for weeks trying to figure this out.
MORE INFO:
When I inspect the code, it shows the attributes of btn btn-info as struck out. I understand this to mean that a closer CSS tag has overridden that element, but the tag that inserts that CSS tag is the last in the list. How can there be anything closer? And if there is something, why doesn't it show in the inspector?
Are you using simple_form ? If so, take a look in your config/initializers/simple_form.rb (or simple_form_bootstrap.rb if you used the flag --bootstrap at the generation, which I think you did)
By default, Simple Form apply a specific wrapper (see documentation here to make your own).
If you just need this one button, either way, you have to specify it like so :
<%= f.input :username, input_html: { class: 'btn btn-info' } %>
You have the same helper for the generated label :
<%= f.input :username, label_html: { class: 'my_class' } %>
Now, for a button, apparently doing simply this should do the trick (according to the documentation):
<%= f.button :submit, "Custom Button Text", class: "btn btn-info" %>
Don't hesitate to have a look at the (well made) documentation here (once again, assuming you use Simple Form :-) )
Check simple_form_bootstrap.rb in your initializers and remove 'btn-default' class from
SimpleForm.setup do |config| config.button_class = 'btn btn-default'
Use e.g. your own style there - if you want it applied for all buttons. Alternatively, make this option an empty string and apply individual specific classes for each separate button:
<%= f.button :submit, class: "btn btn-specific" %>
The config value is added to button classes here
I don't see easy way to remove this class output for single specific control. Either remove it globally or override selectors for this style in your case.
See this - you can't individually remove btn-default class - need to remove it in general config file if you need

What does the form-inputs HTML class do in simple_form?

Doing a code search for "form-inputs" in the simple_form github repo indicates it's added as an HTML class in generated templates for ERB, slim, and erb. For example, in the HAML template file _form.html.haml:
= simple_form_for(#<%= singular_table_name %>) do |f|
= f.error_notification
.form-inputs
<%- attributes.each do |attribute| -%>
= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>
<%- end -%>
.form-actions
= f.button :submit
However, I can't see the HTML class being used within simple_form or elsewhere (such as Twitter Bootstrap). For example, I can't find any CSS files changing the styling of divs with the form-inputs class.
What is the purpose of the form-inputs class?
This was ostensibly added to "make it easier to integrate with bootstrap". It replaces a similar wrapper div with a different class. As you've pointed out, this is more relevant for form-actions than for form-inputs, so the latter is most likely just a convenient way to encapsulate all of the fields in a consistent way.

Format CSS output in Rails

I'm building a small rails app that saves CSS snippets. I have a controller that allows the user to 'get' my_app.com/styles.css, which outputs plain text of all css snippets that have been entered. Is there a way I can "prettify" that css as the view is rendered? Or do I need to use some sort of javascript plugin? Or even if I could "prettify" it when it's saved in the first place. I've seen some similar server side techniques used with CSSTidy, but that's PHP only.
Edit:
Here's how I'm rendering the css view:
In my routes.rb
get 'styles', to: 'styles#snippets'
In my controller
class StylesController < ApplicationController
def snippets
#entries = Entry.all
end
end
In my view (snippets.css.erb)
<% #entries.each do |entry| %>
/* <%= entry.name %>
======================================*/
<%= entry.css %>
<% end %>
This outputs a file with a tag and then each CSS snippet. The whitespace is just weird. I don't want to rely on the users's input to properly render the CSS indentation on the output. I'd rather format it on the output to be indented nicely.
you can look at a couple of options
highlight gem
coderay railscast
Pygments.rb

Rails 3 Ajaxful_rating Styling Issue

I'm using the ajaxful_rating gem for a user rating system in my rails app and I came across a weird styling issue:
As you can see there's much too many stars, there shouldn't be more than 5. I used Ajaxful_rating before in a previous app and didn't run into this problem. I recently started using Twitter Boostrap but as far as I can tell there aren't any styling conflicts as I removed every css link except the one needed for ajaxful_rating and I had the same issue.
Here's my view:
<dl>
<% Upload.by_ratings.limit(5).each do |upload| %>
<dt><%= link_to truncate(upload.name, :length => 55), upload%></dt>
<dd><%= upload.user.username %> - <%= ratings_for upload, :static %></dd>
<% end %>
</dl>
Has anybody ran into this problem before?
The problem was that I was directly linking to the css in my layout. I had forgotten that I needed to call the helper method ajaxful_rating_style instead.
place <%= ajaxful_rating_style %> in your javascripts.

ASP.NET MVC 2 client side validation not working for Html.ValidationMessage()?

I'm trying to get a very simple client side validation example to work in ASP.NET MVC 2. I'm using data annotations to set a required property "Surname". When I use the Html.ValidationMessageFor(x => x.Surname) the correct client side validation script is written to the page. But when I use Html.ValidationMessage("Surname") the client side validation is not rendered out until after the page has been posted. Client side validation only starts working after a form post! I can see that the script is updated in the page after a form post. There appears to be a bug in Html.ValidationMessage()?
Make sure you are referencing the correct scripts in your master page head.
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcValidation.js") %>" type="text/javascript"></script>
also look at your view to make sure the client validation call is above your form
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<%= Html.ValidationSummary(true) %>
...
<% } %>
and of course your validation message to show the problem.
<span class="editor-label"><%= Html.ValidationMessageFor(u => u.Name)%></span>
That is really all you need. I believe the required attribute will only start its check if you enter text in the field then remove the text and tab out of the field, so try that to see if you get the validation. Others will validate when the attribute needs to. For example the [StringLength(50)] will show an error message when you exceed 50 characters.
i've not tried but the metadata are stored on the proprerty so only the ValidationMessageFor has the ability to check the prop (via static reflection).
The other helper use a string key to access a modelstate dictionary without any reference to the property (and no validation metadata info), so i dot't think the Html.ValidationMessage(string key) has the ability to inject validation script client-side.
As far as I know the validation requires an attempt to validate even if it's client side.
You could try on the GET view creating a new instance of your model, then use TryValidateModel() before sending it to the view. This should cause the validation logic to run and thus to populate the clientside validation, this will result in all required fields showing their error version but depending how you choose to style them this doesn't have to be a big issue.

Resources