I have a form which contains a dropdown of 3 values QUESTIONS_TYPES = {'single', 'multiple', A text}
<div class="field">
<%= f.label :question_type %><br>
<%= f.select :question_type, Question::QUESTIONS_TYPES, prompt: 'Select a question type' %>
</div>
Using Jquery, this dropdown shows other fields(in the block whose class is .answers_list) depending of the choosing value.
$(document).ready(function(){
$('#question_question_type').change(function(){
var qst_type = $('#question_question_type option:selected').text()
if (qst_type == 'Multiple' || qst_type == 'Single'){
$('.answers_list').show();
} else{
$('.answers_list').hide();
}
});
});
The thing is when I access to the form via a link:
<%= link_to 'New Question', new_question_path %>
My dropdown doesn't respond the jQuery action, once i refresh the page it does. Any suggestion?
Thanks!!
use
$( ".target" ).toggle();
see
Click here
Related
Note:
Similar questions exist but none of them resemble my case
I am making a small Ajax form in my rails views with yes or no radio buttons, I made this form with remote: true and it acts correctly as Ajax if I use a separate submit button (no page reload happens & form is passed to controller)
If I use Jquery to make the radio buttons themselves submit the form, then it submits but not in Ajax (but with a page reload)
So how to fix this to:
Submit form on clicking one of the 2 radio buttons in Ajax?
The two things I tried:
1) Make two different submit buttons & try to adjust the form value in the submit btn itself, if I make them as submit buttons, Ajax works well but the form doesn't get my required value
<div class="radio-button-btn-wrapper mr-2">
<%= f.submit t('yes'), recommended: true, class: "radio-button-btn-label-white background-green" %>
</div>
<div class="radio-button-btn-wrapper mr-2">
<%= f.submit t('no'), recommended: false, class: "radio-button-btn-label-white background-red" %>
</div>
2) Adjust the radio buttons to submit the form in Ajax manner (tried this but it didn't work)
<%= simple_form_for [...model names], remote: true do |f| %>
<div class="flex">
<div class="radio-button-btn-wrapper mr-2">
<%= label :recommended, t('yes'), class: "radio-button-btn-label white" %>
<%= f.radio_button :recommended, true, onclick: "$(this).closest('form').submit();", class: "radio-button-btn background-green" %>
</div>
<div class="radio-button-btn-wrapper">
<%= label :recommended, t('no'), class: "radio-button-btn-label white" %>
<%= f.radio_button :recommended, false, onclick: "$.ajax((this).closest('form').submit());", class: "radio-button-btn background-red" %>
</div>
</div>
What worked for me was adding a 'normal' submit button and set it to display none. Then add an eventListener that listen to a click on the radio button and if that happens, let it click on the hidden submit button.
<%= simple_form_for [...model names], remote: true do |f| %>
<div class="flex">
<div class="radio-button-btn-wrapper mr-2">
<%= label :recommended, t('yes'), class: "radio-button-btn-label white" %>
<%= f.radio_button :recommended, true, class: "radio-button-btn background-green" %>
</div>
<div class="radio-button-btn-wrapper">
<%= label :recommended, t('no'), class: "radio-button-btn-label white" %>
<%= f.radio_button :recommended, false, class: "radio-button-btn background-red" %>
</div>
<%= f.submit '', class: 'd-none', id: 'submitMyForm' %>
</div>
document.addEventListener('click', function(event){
if(event.target.classList.contains('radio-button-btn'){
document.querySelector('#submitMyForm').click();
}
});
Please look into the code below and try to adapt it for your case. This is working code I have tested in my Rails app.
The basic idea is instead of trying to make the radio buttons as submit buttons I employed the approach of a hidden form and then bind click events on radio buttons. In the button click handler I set the selected radio button's value as a hidden field value in hidden form and submit the hidden form. It gets submitted as an AJAX request and on controller-end handle the JS response.
Hope this helps.
routes.rb
root "welcome#index"
post "welcome_submit_form" => "welcome#submit_form", as: :welcome_submit_form
app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
def index
end
def submit_form
#received_radio_value = params[:selected_radio_value]
render file: "welcome/submit_form_response.js.haml"
end
end
app/views/welcome/index.html.haml
.my-container<
%div(style='display: none;')
= form_tag(welcome_submit_form_path, class: 'my-hidden-form', remote: true) do |f|
= hidden_field_tag "selected_radio_value", nil
= radio_button_tag 'favorite_color', 'red', false, class: 'my-radio-btn'
Red
= radio_button_tag 'favorite_color', 'blue', false, class: 'my-radio-btn'
Blue
.my-selected-radio-value(style='display: none')
app/views/welcome/submit_form_response.html.haml
%h2= "My Radio Value: #{#received_radio_value}"
app/views/welcome/submit_form_response.js.haml
- response_markup = escape_javascript(render( partial: "welcome/submit_form_response.html.haml" ))
:plain
var responseMarkup = "#{response_markup}";
var responseContainer = $('.my-selected-radio-value');
responseContainer.html(responseMarkup);
responseContainer.show();
app/assets/javascripts/welcome.js
(function ($) {
bindClickEventOnMyRadioBtn = function() {
$('.my-container .my-radio-btn').off('click').on('click', function(event) {
var selectedRadioVal = $(this).val();
var myHiddenForm = $('.my-container .my-hidden-form');
var radioValueField = myHiddenForm.find('input[name=selected_radio_value]');
radioValueField.val(selectedRadioVal);
myHiddenForm.submit();
})
}
}) (jQuery);
var ready;
ready = function() {
bindClickEventOnMyRadioBtn();
};
$(document).ready(ready);
After extensive searching for why this happens & how to fix it in the easiest way, I found this issue in Rails 5.2 & thanks to this solution from Padi we should use this code to make it work as expected:
// Get hold of the form object
form = document.querySelector('form');
// Use the Rails fire helper
Rails.fire(form, 'submit');
How to show form on load. Now I can see form fields on click of button (add keyskills). I want all function to be work together.On load i want to see the form and onclick 'add key skill' or 'remove key skill' it should add and remove(now on click of add or remove it is working, but not sees the form on load, only on click of 'add key skill' i can see the form)
$(function()
{
function check_to_hide_or_show_add_key_skill_link()
{
if ($('#key_skills .nested-fields:visible').length == 4) {
$('#key_skills .links a').hide();
} else {
$('#key_skills .links a').show();
}
}
$('#key_skills').on('cocoon:after-insert', function()
{
check_to_hide_or_show_add_key_skill_link();
});
$('#key_skills').on('cocoon:after-remove', function()
{
check_to_hide_or_show_add_key_skill_link();
});
check_to_hide_or_show_add_key_skill_link();
});
My form
Key Skills*
<div id="key_skills">
<%= f.simple_fields_for :key_skills do |key_skill| %>
<div class="nested-fields">
<div class="field">
<%= f.input :name , input_html: { class: 'form-control keySkill', required: true }%>
<%= f.input :relevant_experience, input_html: { class: 'form-control', required: true } %>
<%= link_to_remove_association "Remove Skill", f %>
</div>
</div>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Key Skill', f, :key_skills, class: "links" %>
</div>
</div>
This is my current output now. On click of add key skill i will get form,but i want it on load)
Since you do not provide a lot of information, I have no idea what the name of the top-element is, but let us assume it is a Job and a job has many key_skills.
In your JobsController there is a create method, more or less as follows:
def create
#job = Job.new
end
if you want to immediately add a key-skill to fill in you can just write
def create
#job = Job.new
#job.key_skills.build
end
(which will add an empty key-skill to fill in).
Related issue on cocoon-repository: https://github.com/nathanvda/cocoon/issues/420
In my Rails app I have this code
<%= form_for #experience, url: experience_path do |f| %>
<div class="experselect end-date">
<%= f.label :experience_end, class: "profile_label" %><br />
<%= f.date_select :experience_end, {start_year: 1945, discard_day: true, order: [ :day, :month, :year ]}, :html=> {class: 'date-select'} %>
</div>
<div class="form-checkbox current-item">
<%= f.check_box :experience_current, class: 'is_current', id: "checkbox_id" %>
I currently work here
</div>
<%= f.submit "Update experience" %>
And I have a link_to_add_fields method that add the same form as this I have also this script that disable the experience_end when the checkbox is checked and it works great.
function disableEndDate(thisObj) {
var targetedSelect = thisObj.closest(".form-checkbox").prev(".experselect").find("select");
if (thisObj.prop("checked")) {
targetedSelect.prop(
'disabled', true);
targetedSelect.css(
"background-color", "#D9D8DD");
} else {
targetedSelect.prop(
'disabled', false);
targetedSelect.css(
"background-color", "#FFFFFF");
}
}
$(document).ready(function(){
$("input[class='is_current']").click(function () {
disableEndDate($(this));
});
});
But actually my problem is when checkbox and submit the form and try to edit it again i find that the checkbox is checked and the select is disabled but the background of the select is not #D9D8DD as expected
You have to reach your select starting from your checkbox. For this, you 'll need to pass $(this)parameter to your disableEndDate() function on click event :
$("input[class='is_current']").click(function () {
disableEndDate($(this));
});
Now your function is ready to get your clicked checkbox element. And you also know that DIVs containing input and select are nested.
You get targetedSelect starting at your checkbox. You reach the parent div (.form-checkbox), then the previous div containing the select element (.form-checkbox), and finally, find the select.
So :
function disableEndDate(thisObj) {
var targetedSelect = thisObj.closest(".form-checkbox").prev(".experselect").find("select");
if (thisObj.prop("checked")) {
targetedSelect.prop(
'disabled', true);
targetedSelect.css(
"background-color", "#D9D8DD");
} else {
targetedSelect.prop(
'disabled', false);
targetedSelect.css(
"background-color", "#FFFFFF");
}
}
Live exemple
Hope this will help
I want to have a button for retweets in my web-application. When I press the button I want a form to display in order to add my own text to the tweet.
I implemented this . However I have a problem: all my forms and buttons contain the same id and class, so you can imagine that when I press a button it will display the first form with that id/class instead of the one that it has to show. How can I show the form that I have to show ?
Here are only the parts of the code that contain retweet part(the other parts are not important I think for the problem but I can post them if someone wants me to) :
<button type="buton" id="retweet-button">retweet</button>
<%= form_for(current_user.tweets.build,url: retweet_act_path, method: :post, html: { multipart: true, :class => "retweet_form" }) do |f| %>
<%= f.hidden_field :original_tweet_id, value: tweet.id %>
<%= f.text_area :content, placeholder: "Add a message to the tweet..." %>
<%= f.submit "Retweet"%>
<% end %>
And the JS:
<script type="text/javascript">
$(document).ready(function() {
$('.retweet_form').hide(); //Initially form wil be hidden.
$('#retweet-button').click(function() {
$('.retweet_form').show();//Form shows on button click
});
});
</script>
How can I show the form that I have to show when pressing a certain button ? (I guess I have to have a different ID for every button and form , but how ? )
As I understood from the code, you use one button/form pair per tweet. So that, you are able to use tweet ID to generate form ID. To connect button to appropriate form, use data-* fields.
Generation of forms and buttons on Rails side (NOTE: syntax highlight is broken):
<button type="button" class="retweet-button" data-target-form-id="<%= "#retweet-form-#{tweet.id}" %>">retweet</button>
<%= form_for(current_user.tweets.build,url: retweet_act_path, method: :post, html: { multipart: true, :class => "retweet_form", id: "retweet-form-#{tweet.id}" }) do |f| %>
<%= f.hidden_field :original_tweet_id, value: tweet.id %>
<%= f.text_area :content, placeholder: "Add a message to the tweet..." %>
<%= f.submit "Retweet"%>
<% end %>
And JS:
$('.retweet_form').hide();
$('.retweet-button').click(function() {
var formId = $(this).data('target-form-id');
$(formId).show();
});
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'));
});
});
});