How to reject Rails update method and trigger JavaScript alert box? - javascript

I've update method inside my controller:
def update
if #daily_order.update(daily_order_params.merge({default_order:false}))
respond_to :js
else
render :edit
end
end
I've pax as one of the params inside the daily_order_params and what I'm trying to do now is, I want to show a JS alert when user is trying to update a daily order with zero (0) pax value.
I try to use byebug inside that update method to check params[:pax] but it returns nothing. It's blank.
But the newly updated pax value was saved successfully inside the database.
I try to use before_update inside my model, but I didn't know how to move forward.
before_update :reject_zero_pax_order_update
def reject_zero_pax_order_update
# i got stucked here
end
update.js.erb
console.log("record updated");
What should I do to:
Reject the update if the entered pax is 0
Trigger a JS alert box if the entered pax is 0
Maintain the old pax inside the database

The :pax attribute is inside the :daily_order hash not inside the params hash.
Your params looks something like this:
{ daily_order: { pax: 0 }}
hence you should access it with params[:daily_order][:pax]
Your action should look something like this :
unless params[:daily_order][:pax] == 0
#daily_order.update(daily_params.merge{default_order: false} )
respond_to :js
else
render :edit
end
#update.js.erb
alert('hey, the pax cant be 0 ');
I am assuming, you want the update to take place only when the pax is present else show the alert.

For displaying alert box for pax value can't be equal to 0, you need to add id or class on both update button and pax field. Also you have to add hidden field for getting id of current daily order which is to be updated.
# Add hidden field:
<%= hidden_field_tag "daily_order_id", #daily_order.id %>
# Add id on pax field:
<%= f.text_field :pax, id: 'daily_order_pax' %>
# Add id on update button:
<%= f.submit 'Update', id: 'update_daily_order' %>
Then add following code in js file:-
$(document).on('click', '#update_daily_order', function(event) {
event.preventdefault();
var id = $('#daily_order_id').val();
var pax_value = $('#daily_order_pax').val();
if (pax_value == 0) {
alert("pax value can't be equal to 0");
}else {
$.ajax({
type: 'PUT',
url: '/daily_orders/' + id
data: $('#form_id').serialize();
});
}
});
Above ajax will call only when pax value is not equal to 0

Related

How to send a selected element and a text input via jQuery

My app has a live search implemented and it works properly. The problem that I have is that now I have a table with a lot of columns and I want to search through all elements. I want to have only one text input and a drop down that will select the column that I want to search in.
Searchable module
module Searchable
extend ActiveSupport::Concern
module ClassMethods
def search_for(present_column,record)
record.present? ? where(present_column+' LIKE ?', record+"%") : all
end
end
end
People controller
class PeopleController < ApplicationController
def index
#people = Person.page(params[:page]).per(5).search_for(params[:object_columns], params[:search])
end
The search engine
<%= form_tag do %>
<% valid_column_names = target.column_names.reject{|r| r == "created_at" || r == "updated_at" || r == "slug"} %>
<%= select_tag :object_columns, options_for_select(valid_column_names) %>
<%= text_field_tag :search, '', autocomplete: :off %>
<% end %>
The live search js
$(function () {
$("input#search").keyup(function () {
$.get($("#object_columns option:selected").text(), $("#object_columns").serialize(), null, "script");
$.get($("#search").attr("action"), $("#search").serialize(), null, "script");
});
});
The input text is returned as expected, but nothing comes from the object_columns. When I type the word "n", for example, my server terminal returns this message:
Started GET "/people?&search=n&_=1463081307356" for 127.0.0.1 at 2016-05-12 16:28:34 -0300
Processing by PeopleController#index as JS
Parameters: {"search"=>"n", "_"=>"1463081307356"}
EDIT:
I had an idea later on and made some changes. I gave the form an ID and used it to do the request, now I can have both information (column names and the search record) at the same time. The only problem now is with the path, it is returning an URI error.
The search engine
<%= form_tag people_path, class: "form_id" do %>
<% valid_column_names = target.column_names.reject{|r| r == "created_at" || r == "updated_at" || r == "slug"} %>
<%= select_tag :object_columns, options_for_select(valid_column_names) %>
<%= text_field_tag :search, '', autocomplete: :off %>
<% end %>
The live search
$(function () {
$("input#search").keyup(function () {
$.get($(".form_id"), $(".form_id").serialize(), null, "script");null, "script");
});
});
In your search_for method, the return value is always all. You really want the return value to be the result of the ternary operator directly above it. Remove the last all and you should be good to go.
module ClassMethods
def search_for(present_column,record)
record.present? ? where(present_column+' LIKE ?', record+"%") : all
# all <== this should be removed
end
end
In your javascript, you'll need a few changes:
$(function () {
function search() {
$.get("/search", { column_name: $("select#column_name").val(), search: $("#search").val() }, null, "script");
};
$("select#column_name").change(search);
$("input#search").keyup(search);
});
The actual Ajax call has been changed to:
remove the undefined "action" attribute on the search input field
explicitly reference the URL to send the request
create hash parameters for the ajax call
remove the unnecessary calls to serialize()
This also installs a handler on the change event of the column selection, hence the refactoring of the Ajax call to a separate function.

calling .val() on date_select element returning undefined?

