rails custom html elements form - html

I am new in Rails and i've searched around the web and books but I couldnt find how to make custom forms when working with rails..
what happens is that I am used to write my own HTML tags and I confortable with that. I dont like to use libs like JSF (from JAVA) that writes html components for me and I dont want that rails write it for me, except for simple tags like
text_field(:post, :title, :size => 20)
# => <input type="text" id="post_title" name="post[title]" size="20" value="#{#post.title}" />
so.. how can I do that.. for example: I would like to write by myself
<input type="text" class="myclass" data="mydata" name="how-to-get-the-attribute-name-with-rails" value="how-to-get-value-with-rails" />
how can I do that?

If you want more control over the html you are creating, you can also use a content_tag
content_tag :input, "label_name", class: "myclass", data: "mydata", name: "how-to-get-the-attribute-name-with-rails", value: "how-to-get-value-with-rails"
You can supplement any html element tag for :input. So if you want a div instead, use :div etc...

As you have written above, The name of any form field in rails is in the following format
name = 'post[name]' i.e. model_name[attribute_name]
So your params hash will contain :post => {:name => value} which allows you to use mass-assignment. But if you want to get some extra parameters from the form you can directly include them in the form and give them any name as you want. It will be available in your params hash.
You can get value easily using value = <%= #object.attribute_name. %>
I am not sure if you wanted to know this or something else. Let me know if you need more help.

You can simply write html inside a Rails form, so
<input type="text" class="myclass" data="mydata" name="how-to-get-the-attribute-name-with-rails" value="how-to-get-value-with-rails" />
is perfectly valid, but note that you should use the names and id's in correct way to automatically bind them to your back end controller.
After all, what text_field(:post, :title, :size => 20) does is it convert the parameters to pure HTML (we call them helper methods in Rails).
Read here for formhelper options (using helpers will keep your code clean).

Related

Displaying data from the console into an HTML form using EJS

So, I'm building an app where the user enters some data, the code modifies it, and returns it back to the user on the screen in an HTML input tag probably.
The user input is taken as : const userInput = req.body.user_word; (using Node.js for backend)
and the modified data is stored as var encrypted_word
I wish to display the contents of this variable into an input tag <input type="text" name="encrypted_word"> using EJS
I read that <%= tag is helpful in doing so but couldn't devise the solution.
Can someone help me with this...
i would use <%- instead of <%= also you have to the attribute value for inputs
<input type="text" value="<%- encrypted_word %>">

How can I include an HTML input in rails strong params?

I'm trying to create instances of a model "Post" with strong params that look like this:
private
def post_params
params.require(:post).permit(:name, {images: []})
end
In my form, this is how I upload files to post_params["images"], and therefore to post.images:
<%= f.file_field :images, multiple: true %>
But I want to apply custom styling to the upload button, so I build one using HTML. But I can't figure out what name attribute to give the input so that it's included in post_params. Here's what I've tried:
<input name="images" type="file" multiple="true"/>
<input name="post[images]" type="file" multiple="true"/>
<input name="post['images']" type="file" multiple="true"/>
<input name=":images" type="file" multiple="true"/>
But they all just go to params["post"]["images"], not strong_params.
What name can I give an HTML input so it's included in strong params?
Something like this:
<input multiple="multiple" name="post[images][]" id="posts_images" type="file">
This should generate the correct JSON params that your controller is expecting. It can get confusing with the multiple levels of hash/array. That's why I use the inspect element in the browser as mentioned in my comment above to see what Rails is generating, then I can build custom styled elements to suit my needs.
One way to remember it is: You are require-ing post, and then looking for a hash with a key of images and a value of type array. That way it's easier to know where to use singular vs plural, what is the key, etc. So mapping it out syntactically would be:
<model name>[<key defined in strong params>][]
in the .erb version if you look at the top of your form, think about what the value of f is in the ... do |f|. That's where it gets the controller name of post (singular) and then you are giving it the method name :images (plural) in the file_field. According to the Rails Docs you could use the singular :image but the plural seems more correct to me.

How to dynamically add text fields on Rails 4? (not nested)

