How to show a form on load - javascript

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

Related

Rails 5 ajax form: submit form on clicking one of the 2 radio buttons in Ajax

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');

Using JavaScript/Jquery to show forms with the same id/class in Ruby

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();
});

How to Change Date Format According to User Selection?

How can I change the date :order according to the User's "f.select :categories" choice?
For example when a User goes to the Quantified _form he can select between "Monthly Average" or "One-Time Instance";
If he selects "Monthly Average" I want the _results_fields.html.erb to provide the date selection as ":order => [:month, :year]" if he selects "One-Time Instance" I want the _results_fields.html.erb to provide the date selection as ":order => [:month, :day, :year]
Ideally this would be done dynamically via javascript, but I would be happy to accept an answer that does it via the view.
_results_fields.html.erb
<div class="nested-fields">
<div class="form-group">
<%= f.text_field :result_value, class: 'form-control', placeholder: 'Enter Result' %>
<br/>
<%= f.date_select :date_value, :order => [:month, :year], class: 'date-select' %>
<%= link_to_remove_association "Remove Result", f %>
</div>
</div>
_form.html.erb
<%= form_for #quantified do |f| %>
<div class="america">
<%= f.select :categories, Quantified::CATEGORIES %>
<br/>
<br/>
<div class="form-group">
<%= f.text_field :name, class: 'form-control', placeholder: 'Enter Name' %>
</div>
<div class="form-group">
<%= f.text_field :metric, class: 'form-control', placeholder: 'Enter Metric' %>
</div>
<div id="results">
<%= f.fields_for :results do |result| %>
<%= render 'result_fields', :f => result %>
<% end %>
</div>
<div class="links">
<%= link_to_add_association 'add result', f, :results %>
</div>
<%= f.submit %>
</div>
<% end %>
quantified.rb
class Quantified < ActiveRecord::Base
belongs_to :user
scope :averaged, -> { where(categories: 'Monthly Average') }
scope :instance, -> { where(categories: 'One-Time Instance') }
has_many :results
accepts_nested_attributes_for :results, :reject_if => :all_blank, :allow_destroy => true
CATEGORIES = ['Monthly Average', 'One-Time Instance']
end
Github: https://github.com/RallyWithGalli/ruletoday
Thank you for your time.
The answer here was to use some jquery provided by the gem that was being used to add the date selects, as well as some jquery of our own
First things first, we rig up the checkboxes with a click() event, that hides anything with the class 'day' if instance is checked, and shows it if not.
$('.date-toggle').click(function(){
if( $(this).attr('id') == 'instance') {
$('.day').show();
} else {
$('.day').hide();
}
});
The trick here is to use the rails date select option :with_css_classes on the date select, so that it looks like this:
<%= f.date_select :date_value, :order => [:month, :day, :year], :with_css_classes => true, class: 'date-select' %>
This causes each included field to get a class corresponding to its name, hence our reference to '.day' up there.
The next important part, however, because he is using a gem called cocoon to add new elements that included date fields, we had to use some of their jquery event bindings to make sure that the new ones got the right action applied to them.
$('#container').on('cocoon:after-insert', function(e, insertedItem) {
if($('#instance').is(':checked')) {
$('.day').show();
} else {
$('.day').hide();
}
});
Technically, the $('.day').show() is not necessary, because it defaults to being shown, but this, to me, gets across the intent a little clearer.
I think my solution is a little bit messy, but hopefully it gives you an indication of my train of thought and give you something to build upon.
I have changed your categories to work with a radio button group because the select field is a bit weird for 2 elements (subjective I know), to change it back to a select form,simply keep your code as is, but you will need to check the value of the select dropdown using jQuery .change() or some other vanilla Javascript way...
You haven't provided any controller names, so I didn't know how to name my JS file, but hopefully you know how to integrate.
IMO, I'm not sure why this needs AJAX, so maybe you can explain to me where that comes in.
_form.html.erb
<%= Quantified::CATEGORIES.each do |c| %>
<%= f.radio_button(:category, c) %>
<%= label(c, c) %>
<% end %>
_results_fields.html.erb
<%= f.date_select :date_value, :order => [:month, :year], class: 'date-select-my' %>
<%= f.date_select :date_value, :order => [:month, :year], class: 'date-select-mdy' %>
vanilla.js
$(document).ready(function(){
$('.date-select-mdy').hide();
$('.date-select-mdy').attr("disabled", true);
$('input[name$=\category\']').click(function() {
var target_value;
target_value = $(this).val;
if (target_value === 'Monthly Average') {
$('.date-select-my').show();
$('.date-select-mdy').hide();
$('.date-select-my').attr("disabled", false);
return $('.date-select-mdy').attr("disabled", true);
} else {
$('.date-select-my').hide();
$('.date-select-mdy').show();
$('.date-select-my').attr("disabled", true);
return $('.date-select-mdy').attr("disabled", false);
}
});
});
a_little_bit_of_coffee_because_i_dislike_js.coffee
$->
$('.date-select-mdy').hide()
$('.date-select-mdy').attr("disabled",true)
$('input[name$=\category\']').click ->
target_value = $(this).val
if target_value == 'Monthly Average'
$('.date-select-my').show()
$('.date-select-mdy').hide()
$('.date-select-my').attr("disabled",false)
$('.date-select-mdy').attr("disabled",true)
else
$('.date-select-my').hide()
$('.date-select-mdy').show()
$('.date-select-my').attr("disabled",true)
$('.date-select-mdy').attr("disabled",false)
return

