Generating dropdown values based on value of another dropdown in rails - ruby-on-rails

So basically, what I'm trying to do is show the value of status dropdown as [initial, started completed] when bug_type dropdown's value is bug, otherwise status dropdown should show [initial, started, resolved]
<div class="col">
<div class="form-group">
<%= form.select :bug_type, options_for_select([['Bug', 'bug'], ['Feature', 'feature']]) %> <br>
</div>
</div>
<div class="col">
<div class="form-group">
<% if #bug.bug_type == 'bug'%>
<%= form.select :status, options_for_select([['Initial', 'initial'], ['Started', 'started'], ['Completed', 'completed']]) %> <br>
<% else %>
<%= form.select :status, options_for_select([['Initial', 'initial'], ['Started', 'started'], ['Resolved', 'resolved']]) %> <br>
<% end %>
</div>
</div>
So far, I tried doing this but it doesn't work.
Also, I've used enums for bug_type and status. Please help me, if there's another approach to deal with this.

there are two ways for your requirement. One is client side you can change the dropdown value or you can send one server side request and render your required options.
For client side you can do like this:
<div class="col">
<div class="form-group">
<%= form.select :bug_type, options_for_select([["Bug", "bug"], ["Feature", "feature"]]) %>
</div>
</div>
<div class="col">
<div class="form-group">
<% if #bug.bug_type == "bug" %>
<%= form.select :status, options_for_select([["Initial", "initial"], ["Started", "started"], ["Completed", "completed"]]) %>
<% else %>
<%= form.select :status, options_for_select([["Initial", "initial"], ["Started", "started"], ["Resolved", "resolved"]]) %>
<% end %>
</div>
</div>
<script>
// Please change selector accoding to your DOM.
// This is bug type select dropdown
$('#bug_type_select').change(function() {
var selectedValue = $('#bug_type option:selected').val();
var bugOptions = {
'initial': 'Initial',
'started': 'Started',
'completed': 'Completed'
}
var featureOptions = {
'initial': 'Initial',
'started': 'Started',
'resolved': 'Resolved'
}
// Please change selector accoding to your DOM.
// This is status select dropdown
var $mySelect = $('#mySelect');
$mySelect.empty();
if (selectedValue === 'bug') {
$.each(bugOptions, function(key, value) {
var $option = $('<option/>', {
value: key,
text: value
});
$mySelect.append($option);
});
} else {
$.each(featureOptions, function(key, value) {
var $option = $('<option/>', {
value: key,
text: value
});
$mySelect.append($option);
});
}
});
</script>

Related

Deep rails nested attributes on the fly

