Rails - Change form field based on another field selection - javascript

I have a form with the following field.
<%= f.select :year, CalenderBuilder.getCurrentYearArray %>
<%= f.select :month, CalenderBuilder.getCurrentMonthArray %>
what i want is how to change month field based on the selection of year field
if year selected is current year then
<%= f.select :month, CalenderBuilder.getCurrentMonthArray[0..Date::MONTHNAMES.index(DateTime.now.strftime("%B"))-1] %>
else
<%= f.select :month, CalenderBuilder.getCurrentMonthArray %>
end
Calender Builder contains functions 'getCurrentMonthArray' and 'getCurrentYearArray' which return data like [["January", "Jan"], ["February", "Feb"], ["March", "Mar"], ... , ["November", "Nov"], ["December", "Dec"]] and [[2021, 2021], [2022, 2022], [2023, 2023]] respectively
what i'm doing basically is if year selected is current year then i want rails to render from January to current month. can anyone help me with this

Related

Add a new form based on another form's data?

I have a dropdown menu that allows the user to select a time period (ie: January 2018, 1st Trimester, Summer 2018, etc.). At the very bottom there's an option labelled "Other". How can I make it so that if the user selects "Other", and text-input form appears beneath that so that they can elaborate on what "Other" means? Here's my current code:
HTML:
Time Period:
<% if f.object.award.add_period? %>
<div class="time_period_<%= f.object.award.id %>" id="otherBoolID">
<%= f.select :time_period, Award::TimePeriods, {:include_blank => true}, { :class => "date_dropdown"} %>
</div>
<% end %>
<div id="boolID" <%= "hidden" %>>
<%= f.input :time_period, :label => false, placeholder: "Other (please specify)", :input_html => { :class => 'awardform' } %>
</div>
JavaScript/JQuery:
$('#otherBoolID').change(function () {
var x = document.getElementById('otherBoolID').value;
if (x == "Other") {
document.getElementById('boolID').style.display = 'visible';
}
});
Any idea what's going wrong? Currently the "other" form is hidden on page load, but doesn't become visible if you select "Other" in the dropdown menu. If it's worth mentioning, I'm working with a ruby on rails framework.
Could the issue be that the id="otherBoolID" is on the <div> rather than <select> tag?

Is there a way to regenerate link_to_add_association (specifically data-association-insertion-template)?

