Displaying different divs based on dropdown selection in Rails form - ruby-on-rails

I am trying to create a form in Rails that includes a dropdown menu with three options: 'foo', 'bar', and 'baz'. If the user selects one of these options, I want to display a different div based on the selected option.
Here is my code:
<% options = [['Foo', 'foo'], ['Bar', 'bar'], ['Baz', 'baz']] %>
<%= form.label :type %>
<%= form.select :type, options_for_select(options, #selected_type), name: 'type' %>
<% if #selected_type == 'foo' %>
<div>
<%= form.hidden_field :type, value:'foo' %>
</div>
<% elsif #selected_type == 'bar' %>
<div>
<%= form.hidden_field :type, value:'bar' %>
</div>
<% elsif #selected_type == 'baz' %>
<div>
<%= form.hidden_field :type, value:'baz' %>
</div>
<% end %>
This is in my controller:
#vendor_item = VendorItem.new
#selected_type = params[:type]
puts "Selected type: #{#selected_type}"
I have implemented this using a select element, but the form is not working as expected. When I select an option from the dropdown menu, the form is not being submitted, and the divs are not being displayed.

CASE 1: If the form should be submitted on the server side, after the dropdown change:
<% options = [['Foo', 'foo'], ['Bar', 'bar'], ['Baz', 'baz']] %>
<%= form_with url: "your URL goes here", class: 'test_submit_form' do |form| %>
<%= form.label :type %>
<%= form.select :type, options_for_select(options, #selected_type), name: 'type' %>
<% if #selected_type == 'foo' %>
<div>
<%= form.hidden_field :type, value:'foo' %>
</div>
<% elsif #selected_type == 'bar' %>
<div>
<%= form.hidden_field :type, value:'bar' %>
</div>
<% elsif #selected_type == 'baz' %>
<div>
<%= form.hidden_field :type, value:'baz' %>
</div>
<% end %>
<%= form.submit %>
<% end %>
Javascript:
<script>
$('#type').on('change', function(){
$('form.test_submit_form').submit();
});
</script>
CASE 2: If you just need to show/hide DIVs on client side, after dropdown change:
<% options = [['Foo', 'foo'], ['Bar', 'bar'], ['Baz', 'baz']] %>
<%= form_with url: "your URL goes here", class: 'test_submit_form' do |form| %>
<%= form.label :type %>
<%= form.select :type, options_for_select(options, #selected_type), name: 'type' %>
<div class="option-container foo" style="display: <%= #selected_type == 'foo' ? 'block' : 'none'%>">
<%= form.hidden_field :type, value:'foo' %>
</div>
<div class="option-container bar" style="display: <%= #selected_type == 'bar' ? 'block' : 'none'%>">
<%= form.hidden_field :type, value:'bar' %>
</div>
<div class="option-container baz" style="display: <%= #selected_type == 'baz' ? 'block' : 'none'%>">
<%= form.hidden_field :type, value:'baz' %>
</div>
<%= form.submit %>
<% end %>
Javascript:
<script>
$('#type').on('change', function(){
$('.option-container').hide();
$('.option-container.' + $(this).val()).show();
});
</script>
Notice the option-container and option (foo, bar, baz) class on div and controller code will remain the same for both cases:
#selected_type = params[:type]

Related

Date not saving within parameters of model

within my view form, I currently have this code:
<div class="panel panel-default">
<div class= "panel-body">
<%= form_for #meal_plan, url: new_meal_plan_path, method: "GET", html: { class: "form-inline" } do |form| %>
<div class="form_group">
<%= form.label :start_date %>
<%= form.text_field :start_date, type: "date", class: "form-control" %>
</div>
<div class="form_group">
<%= form.label :end_date %>
<%= form.text_field :end_date, type: "date", class: "form-control" %>
</div>
<div class="form-group action">
<%= form.submit "Generate Plan", class: "btn btn-default"%>
</div>
<% end %>
</div>
</div>
That takes a start date and an end date input for a meal plan. In the new method within the meal_plan_controller, I have:
def new
puts params[:start_date]
puts params[:end_date]
#meal_plan = current_user.meal_plans.build(
start_date: params[:start_date] || Date.today,
end_date: params[:end_date] || 6.days.from_now.to_date,
)
#meal_plan.build_meals
end
In the puts statements that I wrote to debug, :start_date and :end_date contains only the default dates, so my guess is that the dates are not saving when the user hits submit, but I can't figure out why.

Rails - Search results are not filtered. Returning all availability

The task scope: A user selects an option from a drop down menu (Single/Double bedroom), clicks on search button and gets all related results. Then on the search page the user can further refine results by using available filters (TV/Shower). For some reason none of these actions modify the search results- the page displays all available listings in the database, rather than the ones that match the criteria..
What am I doing wrong?
Here is what I have so far:
HOME SEARCH BAR
<%= form_tag search_path, method: :get do %>
<div class="row">
<div class="col-md-7">
<%= select_tag :bedroom, options_for_select([['Single', 1], ['Double', 2]]), class: "form-control" %>
</div>
<div class="col-md-2">
<%= submit_tag "Search", class: "btn btn-normal btn-block" %>
</div>
</div>
<% end %>
SEARCH PAGE
<div class="col-sm-3">
<%= search_form_for #search, url: search_path, remote: true do |f| %>
<div class="row">
<div>
<%= check_box_tag "q[is_tv_eq]", true %> TV
</div>
<div>
<%= check_box_tag "q[is_shower_eq]", true %> Shower
</div>
</div>
<div class="row text-center">
<%= f.submit "Search", class: "btn btn-form" %>
</div>
<% end %>
<%= render partial: "rooms/rooms_list", locals: {rooms: #arrRooms} %>
</div>
ROOM LIST PARTIAL
<% rooms.each do |room| %>
<div class="row">
<%= image_tag room.cover_photo(:medium) %>
<%= link_to room.user_id, room %>
<%= room.price %> - <%= room.bedroom %>
<div id="star_<%= room.id %>"></div> <%= pluralize(room.average_rating, "review") %>
</div>
<script>
$('#star_<%= room.id %>').raty({
path: '/assets',
readOnly: true,
score: <%= room.average_rating %>
});
</script>
<% end %>
ROOM MODULE
class CreateRooms < ActiveRecord::Migration[5.0]
def change
create_table :rooms do |t|
t.string :bedroom
t.integer :price
t.boolean :active
t.timestamps
end
end
end
PAGE CONTROLLER
def search
# STEP 1
if params[:search].present? && params[:search].strip != ""
session[:loc_search] = params[:search]
end
# STEP 2
if session[:loc_search] && session[:loc_search] != ""
#rooms_bedroom = Room.where(active: true, bedroom: session[:loc_search]).order(:price)
else
#rooms_bedroom = Room.where(active: true).all
end
# STEP 3
#search = #rooms_bedroom.ransack(params[:q])
#rooms = #search.result
#arRoooms = #rooms.to_a
end
DEFINED THE BEDROOM OPTIONS IN THE ROOM OVERVIEW PAGE (not sure if that helps)
<%= form_for #room do |f| %>
<div class="form-group">
<label> Bedroom Type </label>
<%= f.select :bedroom, [["Single", "Single"], ["Double", "Double"]],
id: "bedroom", prompt: "Select...", class: "form-control" %>
</div>
</div>
<div><%= f.submit "Save", class: "btn btn-normal" %></div>
<% end %>
Thanks

Rails: Show or Hide elements based on DropDown selection using IF

Using an IF Statement, How can I hide/show an element based on the value in the drop-down selection (transactionType)
Here's something I've been trying
Where did I go wrong?
<%= form_for(transaction) do |f| %>
<div class="field">
<%= f.label :transactionType %>
<%= f.select :transactionType, ['Income', 'Expense']%>
</div>
<%= if transaction.transactionType == 'Income' %>
<div class="field">
<%= f.label :amount %>
<%= f.number_field :amount, options = { max: 0 }%>
</div>
<% else %>
<div class="field">
<%= f.label :amount %>
<%= f.number_field :amount, options = { min: 0 }%>
</div>
<% end %>
How about using css classes..if its all about hiding elements from view...
So if you are using bootstrap,you can use hidden class.check more here.
in below example,i have used ternary operator which is just like if else.
for example:-
<%= form_for(transaction) do |f| %>
<div class="field">
<%= f.label :transactionType %>
<%= f.select :transactionType, ['Income', 'Expense']%>
</div>
<!-- here comes ternary operator -->
<div class="field <%= transaction.transactionType == 'Income' ? 'present' : 'hidden' %>">
<%= f.label :amount %>
<%= f.number_field :amount, options = { max: 0 }%>
</div>
<div class="field <%= transaction.transactionType != 'Income' ? 'present' : 'hidden' %>"">
<%= f.label :amount %>
<%= f.number_field :amount, options = { min: 0 }%>
</div>
if not using bootstrap,you can create custom class to hide/show elements.
Haven't used erb in quite some time, but I think you need to change
<%= if transaction.transactionType == 'Income' %>
should be
<% if transaction.transactionType == 'Income' %>
But this is only for the initial state. After that you will need jquery to toggle according to your select element

Rails 4: passing custom data and form data in ajax call

I am trying to submit a simple form using ajax call this way
$('#save-artificial-form').click(function () {
var fd = $('#categories-form').serialize();
console.log(fd);
var url = "/categories";
$.ajax({
type: 'POST',
url: url,
data: $('#categories-form').serialize(),
success: function() {
return true;
}
});
It works perfectly fine and save form data. But I want to add one more data category_type but I don't know how to do this. I want something like this
data: $('#categories-form').serialize(), category_type: "advanced"
How can I do this? It is okay if category_type is added/pushed in the fd variable above.
code in my form
<%= form_for(#category, :html => {:id => "categories-form", class: "form-alt"}) do |f| %>
<% if #category.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#category.errors.count, "error") %> prohibited this category from being saved:</h2>
<ul>
<% #category.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :enabled %><br>
<%= f.check_box :enabled %>
</div>
<div style="margin: 6px 0px 0 0 !important;">
<%= link_to "This is test", 'javascript:void(0)', id: "save-artificial-form", :rel => "tooltip", :title => "save" %>
</div>
<% end %>
Option 1:
Use a hidden field and it will be added automatically to the serialized string
<%= f.hidden_field :category_type, value: 'advanced' %>
Option 2:
Concat the missing value to the serialized string ie. "param=value"+ "&missing_data=bar"
data: $('#categories-form').serialize() + '&category_type=advanced'

show rest of a form if a checkbox is ckecked in ruby on rails

I need to ask to my user if will pay a service with credit card...if it checked the option pay_with_card? it must show the rest of the form, that ask for other data like card number, mail, etc. if the user don't checked it, it must show a message, the question is...how can I do this? thanks in advance
<%= form_for(#product) do |f| %>
<%= f.label :pay_with_card? %>
<%= f.check_box :pay_with_card,{}, "Yes", "No"%>
<div>
<%= f.label :card_number %> <%= f.text_field :card_number %>
</div>
<div>
<%= f.label :mail %> <%= f.text_field :mail %>
</div>
<% end %>
Make the card number/mail details div style="display:none;", then add some javascript to the checkbox to change it to display:block;
Something like this:
<%= form_for(#product) do |f| %>
<%= f.label :pay_with_card? %>
<%= f.check_box :pay_with_card,{}, "Yes", "No"%>
<div id="card_details" style="display:none;">
<%= f.label :card_number %> <%= f.text_field :card_number %>
<%= f.label :mail %> <%= f.text_field :mail %>
</div>
<% end %>
<script type="text/javascript">
var checkbox = document.getElementById('product_pay_with_card');
var details_div = document.getElementById('card_details');
checkbox.onchange = function() {
if(this.checked) {
details_div.style['display'] = 'block';
} else {
details_div.style['display'] = 'none';
}
};
</script>
How about using jQuery?
First, wrap your credit card fields in a div with class credit_card_fields and than add this JS code to your page:
$("input[type='checkbox']#pay_with_card").on('change', function(){
$('.credit_card_fields').toggle();
});
You can use JS for it or move pay_with_card out of form like:
<%= link_to 'pay with card', your_current_path(:pay_with_card => 1) %>
<%= form_for(...) do |f| %>
<% if params[:pay_with_card] %>
<%= # fields for card %>
<% end %>
<% end %>
You can do it through jQuery, for example:
$ ->
$('select#pay_with_card').change ->
if $(this).val() == 'yes'
$('.card_block').slideDown('fast')
else
$('.card_block').slideUp('fast')
assumed that part of the form with payment card is included in the div with .card_block class
Ok my solution is this: all the code in the view, if a user check pay_with_card...(mi code is in spanish) it shows the complete form...if is not checked donĀ“t show nothing, just the same checkbox asking for payment... thanks guys.
function mostrar (){
var checkbox = document.getElementById('chk_tarjeta');
if (checkbox.checked)
document.getElementById("card_details").style.display = "block";
else
document.getElementById("card_details").style.display = "none";
</script>
<h1>Forma de Pago</h1>
<%= form_for(#product) do |f| %>
<div id="product_pay_with_card">
<div >
<%= f.label :paga_con_tarjeta? %></br>
<%= f.check_box :paga_con_tarjeta, :id => "chk_tarjeta", :onclick => "mostrar();" %>
<div>
</div>
</div>
<div id="card_details" >
<div>
<%= f.label :numero_de_tarjeta %></br>
<%= f.text_field :numerotarjeta %>
</div>
<div>
<%= f.label :codigo_de_seguridad %></br>
<%= f.text_field :codigoseguridad %>
</div>
This worked for me with a form_with model and bootstrap
Change my_hidden_form with an id that makes sense for your form.
Original code is haml
= form_with scope: :model, url: models_path, local: true do |form|
.row
.col-6
.form-group
%h5.mb0 THE CASE TO TICK
= form.check_box :form_value, {:data => {:aria => {controls: :my_hidden_form, expanded: false}, :toggle => "collapse", :type => "checkbox", :target => "#my_hidden_form" }}
.row
.col-6
.form-group.collapse#my_hidden_form
%h5.mb0 THE FORM TO SHOW WHEN CASE IS TICKED
= form.text_field :name, placeholder: "A name"
.row
.col-md-12.text-right
= form.submit 'Submit', class: "btn btn-primary"
Converted to erb/html with https://haml2erb.org/
<%= form_with scope: :model, url: models_path, local: true do |form| %>
<div class="row">
<div class="col-6">
<div class="form-group">
<h5 class="mb0">THE CASE TO TICK
<%= form.check_box :form_value, {:data => {:aria => {controls: :my_hidden_form, expanded: false}, :toggle => "collapse", :type => "checkbox", :target => "#my_hidden_form" }} %>
</h5>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="form-group collapse" id="my_hidden_form">
<h5 class="mb0">THE FORM TO SHOW WHEN CASE IS TICKED
<%= form.text_field :name, placeholder: "A name" %>
</h5>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 text-right">
<%= form.submit 'Submit', class: "btn btn-primary" %>
</div>
</div>
<% end %>
Since the approach suggested by #Unixmonkey didn't work for me, here's a slight variation I put together using an event listener.
<script type="text/javascript">
const checkbox = document.getElementById('product_pay_with_card');
const details_div = document.getElementById('card_details');
checkbox.addEventListener("change", (event) => {
if (event.currentTarget.checked) {
details_div.style['display'] = 'block';
}
else {
details_div.style['display'] = 'none';
}
});
</script>

Resources