I'm trying to obtain the selected date from a date_select:
<%= form_for(#newevent) do |f| %>
<%= f.date_select :day, { id: "date-select"} %>
<button id="check-button" type="button">Check</button>
<% end %>
using JQuery/Javascript:
$(document).on('click', "#check-button", function(){
var selectedDate = $("#date-select").val();
alert(selectedDate);
var checkList = []; //creates array to store customer ids
$("#check-list li input").each(function(){ //for each listed colleague...
if( $(this).is(":checked")){ //if check-box is ticked
checkList.push($(this).val()); //add id to list
}
});
$.ajax({
url: '/events/check',
data: {checkList: checkList , selected_date: selectedDate },
method: "POST"
}
);
});
for reference here is where :day is defined in my migration file:
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.timestamps
t.references :calendar, foreign_key: true
...
t.date :day
...
end
However, on alert the returned value is "undefined". Why is this happening? I would like it to return the a value in the form YYYY-MM-DD. Apologies if this is obvious, but I am new to programming and can't seem to fix this one myself
Date_select, according to the rails api "Returns a set of select tags (one for year, month, and day)". Your javascript is going to have to deal with three separate selects and construct a date from them. Look at your generated HTML to get the id's.

Chose a course using f.select and automatically entered into the field count_stud value

There is a form in which we choose the year and course. Another field is not visible (it should change the number of students, which corresponds to the selected course).Сhose a course using f.select and automatically entered into the field count_stud value equal to the number of students on this course. How to do this? Probably need JavaScript (Ajax technology)
Using ajax you can do this,
change your select like below
<%= f.select(:course_id, #courses.map{|p| [p.id]},{},{:class => "course_id"}) %>
year:
<%= f.select(:year_id, #years.map{|p| [p.name, p.id]} ,{},{:onchange => "update_student(this.value)"}) %>
text box:
<%= f.text_field :count_stud, :value => #student_count,:class => "student" %>
in ajax code:
function update_student(year) {
var course = jQuery(".course_id").val(); // finding course value
if(course == ""){ // checking course value being selected or not
alert("Please select course ");
return false;
}
jQuery.ajax({
url: "update_student",
type: "GET",
data: {"course_id" : course,"year": year },
dataType: "text",
success: function(data) {
jQuery(".student").val(data); // inserting response to text field.
}
});
}
so,onchange of the course select box one ajax request will go with year and course value,then in your action you get the values in params and find the no of student and return like
in YearCoursesController
def update_student
year = params[:year]
course = params[:course]
#write logic to find student
#assign in one variable
year_courses = YearCourse.find_by(year_id: year, course_id: course)
student_count = year_courses ? year_courses.students.count : 0
render :text => student_count #we are returning the value
end
then that value will insert to the text box.

Rails 4 / Ruby 2: Local variable (FormBuilder) for partial is lost through dynamic update

I have this form that renders a partial for selecting a person's task.
new.html.slim:
= form_for(#person) do |f|
= f.text_field :name
= f.fields_for :assignment do |a|
= a.collection_select :project_id, Project.order(:name), :id, :name
div id="task_list"
= render 'shared/_task_select', a: a
= f.submit 'Save'
shared/_task_select.html.slim:
= a.collection_select :task_id, #tasks, :id, :name
Changing the project triggers a javascript that runs a "create_tasklist"-method in the PersonsController.
new.js:
$(document).ready(function() {
$('#person_assignment_attributes_project_id').change(function() {
var selection = $('#person_assignment_attributes_project_id').val();
$.ajax({
url: "/create_tasklist",
data: {
project_id : selection
},
dataType: "script"
});
});
});
The "create_tasklist"-method triggers a javascript that updates the partial:
create_tasklist.js.erb:
$("#task_list").html("<%= escape_javascript(render 'shared/task_list', a: a) %>");
Now this raises the error:
undefined local variable or method `a' for #<#<Class:0x42cd770>:0x4213ef0>
The same form works well when editing existing persons - until changing the project. Thus, FormBuilder "a" loses its definition through the javascript actions. I have to use a partial here because I want to do more stuff with it in a later stage. Any ideas how to get that variable to keep its defintion?
Edit 1:
I already tried adding this below the third line of new.html.slim:
javascript:
var a = "#{a}";
and then adding: a: a in the "data" declaration of new.js.
Edit 2:
With this the FormBuilder seems to pass through until the "create_tasklist"-method, but I do not know how to access it properly there. If I declare ´#a = params[:a]´ in the "create_tasklist"-method and then use (in create_tasklist.js.erb):
$("#task_list").html("<%= escape_javascript(render 'shared/task_list', a: #a) %>");
I recieve the error:
undefined method `collection_select' for "#<ActionView::Helpers::FormBuilder:0x4760400>":String
So the FormBuilder has become a string but a least it "got through" somehow. How can I leave it intact and is a more efficent way to achieve this?

Rails Updating a DIV (with reload from model) after a javascript call

OK, I have a page which shows the customer how many Widgets he has. Here's the view (haml):
#available
= "Available widgets: #{#customer.widgets.unused.count()}"
("unused" is a scope in the model showing the available widgets).
When Customer redeems Widgets with a form with ":remote => true", some javascript places a nice DIV on the page with animation and the model is updated by the controller.
Here's the controller:
def redeem
#customer = Customer.find(params[:customer_id])
number = params[:amount].to_i
unless #customer.widgets.unused.empty?
number.times do
#customer = Customer.find(params[:customer_id])
widget = #customer.widgets.unused.first # Grab first unused pass
widget.status = "Redeemed"
widget.save!
end
else
#pay = "true"
# customer.widgets.new
end
# redirect_to #customer
end
And here's the javascript (js.erb):
var number = <%= params[:amount] %>;
<% if #pay.eql? "true" %>
$("#widget-pay").modal('toggle');
<% else %>
while (number > 0) {
var item = $('<div class="widget-show">...</div>');
$('#allwidgets').isotope('insert', item);
number --;
}
<% end %>
My problem is I now want to update the "#available" DIV with the new Widget count. How do I do this?
At worst I could reload the page so the data is pulled from the model again, at best just update the DIV. Neither which I seem to be able to do from the javascript.
You can do something like this:
render :js => "$('#available').append(widget)"
widget.save!

Categories

Resources