I have a form, the form has 'fields_for :addresses' and renders partial 'address_fields' in that 'fields_for :addresses', in that partial 'address_fields' there is 'fields_for :sub_address', when the browser is first loaded, the 'fields_for :sub_address' in the partial 'address_fields' appears, but when the 'Add Addresses' button is pressed the "fields_for :sub_address" element does not appear. So basically I have a nested form inside the nested form 'addresses', but it doesn't render when I click on 'Add Address'.
This is my 'Add Address' javascript code:
class AddFields {
constructor() {
this.links = document.querySelectorAll('.add_fields');
this.iterateLinks();
}
iterateLinks() {
if (this.links.length === 0) return
this.links.forEach(link => {
link.addEventListener('click', e => {
this.handleClick(link, e)
});
});
}
handleClick(link, e) {
if (!link || !e) return;
e.preventDefault();
let time = new Date().getTime();
let linkId = link.dataset.id;
let regexp = linkId ? new RegExp(linkId, 'g') : null
let newFields = regexp ? link.dataset.fields.replace(regexp, time) : null
newFields ? link.insertAdjacentHTML('beforebegin', newFields) : null
}
}
window.addEventListener('turbolinks:load', () => new AddFields());
here is my views:
new.html.erb
<%= form_with model: #data, url: address_path(token: params[:token]) do |form| %>
<div class="row">
<div class="col">
//another html here
</div>
</div>
<fieldset>
<div class="card mt-2">
<div class="card-body">
<%= form.fields_for :address do |addr| %>
<%= render 'sub_address_fields', form: addr %>
<% end %>
<%= link_to_add_fields 'Add Address', form, :addr %>
</div>
</div>
</fieldset>
<div class="form-group">
<%= form.submit :'Submit', name: 'submit', class: 'btn btn-primary mt-2' %>
</div>
<% end %>
```
partial view:
<div class="nested-fields">
<%= form.hidden_field :_destroy %>
<div class="row">
<div class="col">
//another html here
</div>
<%= form.fields_for :sub_address do |sub_addr| %>
<div class="row">
<div class="col">
<div class="form-group mt-2">
<div class="custom-file form-control">
<%= sub_addr.label :id_card, class: 'id-card-label', for: 'id-card-file' %>
<%= sub_addr.file_field :attachment_id_card, id: 'id-card-file' %>
</div>
</div>
</div>
<div class="col">
<div class="form-group mt-2">
<div class="custom-file form-control">
<%= sub_addr.label :self_assessment, class: 'self-assessment-label', for: 'self-assessment-file' %>
<%= sub_addr.file_field :attachment_self_assess, id: 'self-assess-file' %>
</div>
</div>
</div>
<div class="col">
<div class="form-group mt-2">
<div class="custom-file form-control">
<%= sub_addr.label 'SWAB', class: 'swab-label', for: 'swab-file' %>
<%= sub_addr.file_field :attachment_swab, id: 'swab-file' %>
</div>
</div>
</div>
</div>
<% end %>
<div class="form-group">
<%= link_to "Remove", '#', class: "remove_fields"%>
</div>
</div>
and this is the helper:
module Frontend::Data::DataHelper
def link_to_add_fields(name, form, association)
new_object = form.object.send(association).klass.new
id = new_object.object_id
fields = form.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s.singularize + '_fields', form: builder)
end
link_to(name, '#', class: 'add_fields', data: {id: id, fields: fields.gsub('\n', '')})
end
end
Is javascript not able to display the form generated from the 'render' function on rails?

Open a text box when other is selected in dropdown list in rails

I have a table "fundings" in which there is a field "status", for which i have a select field in the form. The options for this select field are ["approved", "declined", "pending"]. What i want is when "declined" is selected, a further text box shows to explain the reason for decline. Please help how can this be done.
<%= form_for([#parent, #child, #funding], :html => {class: "form-horizontal",role: "form"}) do |form| %>
<div class = "form-group">
<div class="control-label col-sm-2">
<%= form.label :status %>
</div>
<% if current_user.admin? %>
<div class="col-sm-8">
<%= form.select :status,['Pending', 'Approved', 'Declined'], class: "form-control" %>
</div>
<% else %>
<!-- Disabled for non-admin users -->
<% end %>
</div>
<!-- Submit button here -->
<% end %>
Update
<div class="form-group">
<%= "Status" %>
<%= form.select :status, ['Pending', 'Approved', 'Declined'], {}, id: "sample-status-select", class: "form-control" %>
</div>
<div class="form-group">
<%= "Decline Reason" %>
<%= form.text_area :decline_reason, class: "form-control hidden", id: "decline-reason-textarea" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-10">
<%= form.submit "Apply", class: 'btn btn-primary btn-lg' %>
</div>
</div>
</div>
</div>
<% end %>
<script type="text/javascript">
<plain>
$(function() {
$("#sample-status-select").on("change", function() {
var select_val = $(this).val();
console.log(select_val);
if (select_val === 'Declined') {
$("#decline-reason-textarea").removeClass("hidden");
} else {
$("#decline-reason-textarea").addClass("hidden");
$("#decline-reason-textarea").val("");
}
});
});
</plain>
</script>
$(function() {
$("#sample-status-select").on("change", function() {
var select_val = $(this).val(); // this gets the value of the dropdown menu
console.log(select_val); // this just displays the selected value in the browser console (if you have the browser console open)
if (select_val === 'Declined') {
// if the 'Declined' option is chosen
// we remove the 'hidden' class from the textarea
$("#decline-reason-textarea").removeClass("hidden");
} else {
// if any other option is chosen
// we put back the 'hidden' class to the textarea
// also, we update the textarea value to BLANK (this part is optional, it depends if you want to keep the value of the textarea)
$("#decline-reason-textarea").addClass("hidden");
$("#decline-reason-textarea").val("");
}
});
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="https://httpbin.org/post" method="post">
Status
<select id="sample-status-select">
<option value="Pending">Pending</option>
<option value="Approved">Approved</option>
<option value="Declined">Declined</option>
</select>
<br>
<br> Decline Reason
<textarea id="decline-reason-textarea" class="hidden">
</textarea>
</form>
Check this snippet I made. It should work for you as well.
This is a basic html form so this works even without ruby on rails.
After you get the gist of this, you should be able to port for it to work with your rails app.
<script type="text/javascript">
$(function() {
$("#sample-status-select").on("change", function() {
var select_val = $(this).val();
console.log(select_val);
if (select_val === "Declined") {
$("#decline-reason-textarea").removeClass("hidden");
} else {
$("#decline-reason-textarea").addClass("hidden");
$("#decline-reason-textarea").val("");
}
});
});
</script>

Rails Submit button not submitting

I've moved from BS3 to Materialize so I am going through and changing my forms - I have 4 forms that are extremely similar, but as I switched the first one over it's no longer submitting. The button doesn't even seem like it's getting clicked, but I tied a generic 'logMe' function to it and sure enough it is.
My routes are the exact same for both, the new form is
<div class="row">
<%= form_with(model: #statement, local: true) do |form| %>
<% if #statement.errors.any? %>
<% #statement.errors.full_messages.each do |message| %>
<script>
$(function() {
Materialize.toast("<%= message %>", 3000);
});
</script>
<% end %>
<% end %>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">account_circle</i>
<!--<label for="icon_prefix">SoW Type:</label>-->
<%= form.label :statement_type, 'Type:' %>
<%= form.text_field :statement_type, :id => "disabled", :value => (params[:statement_type]), readonly: true, :disabled => true %>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<i class="material-icons prefix">contacts</i>
<%= form.label :name, "Name:" %>
<%= form.text_field :name, :id => 'required_field1' %>
</div>
<div class="input-field col s6">
<i class="material-icons prefix">contacts</i>
<%= form.label :cost, "Cost:" %>
<%= form.text_field :cost, :id => 'required_field2' %>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<i class="material-icons prefix">date_range</i>
<%= form.label :start_date, "Start Date" %>
<%= form.text_field :start_date, :class => 'datepicker', "data-provide" => 'datepicker', :id => 'required_field4', :placeholder => "YYYY-MM-DD" %>
</div>
<div class="input-field col s6">
<i class="material-icons prefix">date_range</i>
<%= form.label :end_date, "End Date" %>
<%= form.text_field :end_date, :class => 'datepicker', "data-provide" => 'datepicker', :id => 'required_field5', :placeholder => "YYYY-MM-DD" %>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">perm_contact_calendar</i>
<%= form.collection_select(:client_id, current_user.clients.order(:name),:id,:name, :class => "browser-default", :prompt => "Choose a client" ) %>
</div>
</div>
<div class="row">
<div class="col s12">
<%= form.submit 'Submit', :class =>'btn btn-default', :id => 'register', :onclick => "testMe()"%>
</div>
</div>
<% end %>
</div>
<script type="text/javascript">
$(document).ready(function (){
$('select').material_select();
validate();
$('#required_field1, #required_field2').change(validate);
});
function testMe(){
console.log('hi')
}
function validate(){
if ($('#required_field1').val().length > 0 &&
$('#required_field2').val().length > 0
){
$("input[type=submit]").prop("disabled", false);
}
else {
$("input[type=submit]").prop("disabled", true);
}
}
var from_$input = $('#required_field4').pickadate({
selectMonths: true, // Creates a dropdown to control month
selectYears: 15, // Creates a dropdown of 15 years to control year,
today: 'Today',
clear: 'Clear',
close: 'Ok',
closeOnSelect: true,
format: 'yyyy-mm-dd'
}),
from_picker = from_$input.pickadate('picker')
var to_$input = $('#required_field5').pickadate({
selectMonths: true, // Creates a dropdown to control month
selectYears: 15, // Creates a dropdown of 15 years to control year,
clear: 'Clear',
close: 'Ok',
closeOnSelect: true,
format: 'yyyy-mm-dd'
}),
to_picker = to_$input.pickadate('picker')
// Check if there’s a “from” or “to” date to start with.
if ( from_picker.get('value') ) {
to_picker.set('min', from_picker.get('select'))
}
if ( to_picker.get('value') ) {
from_picker.set('max', to_picker.get('select'))
}
// When something is selected, update the “from” and “to” limits.
from_picker.on('set', function(event) {
if ( event.select ) {
to_picker.set('min', from_picker.get('select'))
}
else if ( 'clear' in event ) {
to_picker.set('min', false)
}
})
to_picker.on('set', function(event) {
if ( event.select ) {
from_picker.set('max', to_picker.get('select'))
}
else if ( 'clear' in event ) {
from_picker.set('max', false)
}
})
</script>
I've tried commenting out all JS, switching it to a regular button, linting it and using Rubocop but I don't see anything off. I went through the HTML to make sure the button was inside the form, and it is.
This isn't the first form I've transitioned, but the first I'm having issues with.
(I assume only the view is relevant since it isn't getting to the controller at this point.)
Just to be safe - The view rendering the form is
<div class="row">
<div class="col s12"><span class="flow-text" style="text-align: center;"><h1>New <%= params[:statement_type] %></h1></span></div>
</div>
<% if params[:statement_type] == 'Proposal' %>
<%= render 'proposal_form' %>
<% elsif params[:statement_type] == 'Concept' %>
<%= render 'concept_form' %>
<% elsif params[:statement_type] == 'SoW' %>
<%= render 'sow_form' %>
<% elsif params[:statement_type] == 'Misc' %>
<%= render 'misc_form' %>
<% end %>
<%= link_to 'Back', statements_path %>
SoW + Proposal work. SoW doesn't.
My issue ended up not being HTML based, but Rails based in the end.
My static element that is populated by a param was causing the issue.
<%= f.text_field :statement_type, :id => "disabled", :value => (params[:statement_type]), readonly: true %>
By removing the id: disabled it resolved the inability for the Submit button to submit. Unfortunately, it also makes MaterializeCSS back to highlighting the field when I select it, but my issue was the Submit button not working.

How to use radio button to not send data to the server?

I am able with the radio button and a little javascript to toggle between the two categories, but even if one category is hidden it's data still sends.
challenge.rb
class Challenge < ActiveRecord::Base
scope :oneshot, -> { where(categories: 'One-Shot') }
scope :ongoing, -> { where(categories: 'Ongoing') }
_form
<%= form_for(#challenge) do |f| %>
<%= f.text_field :action %>
<% Challenge::CATEGORY.each do |c| %>
<%= label(c, c) %>:
<%= f.radio_button(:category, c, :class => "date-format-switcher", checked: (c=='One-Shot')) %>
<% end %>
<div id='id_of_first_div'>
<%= f.date_select :deadline %>
</div>
<div id='id_of_second_div'>
<%= f.date_select :date_started %>
</div>
<% end %>
<script>
$(function(){
$('#id_of_second_div').hide();
$('#challenge_category_one-shot').click(function(){
$('#id_of_first_div').show().attr('disabled', false);
$('#id_of_second_div').hide().attr('disabled', true);
});
$('#challenge_category_ongoing').click(function(){
$('#id_of_first_div').hide().attr('disabled', true);
$('#id_of_second_div').show().attr('disabled', false);
});
});
</script>
Radio Button HTML
<input class="date-format-switcher" type="radio" value="One-Shot" checked="checked" name="challenge[category]" id="challenge_category_one-shot" />
<input class="date-format-switcher" type="radio" value="Ongoing" name="challenge[category]" id="challenge_category_ongoing" />
Adapting Fiddle
<input id='a-selector' type='radio' name='selector' value='A' checked/> A
<input id='b-selector' type='radio' name='selector' value='B'/> B
<div id='details'>
<div id='for-a'>
<%= f.date_select :deadline, include_blank: true, selected: Date.current %>
</div>
<div id='for-b'>
<%= f.date_select :date_started, include_blank: true, selected: Date.current %>
</div>
</div>
<script>
var removed = $('#for-b').detach();
$('#a-selector').click(function() {
$('#details').append(removed);
removed = $('#for-b').detach();
})
$('#b-selector').click(function() {
$('#details').append(removed);
removed = $('#for-a').detach();
})
</script>
Setting a form element as disabled only disables user interaction with it; it doesn't remove it from the form's data (although your jQuery code is actually setting the div to disabled, which does nothing, but fixing that wouldn't help at all). What you want to do instead is clear the value of the date elements, e.g.,
<script>
$(function(){
$('#id_of_second_div').hide();
$('#challenge_category_one-shot').click(function(){
$('#id_of_first_div').show();
$('#id_of_second_div').hide();
$('#id_of_second_div select').value('')
});
$('#challenge_category_ongoing').click(function(){
$('#id_of_second_div').show();
$('#id_of_first_div').hide();
$('#id_of_first_div select').value('')
});
});
</script>
Though for that to work, you will need to add include_blank: true as an option to your date_select tags:
<%= f.date_select :deadline, include_blank: true %>
This will add the empty value as an option to your date selects, so that the above code can reset them to that empty value.
I'd also like to note -- all of this is just front-end logic, which any malevolent (or curious) user can circumvent. Your backend code (i.e., your controller) should handle discarding the fields you don't need based on your business logic, too.

Ruby on rails checkbox (when clicked to div, enable checkbox)

I want checkbox to be clicked when div.tel_show is clicked
<script type="text/javascript">
$("div.tel_show").on("click",function(event) {
var target = $(event.target);
if (target.is('input:checkbox')) return;
var checkbox = $(this).find("input[type='checkbox']");
if( !checkbox.prop("checked") ){
checkbox.prop("checked",true);
} else {
checkbox.prop("checked",false);
}
});
</script>
I think I need to change var checkbox = $(this).find("input[type='checkbox']");
what should I write instead of input[type='checkbox']
<div class="row">
<div id="media-contents" class="col-lg-12">
<% if #media_contents.empty? %>
<h2 id="no-media">Dosya Bulunamadı</h2>
<% else %>
<% #media_contents.each do |media| %>
<div class="col-lg-4 tel_show">
<div class="thumbnail">
<%= image_tag media.file_name.url %>
<div class="caption">
<p>
<%= check_box_tag "media_contents[]", media.id %>
</p>
</div>
</div>
</div>
<% end %>
<% end %>
</div>
</div>
Thanks in advance.
Try this:
$("div").live("click",function(event)
{
var target = $(event.target);
if (target.is('input:checkbox')) return;
var checkbox = $(this).find("input[type='checkbox']");
if( checkbox.attr("checked") == "" ){
checkbox.attr("checked","true");
} else {
checkbox.attr("checked","");
}
});
Give your checkbox a class or an id, then use e.g. $('#checkbox_id') to find it.
Input type selectors should not have '' around the type, e.g. should be "input[type=checkbox]" instead of "input[type='checkbox']".

Resources