Rails select - default selected value error - ruby-on-rails

I am trying to set the selected attribute for select but it does not seem to be working
<%= f.fields_for :age_range, OpenStruct.new(#campaign.age_range) do |d| %>
<div class="form-group">
<%= d.label :min, "Age Range", :class => 'col-sm-2 control-label' %>
<div class="col-sm-2">
<%= d.text_field :min, :class => 'form-control' %>
<%= d.select :min, options_for_select(13..90), { include_blank: "Min Age", selected: '23' }, { class: 'form-control'} %>
</div>
<div class="col-sm-2">
<%= d.text_field :max, :class => 'form-control' %>
<%= d.select :max, options_for_select(13..90), { include_blank: "Max Age", selected: '23' }, { class: 'form-control'} %>
</div>
</div>
<div class="line line-dashed b-b line-lg pull-in"></div>
<% end %>
Even by forcing the value i am not able to get it selected
Updated from the Answers
<%= d.select :min, options_for_select((13..90), #campaign.age_range[:min]), { include_blank: "Min Age" }, { class: 'form-control'} %>
But am not able to access the hash value of min to the selected value
#campaign[:age_range] is a hash in the database

You can supply it as a second argument to the helper method options_for_select, for example:
# Static number
options_for_select(13..90, 13)
# or retrieved somehow from form object
options_for_select(13..90, d.object.min)

Related

New search form partial is redirecting to my main index page for the model

I have an events model and I have an address field where I have some geolocation logic being implemented. On my main index page, I'm rendering a search form partial that works just fine to be all to search all of the events in my database.
Here's the original search form:
<%= search_form_for #q,
data: { controller: "places", action: "google-maps-callback#window->places#initMap" } do |f| %>
<div class="formlook">
<div class="event-search-container">
<div class="event-name">
<%= f.label "Event name", class: "form-label" %>
<%= f.search_field :name_cont, placeholder: "Any event", class: "form-control" %>
</div>
<div class="geolocation">
<%= f.label "Geolocation", class: "form-label" %>
<%= f.search_field :address_or_city_or_state_or_country_or_continent_cont_all, class: "form-control", placeholder: "Search by continent, country, state, or city", data: { places_target: "field" } %>
</div>
<div class="dancestyle">
<%= f.label "Dance style", class: "form-label" %>
<%= f.select(:dance_styles_id_in, DanceStyle.all.pluck(:name, :id), { :include_blank => "All dance styles" }, { class: "form-select", id: "select-dancestyle", multiple: true, placeholder: "Any dance style" }) %>
</div>
<div class="eventtype">
<%= f.label "Event Type", class: "form-label" %>
<%= f.select :event_type_id_in, EventType.all.pluck(:name, :id), { :include_blank => "All event types" }, { id: "select-artist", multiple: true, placeholder: "Any event type", class: "form-select" } %>
</div>
<div class="month">
<%= f.label "Month", class: "form-label" %>
<%= f.select(:event_month_in, (Date::MONTHNAMES[1..12]), { prompt: "Any month" }, { id: "select-month", :include_blank => "Any month", class: "form-select", multiple: true }) %>
</div>
<div class="year">
<%= f.label "Year", class: "form-label" %>
<%= f.select :event_year_in, Date.today.year-2 .. Date.today.year+3, { prompt: "Any year" }, { id: "select-year", include_blank: true, class: "form-select", multiple: true } %>
<br>
</div>
</div>
</div>
<%= f.submit "Search!", class: "button-orange" %>
<% end %>
I'm now creating specific event index pages for particular cities now. So I want to be able to use the other search parameters from my main index page without the name or the address field. So I created a new html erb file with a new scope based off the event model for a particular city:
<div class="container index">
<div>
<h1>Dance Events in Austin, Texas!</h1>
<br>
<div class="help-attn">
<p>All of the search options work together! Create your own search filters to find the events you want!</p>
</div>
<%= render 'events/local_search_form' %>
<br>
<h5>Currently displaying <%= pluralize(#events.in_austin.count, "event") %>. </h5>
<br>
</div>
<h3>Upcoming Events</h3>
<div class="event-list-wrapper">
<% #events.upcoming_events.in_austin.each do |event| %>
<%= render 'event', event: event %>
<% end %>
</div>
<h3>Past Events</h3>
<div class="event-list-wrapper past-event">
<% #events.past_events.in_austin.each do |event| %>
<%= render 'event', event: event %>
<% end %>
</div>
I also needed to add the def atx_index to my event model with the same parameters as the def index since in my head they are both index pages, just one has a different scope.
From above you will see that I created a different search form partial to reflect the two fields I don't need anymore, here's the new search form partial.
<%= search_form_for #q do |f| %>
<div class="formlook">
<div class="local-search-container">
z <%= f.hidden_field :address_or_city_or_state_or_country_or_continent_cont_all, value: [""] %>
<div class="dancestyle">
<%= f.label "Dance style", class: "form-label" %>
<%= f.select(:dance_styles_id_in, DanceStyle.all.pluck(:name, :id), { :include_blank => "All dance styles" }, { class: "form-select", id: "select-dancestyle", multiple: true, placeholder: "Any dance style" }) %>
</div>
<div class="eventtype">
<%= f.label "Event Type", class: "form-label" %>
<%= f.select :event_type_id_in, EventType.all.pluck(:name, :id), { :include_blank => "All event types" }, { id: "select-artist", multiple: true, placeholder: "Any event type", class: "form-select" } %>
</div>
<div class="month">
<%= f.label "Month", class: "form-label" %>
<%= f.select(:event_month_in, (Date::MONTHNAMES[1..12]), { prompt: "Any month" }, { id: "select-month", :include_blank => "Any month", class: "form-select", multiple: true }) %>
</div>
<div class="year">
<%= f.label "Year", class: "form-label" %>
<%= f.select :event_year_in, Date.today.year-2 .. Date.today.year+3, { prompt: "Any year" }, { id: "select-year", include_blank: true, class: "form-select", multiple: true } %>
<br>
</div>
</div>
</div>
<%= f.submit "Search!", class: "button-orange" %>
<% end %>
So the specific city event index page is displaying properly following the scope but when I use the search I'm redirected to the main event index page with the search parameters that I inputted. I'm not understanding how the two different search form partials are both linked to the main event index page.
How do I get the new search form partial for the specific city index page to display the search results on its corresponding page?
The issue to my redirect form issue was that I need to set the URL of the new form I created, so I was able to get the proper path names from the routes.
My initial implementation though had my configuring the form specifically and since I wanted to reuse the form on multiple pages for the individual local cities, I was lucky to find an old 7 year old SOF article that referred to setting the url in the render line like this:
<%= render 'events/local_search_form', { url: atx_index_path } %>
and then calling that url string in the local_search_form like so:
<% if local_assigns.has_key? :url %>
<%= search_form_for #q, { url: url } do |f| %>
and now I can simply change the url path for each html.erb file I create for each individual city! I didn’t know about the local assigns!

Setting the end_time value the same as start_time value in a rails form

Rails 6.0.3
I am using a form to schedule meetings.
It is being used for both single time meetings that span over several days (with start_time and end_time) and tasks that last only one day.
For singular day meetings, I need the end_time to be set to the same value as start_time, without user selecting it.
I have tried many things in the controller, but can't work it out.
How would you go about this.
Thanks for the help
<div class="border border-grey-light rounded" style ="padding: 10px;">
<%= form_with(model: meeting, local: true, :html => {:id => "flatpickr-form-single"} ) do |form| %>
<div class="mb-6">
<%= form.label :name, class: 'label' %>
<%= form.text_field :name, required: true, class: 'form-control', placeholder: "Task name" %>
</div>
<div class="mb-6">
<%= form.label :body %>
<%= form.rich_text_area :body, class: 'form-control' %>
</div>
<div class="start_time_result mb-6" style ="width: 30vw;">
<%= form.label :start_time, class: 'label' %>
<div class="flex items-center justify-between max-w-md">
<%= form.text_field :start_time, data: { behavior: "flatpickr" }, placeholder: "Date and time select ...", class: "form-control" %>
</div>
</div>
<div class=" field" style ="width: 30vw;">
<%= form.label :end_time, class: 'label' %>
<div class="end_time_result flex items-center justify-between max-w-md" >
<%= form.text_field :end_time, data: { behavior: "flatpickr" }, placeholder: "Date and time select ...", class: "form-control required" %>
</div>
</div>
<%= form.submit class: "btn btn-primary text-base py-1.5 px-5", value: "Confirm" %>
<% end %>
</div>
<script>
const selectElement = document.querySelector('.start_time_result');
selectElement.addEventListener('change', (event) => {
const end_time_result = document.querySelector('.end_time_result');
end_time_result.textContent = `${event.target.value}`;
});
</script>
You can add a before_action in the controller and set the end_time parameter value to the same as the start_time from there.

Dropdown select menu reset to default option selection after form submit

When I click the submit button it does filter the selections according to the selected brand but the dropdown option reset to the first option
`
**<%= form_tag(products_path, :method => "get",
class: 'navbar-form navbar-left') do %>
<div class="input-group">
<%= search_field_tag :search, params[:search], placeholder: "Search", class: "form-control" %>
<div class="input-group-btn">
<%= button_tag "search", :class => 'btn btn-info glyphicon glyphicon-search',:name => nil%>
</div>
<div class="field">
<%= search_field_tag :min, params[:min], placeholder: "min", class: "form-control" %>
</div>
<div class="field">
<%= search_field_tag :max, params[:max], placeholder: "max", class: "form-control" %>
</div>
<% brands_array = Brand.all.map { |brand| [brand.name, brand.id] } %>
<%= select_tag :brand_id, options_for_select(brands_array) %>
</div>
<% end %>**
`

How do you pass values of select input using simple form gem?

Form is submitting the values as nil, although I selected a value.
<%= simple_form_for #offer do |f| %>
<div class="form-group">
<%= f.label :days_per_turn, "Days Per Turn" %>
<%= f.select :days_per_turn, [ 1, 2, 3, 5, 7, 10, 14 ], selected: '1' %>
<%= f.label :play_as, "I Play As" %>
<%= f.select :play_as, [ 'Random', 'White', 'Black' ], selected: 'Random' %>
<%= f.label :rated, "Rated" %>
<%= f.select :rated, [ 'Yes', 'No', 'Takeback' ], selected: 'No' %>
</div>
<div class="actions">
<%= f.submit "Submit", :class => 'btn btn-primary' %>
</div>
You'll do better to use the simple_form syntax:
<%= simple_form_for #offer do |f| %>
<div class="form-group">
<%= f.label :days_per_turn, "Days Per Turn" %>
<%= f.input :days_per_turn, collection: [[1,1],[2,2],[3,3],[5,5],[7,7],[10,10],[14,14]], selected: 1 %>
<%= f.label :play_as, "I Play As" %>
<%= f.input :play_as, collection: [['Random', :random], ['White', :white], ['Black', :black]], selected: :random %>
<%= f.label :rated, "Rated" %>
<%= f.input :rated, collection: [['Yes', :yes],['No', :no], ['Takeback', :takeback]], selected: :no %>
</div>
<div class="actions">
<%= f.submit "Submit", :class => 'btn btn-primary' %>
</div>
<% end %>

How do I fix this form the Rails way?

I want to have all the errors appear on top of their respective areas.
I ran an if statement with any? on the first one but I know I am repeating myself and have to do it the Rails way.
Any help?
<%= form_for #movie, :html => {:class => "form-horizontal"} do |f| %>
<div class="control-group">
<% if #movie.errors[:title].any? %>
<div class="alert alert-error"><%= #movie.errors[:title].to_sentence %></div>
<% end %>
<%= f.label :title, :class => "control-label" %>
<div class="controls">
<%= f.text_field :title %>
</div>
</div>
<div class="control-group">
<div class="alert alert-error"><%= #movie.errors[:description].to_sentence %></div>
<%= f.label :description,:class => "control-label" %>
<div class="controls">
<%= f.text_area :description, :class => "span8", :rows => "10" %>
</div>
</div>
<div class="control-group">
<div class="alert alert-error"><%= #movie.errors[:rating].to_sentence %></div>
<%= f.label :rating, :class => "control-label" %>
<div class="controls">
<%= f.select :rating, Movie::RATINGS, prompt: "Pick one" %>
</div>
</div>
<div class="control-group">
<div class="alert alert-error"><%= #movie.errors[:total_gross].to_sentence %></div>
<%= f.label :total_gross, :class => "control-label" %>
<div class="controls">
<%= f.number_field :total_gross %>
</div>
</div>
<div class="control-group">
<div class="alert alert-error"><%= #movie.errors[:released_on].to_sentence %></div>
<%= f.label :released_on, :class => "control-label" %>
<div class="controls">
<%= f.date_select :released_on, :order => [:month, :day, :year], :prompt => { :month => 'Select month',:day => 'Select day', :year => 'Select year' }, :start_year => 1950 %>
</div>
</div>
<div class="control-group" >
<%= f.label :image_file_name, :class => "control-label" %>
<div class="controls">
<%= f.text_field :image_file_name %>
</div>
</div>
<div class="form-actions">
<%= f.submit :class => "btn btn-success btn-large" %> <%= link_to "Cancel", root_path, class: "btn btn-danger btn-large" %>
</div>
<% end %>
Here's a solution that will be more DRY and won't necessitate gems like simple_form.
Create a partial for your control group and replace the field name and form field helper with variables:
# File: _control_group.html.erb
<% show_errors = true if show_errors.nil? %>
<div class="control-group">
<% if #movie.errors[field_name].present? && show_errors %>
<div class="alert alert-error">
<%= #movie.errors[field_name].to_sentence %>
</div>
<% end %>
<%= label_tag field_name, :class => "control-label" %>
<div class="controls">
field_helper
</div>
</div>
Then replace these items in your form with a partial render and pass the appropriate code in through the parameters:
<%= form_for #movie, :html => {:class => "form-horizontal"} do |f| %>
<%= render "control_group", field_name: :title, field_helper: f.text_field(:title) %>
<%= render "control_group", field_name: :description, field_helper: f.text_area(:description, :class => "span8", :rows => "10") %>
<%= render "control_group", field_name: :rating, field_helper: f.select(:rating, Movie::RATINGS, prompt: "Pick one") %>
<%= render "control_group", field_name: :total_gross, field_helper: f.number_field(:total_gross) %>
<%= render "control_group", field_name: :released_on, field_helper: f.date_select(:released_on, :order => [:month, :day, :year], :prompt => { :month => 'Select month',:day => 'Select day', :year => 'Select year' }, :start_year => 1950) %>
<%= render "control_group", field_name: :image_file_name, field_helper: f.text_field(:image_file_name), show_errors: false %>
<div class="form-actions">
<%= f.submit :class => "btn btn-success btn-large" %> <%= link_to "Cancel", root_path, class: "btn btn-danger btn-large" %>
</div>
<% end %>
Ran into a similar problem.
Using simple_form worked for me. See an example here

Resources