I'm very new to Rails and I need to dynamically add/remove input fields on a "form_for" in Rails. I am using these inputs to alter a user's profile.
Here's the snippet I want to turn dynamic:
<%= f.label :languages, "Languages" %>
<%= f.text_field :languages, class: "shortInput", value: #parsed_json_user['user']['languages']%> <br />
I have seen many tutorials using nested attributes (I'm not even exactly sure about what those are) and such but I will not be using models. As you can see, I just want an object with a multitude of values (e.g. array) since I'll be using an API to update the "User" model.
I need something like:
Languages:
English remove
add new
Should I be using fields_for? Or somehow use JS or JQuery? Any help would be appreciated.
I searched everywhere for a similar question and haven't found any but if you actually know of or find one, pointing me in the right direction would be wonderful!
Thanks in advance
#languages = User's Languages
f.collection_select :user_languages[], #languages, :id, :name , {hide_label: true, :selected => #languages.first.id} , {:style => "width: 120px",:required => true}
Update: For single form, no nesting - one option is to hack together your own jquery. I had used a different site for my testing, but this Jquery example was the one I found easier. I removed the stuff about a counter for max fields ... it goes in the /app/assests/javascript/.js ...
$(document).ready(function() {
$(".add_field_button").click(function(e){ //on add input button click
e.preventDefault();
$('.input_fields_wrap').append('<div><input type="text" name="mytext[]"/>Remove</div>'); //add input box
}
});
$(".input_fields_wrap").on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove();
})
});
And the html code ...
<div class="input_fields_wrap">
<button class="add_field_button">Add More Fields</button>
<div><input type="text" name="mytext[]"></div>
</div>
If you're not having luck yet - Cocoon Gem or railscast 197/198 will do what you need with jquery which is dynamic. Ignore the parts about nesting and just take what you need from it.
Also, I'm still poking around in turbolinks which had an update recently...you might be able to find an answer there...probably not exactly what you would want...
From what I can tell is that is rely's on two paths you write in rails, that are then built upon via the jquery that acts on (add/delete) :before or :after the link_to_add_association or link_to_remove_association in order to add/hide fields from view on the dom & then the update button actually pushes the whole mess to through activeRecord into the database.

Rails: Creating HTML in a Model

I have a Publication model with a has_many relationship to Contributors. In the model, I have a method that's meant to create an html-ready by line:
def authors
authors = []
Contributor.where(:publication_id => self.id).each do |author|
authors << "link_to "+author.name+", Contributor.find("+author.id.to_s+")"
end
authors.to_sentence
end
In my view, I have the following line:
by <%= #publication.authors %>
But instead of rendering links, it renders the raw code, such as:
by link_to B, Contributor.find(1)
I've tried patching this by adding .html_safe to the end of #publication.authors, but to no avail. Is there a better way to transfer these links from the model to the view?
You're pushing strings into your authors array. It looks like valid code, so running eval on it should work. (Actually author.name will probably evaluate as an undefined symbol, so scratch that.)
A better way would be to use a has_many :authors, :model => 'Contributor' relationship on your Publication model, and you can bring up your array of Contributor objects by simply calling
#publication.authors
You'd want to iterate over these in your view like so:
<% #publication.authors.each do |author| %>
<%= link_to author.name, author %>
<% end %>
Note also that if you're displaying multiple Publication objects in a view this way, you'll want to use Publication.includes(:authors) in your controller when you're retrieving them to avoid the "N+1" problem.
Now, three lines of code doesn't seem very expensive to repeat, but there are ways to DRY that without violating the MVC pattern and cluttering your model:
Place the code to print a publication's authors into a partial, and call the partial as needed.
Place the code into a helper, include the helper and call the method as needed.
Here's a snippet from the source for to_sentence (you can adapt it for your needs, I think):
case length
when 0
""
when 1
self[0].to_s.dup
when 2
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
else
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
end
The full source can be found here.
It looks like you are trying to use haml syntax in your line. Maybe instead of using link_to, use an html hyperlink tag itself?
That being said, why are you having a model return html?
Edit: bdares answered already with what I was trying to say

string with full stop in it not properly outputted in html

I have a Question model in my Ruby on Rails project with Postgresql database which has a string data type called question. (Original hey!) When I input some data with a full stop (.) in it, it doesn't print/output in my html/erb view file correctly, everything before the full stop is missing!
<div class="field">
<%= f.label question.question %><br />
....
It is storing in my database correctly as per the below output from the psql console
select question from questions where "id"=1;
question
----------------------------------
What is 2+3. What is the answer?
(1 row)
Does anyone know what is happening here (and the workaround)? I've tried things such as .html_safe and .to_s to no avail.
EDIT: also another thing that bothers me about the html output is that it gets rid of all my capitalized letters. Wtf?!
So the html output of the example about would be below...
what is the answer?
Not sure about the disappearing text part, but the label helper applies the humanize method to auto-generated label text (i.e. if no explicit label text is passed in). In the console it looks like this:
ruby-1.9.2-p290 :006 > helper.label_tag "All Caps String"
=> "<label for=\"All_Caps_String\">All caps string</label>"
As a workaround, try providing an explicit label value:
ruby-1.9.2-p290 :007 > helper.label_tag "All Caps String", "All Caps String"
=> "<label for=\"All_Caps_String\">All Caps String</label>
So try this:
<%= f.label question.question, question.question %>