Right now, I have a simple <%= date_select(:record, :date, ampm: false) %> in my view. For the past few days, I've been trying to implement a datetime viewer, and just can't grasp it. I've looked at pickadate.js, Bootstrap 3 Datetimepicker, and others. I understand the jQuery behind them - it's simple to just apply a class to an <input> field.
What I don't understand is how the date gets correctly passed as a part of my Rails form. For example, pickadate.js applies a class to an <input> field, but how does my form_for recognize what attribute it's for? When I use a date_select(:record, :date), I'm telling my app that the input should be recorded in the record model as the date attribute, right? How do I do this with a client-side <input> field?
Related
I'm building a simple project where date input plays an important role. I don't want to add an another gem and heavy js library like jquery, bootstrap.
What is the most lightweight solution where I can let users to select/enter date? The pure Ruby way.
Thank you
EDIT:
I use date_field type, but it lets me enter any value. It does not format my input as date.
Code sample:
<%= form.date_field :date %>
SOLUTION (temporary):
Right! I needed to use date_select, not date_field : )
<%= form.date_select :date %>
Your date field should also work but you can try this also , may be this work for you.
<%= form.date_field :date, min: 0.days.ago %>
Rails has a whole heap of in built form helpers for selecting dates and other data types: https://api.rubyonrails.org/v6.0.0/classes/ActionView/Helpers/DateHelper.html#method-i-select_date
I am not sure what you mean by 'pure ruby' as a date picker is html/css with some optional js, but the select_date form helper (and all other rails form helpers) are ruby objects under the hood, which, given arguments, will return HTML.
In addition to the above link, you should check out these docs for how to implement inside a form: https://guides.rubyonrails.org/form_helpers.html#dealing-with-basic-forms
This has to do with the browser support for date_field. It has improved quite a lot recently, see https://caniuse.com/mdn-html_elements_input_input-date
My ransack form has a date to and from search using a datepicker for each. The search and results works great, however I would like to style the form fields so that when the results load, the datetime can be formated just to_date. I am unsure how to access the value used in the form. I could just use the value parameter and apply the styling, but I do not know the variable to use.
<%= f.text_field :order_date_lt, class: "", id: "datepicker1", value: ?????.to_date.strftime('%m-%d-%Y') %>
I found out that in this case #q.order_date_lt, if it is present, will be able to be formatted that way
Experimenting with my Rails form, I find that inserting <scrip>alert("hello")</script> into a text_field gives me two different results.
When I use the value, for example in a display page, it is automagicaly escaped.
When I use the value in a new form, for example to allow user editing, it is not escaped and I get the alert pop-up.
After a lot of research, I have found that text_area has an escape boolean that prevents this, but not text_field. Most of the stuff coming up on google is about escaping within erb templates, which does not appear to work when using a form. There are a couple of hints that data should be sanitized going into the db, but little guidance on the best way to do this --- aside from using old solutions for example xssterminate which appears to date back to Rails 2. Even the RoR security guide focuses on sanitizing erb output rather than santizing the input.
Two questions.
What is the current best-practice approach to sanitizing text_field input before it is saved? (eg: in the form, the controller or the model. What gems are still considered current?)
Regardless, because I am paranoid, how do you sanitize the text_field when displaying db data?
The loofah-activerecord gem (https://github.com/flavorjones/loofah-activerecord) looks like your best bet for sanitizing data on its way into the database. Using xss_foliate on your models will strip tags for all columns by default.
e.g.
class User < ActiveRecord::Base
xss_foliate
...
end
I haven't found a solution to the 2nd point, but would be very keen to know about it if there is one!
I'm working on an RoR project with the Simple_Form gem. For those who don't know, simple form creates easier form helpers for use in views. My question is regarding the f.association helper which allows users to easily select associations on models via a select box, radio buttons or checkboxes.
f.association has an option called value_method which allows you to pass a method for generating the name of the individual models in the association to choose from. The default is just to_s, so it will work with select boxes. However, I'm using radio buttons, and I'd like to know if anyone knows of a way to use the render partial method as the value_method.
In my setup, I have a User model with a user.haml partial that I'd like to be rendered next to each checkbox, that way users selecting other users can have any easy to recognize user div with picture, name, and last login to choose.
Thanks, steakchaser answered my question with his comment. This is the solution:
f.association :some_association, label_method: lambda { |obj| render obj }
I realized label method is better than value method, because even with checkboxes and radio buttons, simple form still put the values in the options value="..." attribute. This caused an html rendering error.
I'm looking to create an ancestry type webpage with a date field that allows user to enter a date going back to thee digits. This makes date_select with dropdown boxes and the jquery datepicker very un-user friendly.
Does anyone know a good way to display a text box for the year but a dropdown for month and day?
I'm hoping to use the "intelligence" of date_select while still allowing the user to enter the year in a more user friendly fashion (the textbox).
Thanks for any help you can give me!
With great respect to the developers of Rails, the date_select usability is pretty weak for almost any case :-)
Unlike other field types, the date_select helper generates three select tags with special names and ids, one each for the year, month, and day elements. It's the naming convention that allows controller code to auto-magically re-assemble the inputs into a (single) date when it is processing the params array.
Sorry, I don't have a handy example of the naming format (since I never use date_select), but if you look at the names of the fields, you might be able to mimic the behavior without too much hackery by using the :discard_year option. That gets you the month and day fields, and a hidden field (I think) containing the current year.
If you're not averse to a little JS or CoffeeScript, you could modify the input field after the DOM is loaded, by removing the hidden "type" attribute (thus making it a simple text field) and setting its value to be empty.
I would choose between three options
1-Use a date_select only for day and month and a text field with some javascript for the year
Date_select accepts a :discard_year option, if you set it to true, the year field is rendered as a hidden_field so there's no select/dropdown http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-date_select
Then you put a text_field and bind to the keyUp event and modify the value of the hidden year field
The most important problem about this is that, if the user has javascript disabled, the value of the text field will never be set to the hidden field and that's a problem.
2-Use a date_select only for day and month and a text field
I'm not sure if you can do this option, you can try using the same date_select as above and set the name of the input field with the name of the year field. The problem is that date_select will put a hidden field with that name and you put another field with the same name and the value sent on submission may not be what you want... You should see if it's posible.
3-Use a date_select and add extra functionality using Choosen http://harvesthq.github.com/chosen/
Put the date_select as always and set the start_year and end_year that you want, then replace the selects with choosen selects, the choosen select includes a text field to search between the years of the select
Choosen gives you a nice and consistence look almost crossbrowser (didn't test it on old IE versions), you get the text input for user-friendliness and, if javascript is disabled, the user still have the three selects.
I would definitelly use number 3, but maybe you don't want to add a plugin.
Experimenting with the Javascript route suggested by Tom, I came up with something like the following:
<%= f.date_select :birth_date %>
<script>
var date_field =
document.getElementsByName('ancestor[birth_date(1i)]')[0];
var new_html = '<%=
f.text_field 'birth_date(1i)', :value=>(f.object.birth_date.strftime("%Y") rescue "") %>';
date_field.outerHTML = new_html;
</script>
(Improvements welcome)