Disable and enable with checkbox and simple form gem - javascript

I'm trying to disable and enable action with checkbox on the post form.
And I don't know much about javascript or JQuery.
And I'm trying to do this action a lot and I don't how to do it, I'm programming alone.
So if anyone could help me with this, I will appreciate!
I'm using a Rails 4.2.8 and jquery-rails-4.3.1 versions.
my form: app/views/posts/_form.html.slim
= simple_form_for(#post, :html => { :multipart => true }) do |f| = f.input :publish,
label: "Publish?",
as: :boolean,
label_html: { class: "publish-check" },
input_html: { checked: false },
remote: true = f.input :published_at, disabled: true, hint: 'You cannot publish your post.',label: "Publish Post at:"
I'm trying to put this on the fileapp/assets/javascript/_form.coffee it's alright or I need to put on another file?
$(document).on "turbolinks:load", ->
$checkbox = $('[id^="post_publish"]')
$select = $('.post_published_at')
$checkbox.change (e) ->
$select.prop 'disabled', !$checkbox.is(':checked')
return
return
This field published_at it's a date time.
So I think now I need to put some array, the id's generated it's likeid="post_published_at_1i" and until id="post_published_at_5i"

If I understood you right, the only way of doing that is with javascript:
= simple_form_for(#post, :html => { :multipart => true }) do |f|
= f.input :publish, label: "Publish?", as: :boolean, input_html: { checked: false }
= f.input :published_at, label: "Publish Post at", style: "visibility: hidden;"
That will create something like the HTML part below, so, you just need to add the javascript to your page and maybe tweak it a little bit.
window.addEventListener('load', function() {
document.getElementById('post_publish').addEventListener('change', function() {
var input = document.getElementById('post_published_at')
if (this.checked) {
input.style.visibility = 'visible';
input.disabled = false;
} else {
input.style.visibility = 'hidden';
input.disabled = true;
}
});
});
<form id="new_post" action="/post" method="post">
<input id="post_publish" type="checkbox">
<label>Publish?</label>
<input id="post_published_at" style="visibility: hidden;">
</form>

Related

Dynamic dropdown in rails simple_form

I have a simple has_many and belongs_to relationship in my rails app. I'm using simple_form and want to dynamically change the dropdown options based on the value chosen by the user.
Models
class Processor < ApplicationRecord
has_many :processor_bank_accounts
end
class ProcessorBankAccount < ApplicationRecord
belongs_to :processor
end
Form inputs
<%= simple_form_for [#customer, #transaction] do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :status, :collection => ["payment request"], include_blank: false %>
<%= f.input :processor, collection: #processors ,label_method: :name,value_method: :id,label: "Processor" , include_blank: false %>
<%= f.input :processor_bank_account, collection: #bank_accounts , label_method: :bank_name, value_method: :id, label: "Processor Bank Account" , include_blank: true %>
<%= f.input :tcurrency, collection: #currencies, include_blank: false, label: 'currency' %>
<%= f.input :amount, as: :decimal, label: 'amount' %>
</div>
<div class="form-actions text-center">
<%= f.button :submit, "Add transaction", class: "form-button"%>
</div>
<% end %>
So essentially, I need the processor_bank_account dropdown to populate based on the processor chosen by the user. In the console, this would just be: ProcessorBankAccount.where(processor: processor).
Need to load options using JS and think I need to use JSON but not sure where to go from here
One way to do this would be to use jQuery to make an AJAX call to a controller action and then let Rails handle the rest through an erb template.
So on your page, with the form, invoke the action via AJAX using something like:
<script>
$(document).ready(function() {
$('#processor_id').on('change', function() {
$.ajax({
url: '/transactions/get_processor_bank_accounts',
type: 'GET',
data: {
processor_id: this.value
},
dataType: 'script',
error: function() {
alert('An error occurred retrieving bank accounts for the selected processor.');
}
});
});
});
</script>
NB, #processor_id is the id for your dropdown control.
Next, instantiate the bank accounts within your action in your controller:
def get_processor_bank_accounts
#processor_bank_accounts = ProcessorBankAccount.where(processor_id: params[:processor_id])
end
And finally simply create a view that will be responsible for repopulating your dropdown:
$select_list = $('#processor_id');
$select_list.empty();
<% #processor_bank_accounts.each do |pba| %>
$select_list.append($('<option value="<%= pba.id %>"><%= pba.name %></option>'));
<% end %>
I came up with the following solution:
1) Add a new method to my processors controller to render the inputs for the second (dynamic) dropdown in JSON format:
def processor_bank_accounts
render json: #processor.processor_bank_accounts.each do |bap|
{ id: bap.id, name: bap.name }
end
end
2) Assign this new function to a new route in config/routes:
get 'api/bankaccounts', to: 'processors#processor_bank_accounts', as: 'bankaccounts'
3) Create a JS function to access the route with the id of the processor selected in the first dropdown and populate the second dropdown with items from the JSON array:
// select first dropdown
const processor = document.getElementById("transaction_processor");
// select second dropdown
const bapSelect = document.getElementById("transaction_processor_bank_account");
function update_baps(processor_id) {
const url = `INSERTWEBURLHERE/api/bankaccounts?id=${processor_id}`;
fetch(url)
.then(response => response.json())
.then((data) => {
bapSelect.innerHTML = ""; // clear second dropdown
data.forEach((bap) => { // go through all the BAPs
const elem = `<option value="${bap.id}">${bap.bank_name}</option>`; // create option elements to insert into the second dropdown, bank_name is the chosen label method in the form
bapSelect.insertAdjacentHTML("beforeend", elem); // insert options into the dropdown
});
});
}
4) Trigger the JS when the first dropdown field is changed:
processor.addEventListener('change', function () {
update_baps(parseInt(processor.value));
});
You should add an id to the selects so you can identify them form the script.
$('select#processor').on('change', function() {
var processor_id = this.value;
var processor_bank_account = $('select#processor_bank_account')
$.ajax({
type: "GET",
url: <%= your_path %> ,
data: { processor_id: processor_id },
success: function(data, textStatus, jqXHR){
processor_bank_account.empty();
var option = new Option(data.bank_name, data.id, false, false);
processor_bank_account.append(option);
},
error: function(jqXHR, textStatus, errorThrown){...}
})
});

