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;
});
Related
I followed this tutorial to implement drag and drop. https://www.driftingruby.com/episodes/drag-and-drop-with-hotwire
I am getting an error on drop that says Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'dataset'). Any thoughts on why this is happening?
Project model:
acts_as_list scope: :project
_project.html.erb
<div id="projects" data-controller="position">
<%= content_tag :div, data: { sgid: project.to_sgid_param, id: "#{dom_id project}" }, class: 'table-row' do %> <div><%= project.name %> </div>
<div><%= project.description %> </div>
<div><%= project.status %> </div>
<div><%= project.user.email %> </div>
<div class="flex justify-end">
<%= link_to "View", project_path(project) , data: {turbo: false} %>
<%= button_to "Delete", project, method: :delete, form: {data: {turbo_confirm: "Are you sure?"}} %> </div>
</div>
<% end %>
</div>
position_controller.js
import { Controller } from "#hotwired/stimulus";
import Sortable from "sortablejs"
import { put, get, post, patch, destroy } from "#rails/request.js"
export default class extends Controller {
connect() {
this.sortable = Sortable.create(this.element, {
animation: 150,
onEnd: this.updatePosition.bind(this)
})
}
async updatePosition(event) {
const response = await put('/projects', {
body: JSON.stringify({
sgid: event.project.dataset.sgid,
position: event.newIndex + 1
})
})
if (response.ok) {
console.log(event.project.dataset.sgid)
}
}
}
well event doesn't have a method project. You may have meant event.target. Anyway it looks as if the target of the event is probably the #projects element (but you need to check this in dev tools and see where the event is being captured).
Let's suppose that the event is being captured by the #projects element, well that element has an empty dataList. So wherever the capture is occurring, you need to put data: {sgid: project.to_sgid_param} on that element.
Finally, you should be able to populate the ajax request with the value sgid: event.target.dataset.sgid.
I'm developing a rails 5.1 app. I'm using chosen javascript plugin in my app for making the select-boxes more user friendly.
In one of my viewpage, I have 2 chosen select boxes. one for project and other for tasks. Requirement is to load only the associated tasks on change of project select box.
My View
<div class="form-group pad-right-one">
<%= f.collection_select :task_project_id_eq, #projects.order(:number), :id, :project_with_number, { include_blank: 'Project' }, {class: 'chosen-select', onchange: "populateTaskFieldWithOptions()"} %>
</div>
<div class="form-group pad-right-one">
<%= f.collection_select :task_id_eq, #tasks.order(:project_id, :number), :id, :task_with_number, { include_blank: 'Task' }, {class: 'chosen-select'} %>
</div>
Js Code
Ajax call that I'm making is a success and I'm getting all the values.
function populateTaskFieldWithOptions(){
let projectId = $("#q_task_project_id_eq").val();
$.ajax({
type: "POST",
url: "/mail/getTasks",
data: {project: projectId},
success:
function(result){
console.log("---Ajax Success----");
document.getElementById('q_task_id_eq').selectedIndex = -1;
var newOption = $('<option value="1">test</option>');
$('#q_task_id_eq').append(newOption);
$('#q_task_id_eq').trigger("chosen:updated");
// Other options I tried ...
//$('#q_task_id_eq').trigger("liszt:updated");
//$('#q_task_id_eq').val(' ').trigger('liszt:updated');
//$('#q_task_id_eq').val(' ').trigger('chosen:updated');
},
error:
function(jqXHR, textStatus, errorThrown){
console.log("---Ajax Error----")
console.error('AJAX Error: ' + textStatus + errorThrown);
}
})
};
I'm not able to reset or update the chosen dropdown.
Any help is really appreciated. Thanks in advance.
$(".chosen-select").chosen("destroy");
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'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>
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;
})