Built a very basic rails app to manipulate nested attributes using cocoon and the add and remove links work great. However, it wasn't too long until I wanted to alter the underlying content of what was inserted, say in response to another field changing the list of option values in an included select tag. It appears that the contents to be added are contained in an 'a' tag data element (data-association-insertion-template). I can quite easily change the select options for all included lines via jQuery but changing the behavior of the link_to_add_association is beyond me.
Here are snippets of my example:
_form.html.erb
<div>
<strong>Entries:</strong>
<div id="entries" style="border: thin solid">
<%= f.fields_for :entries do |oi| %>
<%= render "entry_fields", f: oi %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Entry', f, :entries, {id: 'cocoon-add-entry'} %>
</div>
</div>
</div>
_entry_fields.html.erb
<div class="nested-fields">
<%= f.label :item_id %>
<%= f.select :item_id, #items.collect {|i| [i.style, i.id]}, {include_blank: true}, {selected: :item_id, multiple: false} %>
<%= f.label :decoration_id, 'Decoration' %>
<%= f.select :decoration_id, #decorations.collect { |d| [ d.name, d.id ] }, {include_blank: true}, {selected: :decoration_id, multiple: false, class: 'decoration'} %>
<%= f.label :color %>
<%= f.text_field :color %>
<%= f.label :size_id %>
<%= f.select :size_id, #sizes.collect { |s| [ s.name, s.id ] }, {include_blank: true}, {selected: :size_id, multiple: false} %>
<%= f.label :number %>
<%= f.number_field :number, value: 1, min: 1 %>
<%= f.check_box :_destroy, hidden: true %>
<%= link_to_remove_association "Remove Entry", f %>
</div>
orders.coffee
ready = ->
$('.customer').change ->
$.ajax
url: '/orders/change_customer'
data: { customer_id : #value }
$(document).ready(ready)
$(document).on('turbolinks:load', ready)
order_controller.rb
def change_customer
#decorations = Decoration.joins(:logo).where('logos.customer_id = ?', params[:customer_id])
respond_to do |format|
format.js
end
end
change_customer.js.erb
// update all existing entry decorations with new customer driven options
<% new_decor = options_from_collection_for_select(#decorations, :id, :name) %>
var new_decor_options = "<option value='' selected='selected'></option>" + "<%=j new_decor %>";
$('.decoration').html(new_decor_options);
// now need to change $('#cocoon-add-entry').attr('data-association-insertion-template, ???);
// or regenerate link entirely - but don't have required data to do so here (form builder from original)
I have tried to manipulate the template data string directly via js str.replace but that is one ugly regular expression because of the unescapeHTML and htmlsafe operations done to make it an attribute in the first place. And, that approach doesn't smell good to me. I have been slowly working through the cocoon view_helpers and javascript but nothing seems to fit or I don't seem to have the right methods/data values to build a replacement link. Suggestions?
BTW, kudos for cocoon gem.
After a lot of gnashing of teeth, I have cobbled together a potential solution. I haven't decided if I will let this go into production yet because of the limitations but thanks to combining several different SO questions and answers, the following works:
change_customer.js.erb
// update all existing entry decorations with new customer driven options
<% new_decor = options_from_collection_for_select(#decorations, :id, :name) %>
var new_decor_options = "<option value='' selected='selected'></option>" + "<%=j new_decor %>";
$('.decoration').html(new_decor_options);
// update the Add Entry link to capture new decorations set.
// Note use of ugly hack to recreate 'similar' form.
// Also note that this will only work for new order; will have to revise for edit.
'<%= form_for(Order.new) do |ff| %>'
$('#cocoon-add-entry').replaceWith("<%=j render partial: 'add_entry_link', locals: {f: ff} %>");
'<% end %>'
_add_entry_link.html.erb
<%= link_to_add_association 'Add Entry', f, :entries, {id: 'cocoon-add-entry', data: {'association-insertion-method' => 'after'}} %>

Form inside another form rails

Let me first say that I'm a beginner with web development, so stay with me!
The thing is that I have a page where rails will gather all the rooms from the database. And then list them in a table. So far so good. But I want the user to be able to click a button next to each row, that will book the room for the user.
Atm I have it working 80%. The thing is that I have a form inside another form, so when the user press book then it books the last row in the table ofc! So how do I fix this? I read about using javascript to fix this, but as a beginner I dont really know javascript.
I could put the Reservation.new form inside the all_rooms form and it will work. But I need to get the value from the datetimepicker from the user also. Thats why I put it outside.
<%= form_for(Reservation.new, remote: true, format: :js, url: {controller: "booker", action: "create"}) do |new_res| %>
<div class="calender">
<%= new_res.date_field :date, :value => (Time.now + 6.days).strftime('%Y-%m-%d') , min: 6.days.from_now, max: 90.days.from_now %>
</div>
<div class="time">
<%= new_res.time_select :start_time , {:default => {:hour => 10 , :minute => 00}, minute_step: 15 , :start_hour => 8, :end_hour => 18, :hour => 11} %>
<%= new_res.time_select :end_time , {:default => {:hour => 14 , :minute => 00}, minute_step: 15 , :start_hour => 8, :end_hour => 18, :hour => 11} %>
</div>
</div>
<div class="t_Data">
<table class ="rooms_to_book">
<tr>
<th>Namn</th>
<th>Storlek</th>
<th>Byggnad</th>
<th>Utrustning</th>
<th>Booka</th>
</tr>
<% #all_rooms.each do |r| %>
<tr>
<td><%= r.room %></td>
<td><%= r.room_size %></td>
<td><%= r.building %></td>
<td><%= r.room_description %></td>
<td>
<%= new_res.hidden_field :room, value: r.room %>
<%= new_res.hidden_field :building, value: r.building %>
<%= new_res.hidden_field :room_size, value: r.room_size %>
<%= new_res.hidden_field :room_description, value: r.room_description %>
<%= new_res.submit "Book" %>
</td>
</tr>
<% end %>
</table>
</div>
<% end %>
So question is. How do I fix this problem, so when I press book. I create a new reservation and gather all the data + the date the user picked. So its unique for each row.
Instead of all the hidden fields you could name each of the submit buttons like this
<%= new_res.submit "Book", name: r.id %>
then inside your create action in your controller extract the room id from the params hash, as it will be a key in the params hash pointing to "Book". Then using the id you can find the associated Room object and create a new Reservation using everything you had in the hidden fields.

How to add/remove a group of fields using jQuery in a multi-step Rails 3 form?

I have a Rails 3 app with a multi-step form that I developed using this railscast: http://railscasts.com/episodes/217-multistep-forms
In the 3rd step(not the last step) of my form, I have a group of fields, called "Audience", which contains 4 select boxes.
Using Jquery, I have "add" and "remove" links next to this group of fields, so that I can have multiple "Audiences" in the form.
So for example, I start off with 1 Audience. If I click "add", then I have another Audience for a total of 2 Audiences (2 groups of fields). However, if I click on "remove", then that Audience will be removed from the form, and I'll be left with 1 Audience (1 group of fields) again.
This Audience form is nested. I used the nested form gem for this: https://github.com/ryanb/nested_form/
My problem is that no matter what I try, this Audience portion of the form never seems to work correctly. Right now, when the Audience form page first loads, the "remove" link doesn't appear at all, and every time I click the "add" link, 2 groups of fields are added instead of just 1. When I go to another page, and then come back to the Audience form again, then the "remove" link reappears, but the "add" link still does the same thing. Every time I go back to the page, more fields are added without me even clicking on the "add" link. In addition, I set a limit to the number of fields, but that doesn't work either.
I've spent the better part of a week on this problem, and I still can't figure it out. My Jquery skills are not wonderful, but I can do the basics. I've repeatedly asked for suggestions, but they never work. I'm desperate at this point...I already started banging my head against the wall a few days ago.
I have a good demonstration of what I want here, just replace "beets" with a group of fields: http://jsfiddle.net/beehive/8zJr6/
Any suggestions for a solution to this would be greatly appreciated. Maybe I should just go with a different approach entirely?
application.js
$(document).ready(function() {
// Nested Audience form
var x = $('#audiencefields');
var i = $('#audiencefields p').size() + 1;
$('#addlink').live('click', function() {
if ($(".item", x).length < 3) {
$('<p class="item" id="audiencecontainer">beets '+ i +'#removelink').appendTo(i);
i++;
}
return false;
});
$('#removelink').live('click', function() {
if (i > 2) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
_audience_step.html.erb
<div class="uploadcontent">
<h1 class="uploadtitle">select your audience</h1>
<div id="audiencefields">
<p id="audiencecontainer">
<%= f.fields_for :audiences do |audience_form| %>
<ul class="uploadformlist">
<li>
<%= audience_form.label :number_of_people, "Size" %><br />
<%= audience_form.collection_select :number_of_people, Audience::PEOPLE, :to_s, :to_s, :include_blank => true %>
</li>
<li>
<%= audience_form.label :gender %><br />
<%= audience_form.collection_select :gender, Audience::GENDERS, :to_s, :to_s, :include_blank => true %>
</li>
<li>
<%= audience_form.label :age %><br />
<%= audience_form.collection_select :age, Audience::AGES, :to_s, :to_s, :include_blank => true %>
</li>
<li>
<%= audience_form.label :ethnicity %><br />
<%= audience_form.collection_select :ethnicity, Audience::ETHNICITIES, :to_s, :to_s, :include_blank => true %>
</li>
</ul>
<%= audience_form.link_to_remove "Remove this audience", :id => "removelink" %>
<% end %>
</p>
</div>
<p><%= f.link_to_add "Add another audience", :audiences, :id => "addlink" %></p>
</div>
audience.rb
class Audience < ActiveRecord::Base
attr_accessible :age, :ethnicity, :gender, :number_of_people
belongs_to :upload
#validates_presence_of :age, :ethnicity, :gender, :number_of_people
PEOPLE = ['5', '10', '25', '50', '75', '100']
GENDERS = ['Male', 'Female']
ETHNICITIES = ['Caucasian/White', 'African-American/Black', 'Latin/Hispanic', 'Asian', 'Indian', 'Middle-Eastern', 'Native American']
AGES = ['0-2', '3-5', '6-12', '13-17', '18-29', '30-39', '40-49', '50-59', '60+']
end

How reset multiple scroll down selected menus

I've 2 scroll down menus like
<%= f.label :term_id, "TERM *"%>
<br>
<%= f.collection_select :term_id, Term.order(:id), :id, :name, include_blank: true %>
<br>
<%= f.label :lesson_id, "LESSON *" %>
<br>
<%= f.grouped_collection_select :lesson_id, Term.order(:name), :lessons, :name, :id, :name, include_blank: "Ders Seçiniz" %>
and the javascript code is like that
jQuery ->
lessons = $('#demand_lesson_id').html()
$('#demand_term_id').change ->
term = $('#demand_term_id :selected').text()
options = $(lessons).filter("optgroup[label='#{term}']").html()
if options
$('#demand_lesson_id').html(options)
else
$('#demand_lesson_id').empty()
I need to reset when I click to reset button. but all forms elements are cleaned except lessons group collection.
How can I manage it?
The form reset button should restore all your select's default options. But if you need something to override whatever it is overriding the reset button behaviour, here's some plain old jQuery (Sorry, but I'm not familiar with CoffeeScript).
See it at the following jsFiddle
$(function(){
// reset button click
$('#myReset').click(function(){
// cycle through each option and restore to default
$('#myForm select option').each(function(){
$(this).prop('selected', $(this).prop('defaultSelected'));
});
});
});

Categories

Resources