I've Rails 4.0 application with 'order' model which has a status field. While invoking a 'show' action to get 'order' object details, I want to add additional buttons on the 'Show page', in addition to 'Edit' and 'Back'. First one to mark 'update status' which will only update status of this order object to '1' and the second button to mark 'close order' which will only update status of this order object to 2. How can I achieve this without an 'Edit' action/view? Do I need to use form_tag to add these buttons and do I need to write 2 new methods in OrdersController to update the status?
Following is my show.html.erb with two buttons I want add...
<p>
<strong>Name:</strong>
<%= #order.name %>
</p>
<p>
<strong>Status:</strong>
<%= #order.status %>
</p>
<%= link_to 'Edit', edit_order_path(#order) %> |
<%= link_to 'Back', orders_path %> |
<%= link_to 'Shipped', '#', :name => 'shipped_button' %> |
<%= link_to 'Close', '#', :name => 'close_button' %>
If I click on 'Shipped' or 'Close' button they both will be called on to 'OrdersController' as a 'GET' request as shown below,
..
Started GET "/orders/1?name=shipped_button" for 127.0.0.1 at 2014-11-21 15:40:38 -0800
Processing by OrdersController#show as HTML
Parameters: {"name"=>"shipped_button", "id"=>"1"}
Order Load (0.1ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 1]]
Rendered orders/show.html.erb within layouts/application (1.9ms)
Completed 200 OK in 50ms (Views: 47.8ms | ActiveRecord: 0.1ms)
How can I update the model with appropriate status field update. 'status' is an integer field in the 'orders' model.
I would do that with ajax:
You need something like that in your routes.rb file.
resources :orders
orders/show.html.erb:
<div id="order" data-order-id="<%= #order.id %>"></div>
<p id="notice"><%= notice %></p>
<p>
<strong>Status:</strong>
<%= #order.status %>
</p>
<p>
<strong>Name:</strong>
<%= #order.name %>
</p>
<%= link_to 'Edit', edit_order_path(#order) %> |
<%= link_to 'Back', orders_path %>
<%= link_to 'Shipped', '',id: "ship" %> |
<%= link_to 'Close', '', id: "close" %>
<script>
$(function () {
var orderId = $('#order').data("order-id");
var shippButton = $('#ship');
var closeButton = $('#close');
alert(orderId);
closeButton.on("click", function() {
$.ajax({
url: '/orders/'+orderId,
type: 'PATCH',
dataType: 'json',
data: {"order": { "status": "4"}},
complete: function (jqXHR, textStatus) {
// callback
},
success: function (data, textStatus, jqXHR) {
// inform user that it was a sucess like:
alert("successfully changed the order to closed");
},
error: function (jqXHR, textStatus, errorThrown) {
// do something if the request fails
}
});
});
shippButton.on("click", function() {
$.ajax({
url: '/orders/'+orderId,
type: 'PATCH',
dataType: 'json',
data: {"order": { "status": "3"}},
complete: function (jqXHR, textStatus) {
// callback
},
success: function (data, textStatus, jqXHR) {
// inform user that it was a sucess like:
alert("successfully changed the order to shipped");
},
error: function (jqXHR, textStatus, errorThrown) {
// do something if the request fails
}
});
});
});
</script>
Related
Got a partial view successfully interacting with my coffee script. Collection_Select change triggers script & resulting value is correct, Controller does hit def new successfully.
Only question remaining is how to access the results of the coffee script in the controller.
Partial View:
<% #modName = locals[:moduleName] %>
<% #id = locals[:id] %>
<%= form_with url: admin_command_path() do |f| %>
<%= collection_select(:refcode, :Code, Command.where(FLD: #modName), :Code, :Definition, options ={prompt: true}) %>
<br /><br />
<button class="btn_new">
<%= link_to "Execute", new_admin_command_path(mod: #modName, id: #id) %>
</button>
<% end %>
Coffee Script:
get_SubModule = ->
$('#refcode_Code').change (e) ->
com_value = $('#refcode_Code').val()
console.log 'COFFEEE IS LIFE', com_value
str = $('#refcode_Code :selected').text()
data: {sub_mod_str: com_value}
return
return
So now what.
ActiveAdmin.register Command do
def new
[need to access sub_mod_str here however possible]
end
I think when you Change value you need call Ajax and request controller
get_SubModule = ->
$('#refcode_Code').change (e) ->
com_value = $('#refcode_Code').val()
console.log 'COFFEEE IS LIFE', com_value
str = $('#refcode_Code :selected').text()
data: {sub_mod_str: com_value}
$.ajax(
type: 'POST'
url: your_url
data: data
dataType: 'json'
success: (data) =>
console.log(data)
error: (er) =>
console.log(er)
)
return
return
Controller
def new
byebug // check params
end
I need in my app to select from a list of provider a provider, and then, via ajax, I could see below a list of categories, that belongs to a specific provider. I have a form in activeadmin:
<%= semantic_form_for [:admin, #game], builder: ActiveAdmin::FormBuilder do |f| %>
<%= f.semantic_errors :state %>
<%= f.inputs do %>
<%= f.input :categorization_id, label: 'Provider', as: :select,
collection: Provider.all.map { |provider| ["#{provider.name}", provider.id] },
input_html: { class: (:provider_select), 'data-url': category_select_path(provider: 4) } %>
<%= f.input :categorization_id, label: 'Category',input_html: { class: ('category_dropdown') }, as: :select,
collection: Category.all.map { |category| ["#{category.name}", category.id]}%>
...
<% end %>
<%= f.actions %>
<% end %>
In activeadmin controller I have:
controller do
def ajax_call
#provider = Provider.find(params[:provider])
#categories = #provider.categories
respond_to do |format|
format.json { render json: #categories }
end
end
end
JS:
$(document).on('ready page:load', function () {
$('.select.input.optional').last().addClass('hidden_row');
$('#game_categorization_id').change(function () {
var id_value = this.value;
$('.hidden_row').removeClass('hidden_row');
$.ajax({
type: 'GET',
url: '/admin/games/category_select'
// data: id_value
})
});
});
And the routes: match '/admin/games/category_select' => 'admin/games#ajax_call', via: :get, as: 'category_select'
I don't have an idea, how can I pass providers id from collection into url. Currently, I have there category_select_path(provider: 4), but actually it has to be smth. like this - category_select_path(provider: provider.id) In the browser, in a Network tab of devtools I can see my category_select, but there is an error: Couldn't find Game with 'id'=category_select. I can't figure out from where does it come. Any suggestions? Thanks.
The problem was in routes: match '/admin/games/category_select' => 'admin/games#ajax_call', via: :get, as: 'category_select'. It is reserved by a show action of Activeadmin controller. So I changed my routes to: get '/admin/select_category' => 'admin/games#get_providers_categories', as: 'select_category', and added to ajax call data: {provider: provider}, so I could fire in params id of provider:
$.ajax({
type: 'GET',
url: '/admin/select_category',
data: {
provider: provider
},
success: (function (data) {
$('#select_category').children('option').remove();
$('#select_category').prepend('<option value=""></option>');
$.each(data.categories, function () {
$('#select_category').append('<option value="' + this.id + '">' + this.name + '</option>')
})
})
})
I have this simple code which I submit using ajax request
<%= form_for(#category) do |f| %>
<% if #category.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#category.errors.count, "error") %> prohibited this category from being saved:</h2>
<ul>
<% #category.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :enabled %><br>
<%= f.check_box :enabled %>
</div>
<div class="actions">
<%= f.submit "Create Category", :id => "submit__my_form" %>
</div>
<% end %>
<script type="text/javascript">
$(document).on('click', '#submit__my_form', function(event) {
event.preventDefault();
console.log($('#new_category').attr('action'));
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: $('#new_category').attr('action'),
data: $("#new_category").serialize(),
// data: {name: "my name"},
dataType: "json",
processData: false,
contentType: false,
success: function (result) {
return false
},
error: function () {
window.alert("Something went wrong! Please try again");
}
});
});
</script>
I get this error after I submit the form
Started POST "/categories" for 127.0.0.1 at 2015-12-01 16:15:57 +0100
Processing by CategoriesController#create as JSON
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 5]]
Completed 400 Bad Request in 34ms (ActiveRecord: 0.4ms)
ActionController::ParameterMissing (param is missing or the value is empty: category):
app/controllers/categories_controller.rb:73:in `category_params'
app/controllers/categories_controller.rb:28:in `create'
in the log it point out these two lines as error, line 73
def category_params
78: params.require(:category).permit(:name, :enabled, :user_id)
end
and line 28
def create
28: #category = current_user.categories.build(category_params) # Category.new(category_params)
respond_to do |format|
if #category.save
format.html { redirect_to #category, notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: #category }
else
format.html { render :new }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
How can I solve this problem? I found many solution on internet but it is not working for me. I think I am missing something in ajax call.
Looks like you're missing the category parent key in the params. Since you're using strong params, category_params is expecting something like {category: { name: 'blah', enabled: true }}, but most likely getting { name: 'blah', enabled: true }. Check the logs to see which parameters are passed to your create action.
I would use the remote option for submitting your form since calling serialize() on the form data doesn't play nicely with strong params.
First, change your form_for to: <%= form_for(#category, remote: true) do |f| %>
Then, a more Rails-friendly Ajax submit:
$(document).ready(function() {
$("#new_category").on("ajax:success", function(e, data, status, xhr) {
return false;
}).on("ajax:error", function(e, xhr, status, error) {
window.alert("Something went wrong! Please try again");
});
});
You can find more info in the Rails docs on unobtrusive Javascript.
You missed the right content type application/x-www-form-urlencoded; charset=UTF-8, try this ajax call instead (comment line contentType: false too):
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
url: $('#new_skill').attr('action'),
data: $('#new_skill').serialize(),
//data: {name: "my name"},
dataType: "JSON",
processData: false,
//contentType: false,
success: function (result) {
alert(result);
},
error: function () {
window.alert("Something went wrong! Please try again");
}
});
I have a remote form that is populated by jQuery with an AJAX request. Then, I am binding this form to an AJAX callback but the callback is not being triggered.
var msgSuccess=function(evt, data, status, xhr){
alert('ok!!!');
console.log(evt);
console.log(data);
console.log(status);
console.log(xhr);
}
var bindMsg = function() { // BIND IT TO THE CALLBACKS
$("#composeMsgPopup")
.live('ajax:beforeSend', loadingCallback)
.live('ajax:success', msgSuccess)
.live('ajax:error', failureCallback)
.live('ajax:complete',completeCallback);
}
$.ajax({ // GETTING THE FORM CODE
url: link,
type: "get",
success: function(response, textStatus, jqXHR) {
ans=response;
$("#popup_content").html(ans);
$("#popup").bPopup();
bindMsg();
},
error: function(jqXHR, textStatus, errorThrown) {
failureCallback(errorThrown, textStatus, jqXHR);
},
complete: function(jqXHR, textStatus) {
completeCallback("", jqXHR, textStatus);
},
beforeSend: loadingCallback
});
The code for the form:
<%= form_for(:conversation, :remote => true,
:url=> {:controller=>:conversations,:action=>:create},
:html=>{:id => 'composeMsgPopup' }) do |f| %>
<div id="founder-name" class="field"><b>Recipient: <%= #user.name %></b></div>
<div class="field">
<%= f.label :subject,"Subject" %>
<%= f.text_field :subject,:class=>"composeMsgField" %>
</div>
<div class="field">
<%= f.label :content,"Message Content" %>
<%= f.text_area :content,:class=>"composeMsgField" %>
</div>
<%= f.hidden_field :to_user, :value => #user.id %>
<%= f.submit "Send", :class=>"submitbt",:id=>'sendMessage' %>
<% end % >
I have tried to bind with bind() or on() but it does not work. The code is executed but when I submit the form the callback is not executed.
ok i found a solution.
the remote form not triggering the callback for unknown reason, so what i did is change the
submit button behaviour:
<%= f.button :submit, "Update",:class=>"submitbt",:id=>"submitnewpass",:onclick=>"return false;" %>
and bind the button to manually submit the form
var action=$('#composeMsgPopup')[0].action; // action url
$("#sendMessage").click(function() { // bind submit button
$.ajax({
type: "POST",
url: action,
data: $("#submitnewpass").serialize(), // serializes the form's elements.
success: function(data)
{
// do my stuff
},
error: failureCallback,
beforeSend: loadingCallback,
complete: completeCallback
});
return false;
});
I am trying to pass some parameters from my view via an AJAX call to a custom method fetch_info in my photos controller. My controller does not seem to be receiving the parameters. When I click on an image to initiate the AJAX call, I see the following in my terminal:
Processing by PhotosController#fetch_info as JSON
Parameters: {"id"=>"", "secret"=>""}
Completed 500 Internal Server Error in 267ms
FlickRaw::FailedResponse ('flickr.photos.getInfo' - Photo not found):
app/controllers/photos_controller.rb:38:in `fetch_info'
It looks like the fetch_info method is being called, but the parameters are empty. How should I be passing in my parameters through AJAX?
Here is my view. I also have my javascript in the view for the purpose of just getting this to work.
index.html.erb
<div class="body_container">
<div id="photos_container">
<% #photos_array.each do |p| %>
<%= link_to '#' do %>
<div class='each_photo_container', id='<%="#{p[:id]}"%>' >
<%= image_tag p[:s_url] %>
</div>
<% end %>
<!-- Load Modal onClick -->
<script type="text/javascript">
jQuery(function() {
$('#<%=p[:id]%>').click(function (e) {
//ajax call to fetch photo info
var fetch_id = '<%=p[:id]%>';
var fetch_secret = '<%=p[:secret]%>';
$.ajax({
type: 'GET',
url: '/photos/fetch_info',
dataType: 'json',
data: { 'id' : fetch_id.val(), 'secret' : fetch_secret.val() }
});
return false;
});
});
</script>
<% end %>
<div class="basic_modal">
</div>
</div>
</div>
Here is my photos_controller.rb:
def fetch_info
puts params[:id]
puts params[:secret]
info = flickr.photos.getInfo(:photo_id => params[:id], :secret=> params[:secret])
end
You can use this code:
$('##{p[:id]}').click(function (e) {
//ajax call to fetch photo info
var fetch_id = '#{p[:id]}';
var fetch_secret = '#{p[:secret]}';
$.ajax({
type: 'GET',
url: '/photos/fetch_info',
dataType: 'json',
data: { 'id' : fetch_id, 'secret' : fetch_secret }
});
return false;
})