I'm having a problem with one of my variables.
I have 2 variables, :starts_on and :ends_on . Both are of type DateTime. :starts_on gets assigned a date and a time in the form, however :ends_on only gets assigned time from the form. Unfortunately, the date part becomes "2000-01-01", which is not right. I would like to assign date from :starts_on variable, then user can change time part in the form. So far it doesn't work. My code:
in app/views/courses/_form.html.erb
<%= form_for #course do |f| %>
<%= f.label :starts_on, "Date:" %>
<%= f.date_select :starts_on %>
<%= f.label :starts_on, "Time:" %>
<%= f.time_select :starts_on, :ignore_date => true %>
<%= f.time_select :ends_on, :ignore_date => true %>
<%= f.submit "Submit" %>
<% end %>
in app/controllers/courses_controller.rb (I'm only showing edit action, but new is the same idea)
def edit
#course = Course.find(params[:id])
#course.ends_on = #course.starts_on
end
So, I attempted putting the code there to make ends_on equal starts_on and then in the form the user would change the time part of it. However this doesn't work and the date ends up being "2000-01-01" for all of them (time part is correct). If I look up the value of ends_on in the form - it is correct, but doesn't save correctly. Please help?
Edit / Solution:
I figured it out.
I tried changing in controller's update action - didn't work. I tried making hidden date_select and in the end what worked was:
<div style="display: none;">
<%= f.date_select :ends_on %>
</div>
This is quite frustrating that THAT is the only thing that works. It appears that there MUST be <%= f.date_select :ends_on %> in order for it to add a date to the god damn variable. You can't even go without = (the equal sign). Very frustrating.
Thank you for comments and answers, it was all helpful.
I feel that this problem could have better solutions, so this question might be useful in the future to others.
Have you tried adding a hidden <%= f.date_select :ends_on %>? I'm assuming you are only concerned with preventing the user from having to select the same date, so you can have this tag in the form but hide it with css in the html_options hash.
Related
I have a form in Rails which uses fields_for to accept nested attributes:
<%= form_with(model: #combat_tracker, url: form_url) do |f| %>
…
<%= f.fields_for :zones do |zone| %>
<div class="zone-field">
<%= zone.text_field :name %>
<%= zone.check_box :_destroy %>
<%= zone.label :_destroy, "Remove zone" %>
</div>
<% end %>
…
<% end %>
Currently this gives me input fields for any existing zones on #combat_tracker. I want to add a button that will dynamically add a new zone-fields div for a new zone to be added when the form is submitted.
I’m using Rails 7 and assume the solution will involve the use of Turbo or possibly Stimulus, but can’t quite figure out the best way to do this. Thanks.
I don't think you need Turbo or Stimulus. Take a look at cocoon gem, it should do exactly what you're looking for.
Explaining all process here is quite complex for me, but try to follow this guide if the gem's one is too long.
Noob question! :)
I have a form, that has basically no point other than call some_action. The reason I use a form for this, is because we have a specific styling for this in our large website.
<%= styled_form_for(#user, :url => some_action_user_path #user)) do |f| %>
<%= f.save_button %>
<% end %>
I thought, since it's a form, I should be able to put a checkbox in there. It should have no other goal than confirming the user wants to do this action indeed. E.g. "Yes, I want to do some_action to the user model".
How would I make a checkbox that does not really change any attribute or affect anything - Other than that it should be checked for the form to submit?
This is probably dead simple, but according to the documentation and various error messages I should provide arguments such an attribute (which I don't want...)
form_for is meant to work on attributes of a model, which is what all the documentation you are reading is telling you. So if your model had a boolean column you could easily attach a check box to it.
If you ever want a form (or specific tag) that does not follow this, you can use the _tag version of these methods. For example, form_tag or, in your particular case, check_box_tag.
Example:
<%= styled_form_for(#user, :url => some_action_user_path #user)) do |f| %>
<%= check_box_tag "do_some_method" %>
<%= f.save_button %>
<% end %>
NOTE: You will only get a param entry for :do_some_method if it is checked off. If you want to get a param regardless, you have to add a hidden_field_tag before it.
<%= hidden_field_tag "do_some_method", "no_dont_do_it" %>
<%= check_box_tag "do_some_method", "yes_do_it" %>
Now if the checkbox is selected you'll get params[:do_some_method] set to "yes_do_it"; if it's not checked off, instead of getting no entry, you'll get params[:do_some_method] set to "no_dont_do_it".
I have an archive page that I want the user to be able to select a date and pull up microposts created on that date. I think I am close to figuring it out, I just cannot figure out how to set an instance variable with a date_select form. I have a method in my controller that looks something like this:
def archive
#date_search = []
end
I want to set the instance variable to an empty set for now so that it can be assigned later. My partial for the feed looks like this:
<ol class="microposts">
<%= render partial: 'shared/feed_item', collection:Micropost.where("DATE(created_at) = ?", #date_search) %>
</ol>
I can assign #date_search a value in the controller and it will show posts from that date so that seems to work. Now I just need to be able to set the variable with the form. My date form looks something like this:
<%= form_for(#date_search) do |f| %>
<div class="field">
<%= f.select_date Date.today, :prefix => :date_search %>
</div>
<%= f.submit "Submit", class: "btn btn-lrg btn-primary" %>
<% end %>
but I doesn't work. Maybe I am using the wrong kind of select date form because if I don't put the f in front of select_date in the block the forms show up in the view but nothing happens when I submit it. When I put f.select_date I get this error
undefined method 'select_date' for #<ActionView::Helpers::FormBuilder:0x0000010170f3d0>
Does anyone have any ideas?
Thanks for the help.
I've used form_tag in the view and the datepicker gem in a text field tag to create a live update in a form.
e.g.
<%= form_tag the_controller_path, method: :get do %>
<%= submit_tag("date update") %>
<%= label_tag(:q, "Selected Date") %>
<%= text_field_tag :q, #date_search, :class => 'datepicker' %>
That gets the user input.
#date_search here is what will displayed in the text box when the date is updated.
You then use params[:q] in the method to use the selected date in the controller.
e.g. in the controller:
def archive
#date_search = params[:q]
end
Maybe something like this would work for you?
From documentation select_date does not appear in ActionView::Helpers::FormBuilder, so I would try it without f. Also, they use it with a date object:
my_date = Time.now + 6.days
# Generates a date select that defaults to the date in my_date (six days after today).
select_date(my_date)
I am not sure about this though.
Or maybe you want date_select.
This isn't working as I'd like.
I have an entry form for a new job, which is made up of a number of steps. By default there are 4 new and unsaved steps populated per job.
Using the code from the view below, I am able to attach the jQuery UI datepicker control to the text fields and they appear against the correct input field when i click them.
However, when I select a date from the picker it is only ever going into the field representing the start date of the first step.
<%= form_for #job, :url => jobs_path do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<% #job.steps.each do |step| %>
<%= fields_for "job[step_attributes][]", step do |s| %>
<%= s.label :name %>
<%= s.text_field :name %>
<%= s.label :start_date %>
<%= s.text_field :start_date, :class => :datepicker %>
<%= end %>
<% end %>
<script type="text/javascript">
$(function() {
$('.datepicker').datepicker({ dateFormat: "dd/mm/yy"});
});
</script>
I know ultimately this has to do with the generated id attribute for the input elements being the same, was wondering, has anybody successfully overcome this issue?
This fiddle: http://jsfiddle.net/twilson/u9m9L/ demonstrates my problem.
First, invoke fields_for on your form builder instead:
<%= f.fields_for :steps do |s| %>
Second, you don't need to iterate through #job.steps if you specify the association name to fields_for. There's an example on how to use it with one-to-many assoiciations here.
If you still have this problem, paste your generated HTML, it would easier to find the cause.
EDIT
OK so the problem is because Rails form builder does not generate child indexes to give unique IDs to nested fieldsets. This most likely happened because the associations are built but not yet saved to the DB. One way I see is to assign child indexes manually, like so:
<% #job.steps.each_with_index do |step,i| %>
<%= f.fields_for :steps, step, :child_index => i do |s| %>
See if that helps.
This is a somewhat contrived scenario given that you have only new objects. To be able to dynamically add/remove nested items, this would be a bit trickier. You can see how this can be dealt with in the nested model Railscasts.
In the application there is a default report the user see's listing all the calls for a certain phone. However, the user can select a date range to sort the list from. Doing that, everything works correctly, but when the user selects the date range and changes to the second page, the date-range is lost and it goes back to the default view for the second page.
In my controller, I'm checking to see if the date_range param is being passed in. If it isn't, I display the entire listing, if it is, I display the records in between the certain date range.
The problem is, when I click on a new page, the new parameter doesn't include the old date-range that it should.
How do I go about doing this, I was thinking of doing some class level variable test but that isn't working out the way I thought. And I'm pretty stuck.
I don't have the code right in front of me, but if I remember correctly it's something like this:
<% form for :date_range do |f| %>
<%= f.calendar_date_select :start %>
<%= f.calendar_date_select :end %>
<%= f.Submit %>
<% end %>
And in the controller, it's something like:
if params[:date_range] == nil
find the complete listings without a date range
else
find the listings that are within the date range
end
The main problem is that you're using a POST request when submitting the form, but will-paginate uses a GET request. You should also use form_tag instead of form_for because form_for will nest the fields in a hash which is not possible with GET.
<% form_tag items_path, :method => 'get' do %>
<%= calendar_date_select_tag :start_date %>
<%= calendar_date_select_tag :end_date %>
<%= submit_tag "Submit", :name => nil %>
<% end %>
Then check params[:start_date] and params[:end_date] directly. You'll need to change items_path to whatever page you want the form to go to.
This is untested but it should get you in the right direction.
You could modify the link_to (assuming that's how you go through pages) so that it passed the date_range param.
= link_to 'Next', #whatever_path, :date_range => #date_range
where #date_range could be set in your controller by capturing your params in an instance variable.. .
But there may be a better solution.