Completing items in ruby on rails 4

I have migrated a :completed boolean, I then added it to my form like so (simple_form)
<%= f.input :completed, as: :boolean %>
This allows me to update completed, not completed in the edit view.
How can I edit the :completed method in my index view? I want to be able to update complete or not complete on the fly.
EDIT:
My Form
<%= f.input :completed, as: :boolean, input_html: { class: 'completed', id: #todo.id } %>
My View (label has to be after input as per materializecss)
<%= check_box_tag todo.id, 'completed', todo.completed?, class: 'completed' %>
<label class="strikethrough">
COMPLETE
</label>
The JS
// This could be other events as well, so add/change/remove the event trigger as needed
$(document).on('click', '.completed', function(){
updateCompleted($(this));
});
function updateCompleted($el) {
var id = $el.attr('id'),
val = $el.is(':checked');
$.PATCH({
url: '/todos/'+id,
data: { todo: { completed: val } },
success: function(){ whatever },
error: function() { whatever }
});
}
My Controller
params.require(:todo).permit(:title, :item, :image, :completed)
You are going to require some AJAX here. In my experience, doing this is a bit outside of the "rails way", but totally possible.
First, make sure you have the ID of the object somewhere in the dom:
<%= f.input :completed, as: :boolean, input_html: { class: 'completed', id: myobject.id %>
I used the simple_form syntax since that's what it appears you are using for your form builder. If not, comment back and I'll adjust the tag.
Secondly, add a jquery event listener:
// This could be other events as well, so add/change/remove the event trigger as needed
$(document).on('click', '.completed', function(){
updateCompleted($(this));
});
function updateCompleted($el) {
var id = $el.attr('id'),
val = $el.is(':checked');
$.PATCH({
url: '/your_endpoint/'+id,
data: { your_object_name: { completed: val } },
success: function(){ whatever },
error: function() { whatever }
});
}
And in your controller:
private
def your_object_params
params.require(:your_object).permit(..., :completed)
end
That's basically it.
Basically you will want to make a post to the update action from the index action. I would use JavaScript but you can also use a hard refresh if you want to stick with rails. Here is a good intro if you are not familiar with using JS in your rails app. http://railscasts.com/episodes/324-passing-data-to-javascript.

Send checkbox value to rails model field

I would like to send the value of my checkbox (true/false) to my rails model field (:taxable) on the state change of that button.
So far I have this, but I am not sure where to go from here
<script>
$(document).ready(function() {
$('.taxable').on('change', function(event) {
var checkbox = $(event.target);
var isChecked = $(checkbox).is(':checked');
/* */
});
});
</script>
<%= f.input :taxable, :as => :boolean, hint: "Is order taxable?",:id => 'taxable', :class => "taxable", :remote => true %>
Try this :
<script>
$(document).ready(function() {
$('.taxable').on('change', function(event) {
var checkbox = $(event.target);
var isChecked = $(checkbox).is(':checked');
$.ajax({
type: "POST",
url: "/url",
data: { params: { taxable: isChecked } },
success:(data) {
alert(data)
return true;
},
error:(data) {
return false
}
})
/* */
});
});
</script>
<%= f.input :taxable, :as => :boolean, hint: "Is order taxable?",:id => 'taxable', :class => "taxable", :remote => true %>

Removed novalidate doesn't validate form

I'm using Zurb Foundation's Abide validations for a form. When I render the form, the form has a novalidate attribute. I removed the attribute with
$('#new_user').removeAttr('novalidate')
I refreshed the page, but still unable to submit. I saw that I should add $('#new_user').validate(), but the didn't work either. Instead it added the novalidate back.
$("#new_user").removeAttr('novalidate')
$( ->
subscription.setupForm()
subscription =
setupFrom: ->
$('#new_user').submit ->
$('input[type=submit]').attr('disabled', true)
if $('#card_number').length
subscription.processCard()
false
else
true
processCard: ->
card =
number: $('#card_number').val()
cvc: $('#card_code').val()
expMonth: $('#card_month').val()
expYear: $('#card_year').val()
Stripe.createToken(card, subscription.handleStripeResponse)
handleStripeResponse: (status, response) ->
if status == 200
$('#subscription_stripe_card_token').val(response.id)
$('#new_subscription')[0].submit()
else
$('#stripe_error').text(response.error.message)
$('input[type=submit]').attr('disabled', false)
)
The beginning of the form
= form_for(resource, as: resource_name, url: registration_path(resource_name), data: {abide: true}) do |f|
= devise_error_messages!
= hidden_field_tag 'plan', #plan
.field
= f.label :name, 'Full name'
= f.email_field :name, autofocus: true, required: true, pattern: 'name'
%small.error
You must enter in your full name
...

Autocomplete with typeahead in rails 3

I'm developing autocomplete for a particular form in my rails app; for this purpose I'm using typeahead.js with custom controller method. So far, it works but I need using those values within the form again so that I can press the submit button and the form will be posted and processed by rails normally. How can I do this? Here's the code right now
.page-header
%h1
= #org.name
%small= t('.title')
= form_for #org_admin, |
url: organization_organization_admins_path(#organization) do |f|
.form-group
= f.label t('.user')
= f.hidden_field :user, id: 'user_id'
%input.typeahead{ :type => "text", :autocomplete => "off"}
= f.submit t('.submit'), class: 'btn btn-primary'
= link_to t('.back'), organization_organization_admins_path(#organization)
:javascript
$(document).ready(function() {
$('input.typeahead').typeahead({
name: 'names',
remote: "#{search_organization_organization_admins_path(#organization)}?term=%QUERY",
engine: Hogan,
template: '<p><strong>{{username}}</strong></p>',
limit: 10
}).on('typeahead:selected', function(e, data){
$('#user_id').value = data.id
});
});
So, I would like to populate the :user attribute in the form with the json object returned by the controller
Nevermind, I figured out... the above code is in the right path, except for the call to this line
$('#user_id').value = data.id
Since I'm using jQuery to select the hidden element I had to use the jQuery val function instead
$('#user_id').val(data.id)

Categories