I'm trying to do a dynamic select, when user select school appear only the groups that belong to that school, but when I tried to change the select I got this error:
Missing partial admin/groups/_group with {:locale=>[:en], :formats=>[:js, :html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}.
CoffeeScript
$(document).on "page:change", ->
$(document).on 'change', '#schools_select', (evt) ->
$.ajax 'update_groups',
type: 'GET'
dataType: 'script'
data: {
school_id: $("#schools_select option:selected").val()
}
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{errorThrown}")
success: (data, textStatus, jqXHR) ->
console.log("Dynamic school select OK!")
HTML
The school belongs to the model of the form, but the group isn't an attribute of the form.
<div class="form-group">
<%= f.label :school %><br>
<%= f.select :school_id, options_for_select(#schools.active.collect { |school|
[school.name.titleize, school.id] }, 1), {}, { id: 'schools_select' } %>
</div>
<div class="form-group">
<%= label_tag :group %><br>
<%= select_tag :group_id, options_for_select(#groups.active.collect { |group|
[group.name.titleize, group.id] }, 1), { id: 'groups_select' } %>
</div>
Javascript
$("#groups_select").empty().append("<%= escape_javascript(render(:partial => #groups)) %>")
Ruby
def update_groups
#groups = Group.where(school_id: params[:school_id])
respond_to do |format|
format.js
end
end
Routes
get 'students/update_groups', as: 'update_groups'
Make your method like below. Also, make sure yr ajax request triggers.
def update_groups
#groups = Group.where(school_id: params[:school_id])
render json: #groups, root: false
end
My error was that I didn't tell what to render and then I was trying to update the select in other file, when it wasn't necessary.
This is the updated code
CofeeScript
$(document).on "page:change", ->
$(document).on 'change', '#schools_select', (evt) ->
$.ajax 'update_groups',
type: 'GET'
dataType: 'script'
data: {
school_id: $("#schools_select option:selected").val()
}
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{errorThrown}")
success: (data, textStatus, jqXHR) ->
groups = JSON.parse(data)
$.each groups, (index) ->
$('#groups_select').empty().append $('<option></option>').attr('value', groups[index].id).text(groups[index].name)
return
Ruby
def update_groups
#groups = Group.where(school_id: params[:school_id])
respond_to do |format|
format.json { render json: #groups }
end
end
I delete the javascript file.
Related
<%= form_for(#mymodel, remote: true, html: { id: 'match_form' }) do |f| %>
<!-- I need to check if #mymodel.match_id matches the value generated by a controller function -->
<%= f.submit 'Save', class: 'btn btn-primary', id: 'match_submit', style: "width:38px;padding:0px" %>
<%= button_tag 'Cancel', class: 'btn btn-secondary', id: 'match_cancel', style: "width:52px;padding:0px" %>
<% end%>
<script type='text/javascript'>
$(function() {
$(document).on("click", "#match_submit", function(event){
$.ajax('my_controller_method', {
type: 'GET',
dataType: 'script',
data: {
mid: $("#").val(), // how do I pass #mymodel.match_id here?
},
error: function(jqXHR, textStatus, errorThrown) {
return console.log("AJAX Error: " + textStatus);
}
});
});
</script>
I have a Rails form that represents a model as shown above.
How can I access attributes of the model inside the JavaScript code block shown above?
You can use erb inside of javascript too:
mid: <%= #mymodel.match_id %>,
Or you can serialize your object with gon gem (https://github.com/gazay/gon)
I think I've got complicated problem but let's keep it simple. I'm using devise and I want to show error message below form in my login page. Right now when user provide wrong password in console I've got an error POST 401 (Unauthorized) but errors didn't showed up in a page.
slice_code.js.erb
$(document).ready(function() {
var form = $('.centralized-login')
form.submit( function(event) {
event.preventDefault()
var email = $('#email-input').val()
var password = $('#password-input').val()
var req = $.ajax('/user_role', {
data: {
email
}
})
req.then( function(result) {
var { role } = result
switch (role) {
case 'company_manager':
$.ajax('/users/sign_in', {
method: "POST",
data: {
"user[email]": email ,
"user[password]": password,
"authenticity_token": $('input[name="authenticity_token"]').val()
},
success: function(data, textStatus, req){
window.location="/users/sign_in"
}
})
break;
should I add something like $("ajax:error") ?
_new.html.erb
<div class="col-sm-8 col-md-6 col-xs-12">
<div class="vr-textfield-wrapper">
<%= f.email_field :email, id: "email-input", class: "vr-textfield", placeholder: t('users.passwords.new.email_placeholder'), required: true, aria_required: true, autofocus: true %>
<span class="vr-field__invalid-msg"><%= t 'users.passwords.new.valid_email'%></span>
<% if resource.errors.full_messages_for(:email).first %>
<div class="vr-textfield-wrapper">
<div class="alert alert-danger">
<div class="error-explanation">
<%= t('activerecord.errors.models.user.attributes.email.not_found_in_database') %>
</div>
</div>
</div>
<% end %>
</div>
</div>
Edit
success: function(data, textStatus, req){
window.location="/users/sign_in"
},
error: function (jqXHR, textStatus, errorThrown) {
$('.centralized-login').find('.error-explanation').html(errorThrown)
console.log(textStatus + " " + errorThrown);
}
})
sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
include LogoutUsergroups
def after_sign_out_path_for(_user)
new_user_session_path
end
end
You can render the error in the js response(create.js.erb) of view file itself. something like below,
<%- if resource.errors.any? %>
var id = $('form#Id') <!-- Replace with your selector -->
<% resource.errors.each do |key, value| %>
id.find('selector').html("<%= "#{key.to_s.humanize} #{value}" %>");
<% end %>
<%- end %>
Or you could use the error function as like you used the success function,
$.ajax({
success: function(data, textStatus, req){
window.location="/users/sign_in"
}
error: function (jqXHR, textStatus, errorThrown) {
id.find('selector').html(""); # Use the error here to show in the UI.
console.log(textStatus + " " + errorThrown);
}
});
$("ajax:error") should be used when using the remote: true for form submit. For reference: https://github.com/rails/jquery-ujs/wiki/ajax
Im trying to use jquery to get a controller action which shows a pdf page. Before the javascript way, the rails way worked:
Show.html.erb
<%= link_to "Get PDF", client_path(#client.id, format: :pdf) %>
The issue is, I need some params that I get from javascript so a work around was to use ajax to make the request:
js:
$.ajax({
url: "/clients/" + clientId + ".pdf",
type: 'POST', // Ive also tried GET and created a post route in routes.rb
data: { //...
},
success: function(data, xhr) {
//...
console.log('Success.....');
},
error: function() {
console.log("Error....")
}
});
Controller:
respond_to :html, :xml, :json
def show
respond_with do |format|
format.pdf do
render pdf: "demopdf",
template: "clients/show.pdf.html.erb",
locals: {:client => #client}
end
end
end
If I click my rails button, I get the pdf view but not so with a normal button with a button click function. How to do this with ajax? I got the success log but that's it.
EDIT:
How to get Bar to my controller? I need to have Bar in my pdf?
show.html.erb:
<p id="foo"></p>
js:
$("#foo").text("Bar");
So basically I need to pass few params in:
<%= link_to "Get PDF", client_path(#client.id, format: :pdf) %>
If you need to send the parameters, you can do so by adding params in your route code.
<%= link_to "Get PDF", client_path(#client.id, format: :pdf, params1: 'some param', params2: 'other param2' ...) %>
If you need to use the ajax for the link, the add
remote: true in there as well.
I'm getting bad request error 400 using Ajax on Rails.
When i submit my form I have a string to send as parameter from Jquery and i want to retrieve it from params[:assignee] so i can extract the string and save it through my controller.
My controller:
def create
#task = Task.new(task_params)
#task.user = current_user
username = params.permit[:assignee]
#task.assignee = username
#set_category
respond_to do |format|
if #task.save
format.html { redirect_to tasks_url, notice: 'Task was successfully created. '+task_params.inspect}
#format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def task_params
params.require(:task).permit(:owner, :value, :completed, :category, :date, :assignee)
end
And this is my JS:
$( "#new_task" ).submit(function() {
alert("form: "+assignee);
//event.preventDefault();
$.ajax({
url: "/tasks",
type: "POST",
data: {assignee},
dataType: "json",
success: function(data) {
alert('successfully');
},
error: function(xhr, textStatus, error) {
alert(xhr.statusText+""+textStatus+""+error);
}
});
});
assignee is an username selected in a jquery auto-complete form:
select: function(event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join("");
assignee=this.value;
$('input[name=commit]').prop("disabled",false);
return false;
}
My root is "task/" where you can see saved tasks and a form to create a new one.
I searched a lot on the net and I tried them all. How can I do? Thanks so much
400 Bad Request - The server cannot or will not process the request due
to an apparent client error (e.g., malformed request syntax, too large
size, invalid request message framing, or deceptive request routing).
wiki
Change the ajax code to:
$.ajax({
url: "/tasks",
type: "POST",
dataType: "json",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), // Optional
'Content-Type': 'application/json'
},
data: JSON.stringify({ assignee: assignee }),
success: function(data) {
alert('successfully');
},
error: function(xhr, textStatus, error) {
alert(xhr.statusText+""+textStatus+""+error);
}
});
{assignee} that's a not valid JSON object it should be {assignee: assignee}
Also you should add a valid headers, The 'Content-Type' and (X-CSRF-TOKEN optional)
Solved!
$( "#new_task" ).submit(function(event) {
alert("form: "+assignee);
var value = $('#new_task').find('input[name="task[value]"]').val();
event.preventDefault();
$.ajax({
url: "/tasks",
type: "post",
contentType: "application/json",
data: JSON.stringify({ assignee: assignee, value: value }),
success: function(data) {
alert('successfully');
},
error: function(xhr, textStatus, error) {
alert(xhr.statusText+" "+textStatus+" "+error);
}
});
});
event.preventDefault(); --> without this, the form is submitted twice.
var value = $('#new_task').find('input[name="task[value]"]').val(); --> without this, i could lose my form value because of "post tasks" that reminds to task#create
I'm calling an AJAX function from a select_tag like so:
<%= select_tag 'quantity', options_from_collection_for_select(order.options), :quantity, :quantity, order.quantity), onchange: "update_price(#{order.id}, this.value);" %>
And here's the function:
<script type='text/javascript'>
function update_price(order_id, quantity) {
$.ajax({
url: "/cart/" + <%= #cart_transaction.id %> + "/update_quantity",
type: "POST",
data: {
"order_id" : order_id,
"quantity" : quantity },
dataType: "html"
});
}
</script>
My .js.erb isn't called ever, and I suspect it's because I haven't specified remote: true anywhere, but since I don't have a form per se I don't know how to do that. Any help?
Relevant controller code here:
class CartTransactionsController < ApplicationController
load_and_authorize_resource
respond_to :html, :js
before_filter :set_cart_transaction
def update_quantity
#order = #cart_transaction.orders.find(params[:order_id])
#price = current_user.brand.prices
.where(template_id: #order.document.template.id)
.where(quantity: params[:quantity]).first
#order.update_attributes(
price_cents: #price.amount_cents, quantity: params[:quantity]
)
#cart_transaction.save!
respond_to { |format| format.js }
end
private
def set_cart_transaction
#cart_transaction = current_user.cart
end
def cart_transactions_params
params.require(:cart_transaction).permit(
:name, :email, :delivery_address, :comments
)
end
end
Update
Here's the .js.erb that isn't called for some reason:
console.log("update_quantity.js.erb file");
$('#price_cell').html("<%= j render(partial: 'price', locals: { order: #order }) %>");
$('#subtotals').html("<%= j render(partial: 'subtotals', locals: { cart_transaction: #cart_transaction }) %>");
Try this:
function update_price(order_id, quantity) {
$.ajax({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
},
url: "/cart/" + <%= #cart_transaction.id %> + "/update_quantity",
type: "POST",
data: {
"order_id" : order_id,
"quantity" : quantity }
});
}
Use dataType: "script", it will work and will render js.erb