Select/Deselect multiple check boxes using Jquery in loop(Rails)

I working on RoR, I have a two loops inside that i am displaying records with check boxes.
<%= form_tag some_path, :method => 'post' do %>
For loop
<%= check_box_tag 'ids[]', value %> Name
For loop
<%= check_box_tag 'ids_of_second_loop[]', value %> Name
end
end
<%= submit_tag "Next" %>
<% end %>
Now i wanted to apply a jquery where i can select/ deselect the checkboxes.
I can do if its not in the loop straight forward,
I am referring below link for implementation,
link
Loop Output...
How to achieve it...
I would do something like
<%= form_tag some_path, :method => 'post' do %>
For loop
<%= check_box_tag 'ids[]', value, class: 'parent' %> Name
<div class='children'>
For loop
<%= check_box_tag 'ids_of_second_loop[]', value %> Name
end
</div>
end
<%= submit_tag "Next" %>
<% end %>
note that "div class='children'" after the checkbox and the class "parent" on all parent checkboxes
then, javascript
$('input.parent').on('change',function(){
$(this).next('.children').find('input[type=checkbox]').prop('checked',$(this).prop('checked'));
})
it searches the next div with class 'children' after the clicked checkbox, then, it searches all inputs with type=checkbox inside that div, and sets the prop "checked" to the value returned by the current input clicked
Working fiddle :
$("#button").click(function () {
if($("#test")[0].checked)
{
$("#test")[0].checked = false;
}
else
{
$("#test")[0].checked = true;
}
});
http://jsfiddle.net/q8wvv1ky/

Rails: Populate inputs from a select tag in form

I'm running Rails 4 and Ruby 2.
I am creating an app where you can track your calories and macronutrients through each meal you eat.
I'm adding a meal favourites page where the user can add meals they consistently eat. I have done this through a favourites:boolean migration.
When a user creates a new meal I want to show them a drop down box of favourites they have already saved, by something like current_user.meals.where(favourite: true).
When they click on one of their favourites from the drop down I would then like that information to populate the protein, carbs and fat inputs in the form.
What is the best way to do this?
MealsController:
class MealsController < ApplicationController
.
.
.
def new
#meal = current_user.meals.build
end
def create
#meal = current_user.meals.build(meal_params)
respond_to do |format|
if #meal.save
format.html { redirect_to root_path, notice: 'Meal was successfully added.' }
else
format.html { render action: 'new', notice: 'Meal was not added.' }
end
format.js
end
end
.
.
.
private
def set_meal
#meal = Meal.find(params[:id])
end
.
.
.
end
New/Edit Meal Form
<%= form_for(#meal) do |f| %>
.
.
.
<div class="field inline">
<%= f.label :protein %> (g)<br>
<%= f.text_field :protein %>
</div>
<div class="field inline middle">
Carbs (g)<br>
<%= f.text_field :carbohydrates %>
</div>
<div class="field inline right">
<%= f.label :fats %> (g)<br>
<%= f.text_field :fats %>
</div>
<div class="field actions">
<%= f.check_box :favourite, class: "favourites" %> Add to Favourites?
</div>
<div class="actions">
<%= f.submit "Save", class: "btn btn-large" %>
<% if current_page?(edit_meal_path(#meal)) %>
<%= link_to "Delete", #meal, class: "btn btn-large", method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
<% end %>
Thanks!
You can do it with JavaScript/jQuery:
$(document).ready(function() {
bindFavoriteMeal();
});
function bindFavoriteMeal() {
$('#favorite_meal_select').change(function() {
var mealId = $(this).val();
var url = "/meals/" + mealId
$.getJSON(url, function(data) {
$.each(data, function(key, value) {
var field = $("#" + key);
if (field.length) {
field.val(value);
}
});
});
});
}
The show action in your meals controller will have to respond to JSON, and you need to ensure that the form ids match with the JSON keys returned. The JSON could look like:
{ 'name': 'Mustart Salmon', 'protein': 40, 'carbs': 8, 'other_stuff': 'some_value' }
See Rails Controller Overview: Rendering JSON.
The implementation of the select dropdown will depend on what it's for. Is it for associating an item from the dropdown with the object being created? In that case check out the other answer by #jordan-davis. Or is it merely to inform the user of previously made choices? In that case I'd recommend options_for_select. There are a lot of built-in helpers for selects:
ActionView Form Options Helpers
You would populate the dropdown with collection select
<%= collection_select :user, :meal, Meal.all, :id, :name, checked: meal.name.first %>
This code won't cut and paste, but it's to show the idea. After that, you would have to use jQuery to grab the meal id, and then use that to populate the rest of the info. You would start with something along the lines of:
$(".dropdown-menu li a").click(function(){
$(this).parents(".dropdown-menu:first").dropdown('toggle')
var selectedMeal = $(this).text();

Categories

Resources