How to post javascript data to a rails controller action? - javascript

I am using jQuery Shapeshift for drag and drop ordering for some lists that i have. All i need is to send or post this data below to my rails controller action so i can update the order.
This is what i get in my console each time i drag a list.
list_46
0
list_45
1
list_38
2
list_44
3
list_39
4
list_37
5
This is the exact path that i need to send that data above to. I have my routes setup correctly.
sortlists_boards POST /boards/sortlists(.:format)
Javascript Code
jQuery(function() {
$('.listwrap').shapeshift();
return $('.listwrap').on('ss-rearranged', function(e) {
$(this).children().each(function() {
#I need to send/post these two lines below to sortlists_boards_path
console.log($(this).attr("id"))
console.log($(this).index())
});
});
});
Some Github issues that might help
https://github.com/McPants/jquery.shapeshift/issues/64
https://github.com/McPants/jquery.shapeshift/issues/88
https://github.com/McPants/jquery.shapeshift/issues/48

First, modify your Javascript to create an array of ordered pairs and send it to your endpoint:
jQuery(function() {
$('.listwrap').shapeshift();
$('.listwrap').on('ss-rearranged', function(e) {
ordered_items = [];
$(this).children().each(function() {
ordered_items.push([$(this).attr("id"), $(this).index()]);
});
$.post('/boards/sortlists',
{ordered_items: JSON.stringify(ordered_items)},
function(data, status, jqXHR) {
// This is what gets rendered from your rails controller + action
});
});
});
Then, review what it looks like on the Rails side and do something with it
class BoardsController < ApplicationController
# ...
def sortlists
logger.info params[:ordered_items]
end
# ...
end
The output of that will go to log/development.log

Create/Update a JavaScript object on each drag and drop and send an ajax request to the controller, where u can read the object and store in the database.

Related

How to update both a responsive front-end and the database?

I am looking for ways to update the cart in my toy e-commerce application without having to reload the page and I was following this pen.
For example the code that is updating a product's quantity is the following:
$('.product-quantity input').change( function() {
updateQuantity(this);
});
It works nicely but the database is not updating of course at this point.
I was wondering what is the best way to update both the front-end and the database with products' quantities or similar operations? I am probably looking for AJAX but not sure what the latest best practices are (ideally with as less JS as possible).
Your updateQuantity() function has to make an ajax call to a method in your controller that handles the change in the database and responds to either json or js to manipulate the dom.
function updateCart(e){
$.ajax({
type: "patch",
url: 'your_route_to_method', //point to the route that updates the item
data: {
your_resource_scope: { quantity: e.value } //sanitize input in strong params
},
success: function (response) {
//response is the json you get back from your controller
//handle the logic of whatever happens in the dom after you update the quantity
}
});
}
I'd suggest attaching the id of the product you want to update to the input's parent so you can pass it to your route and remember to pass the value under the required scope so you can sanitize the input in your controller via strong_params.
In your controller:
def update
respond_to do |format|
if #your_resource.update(your_resource_params)
format.json { render json: { key: value } } #build the json you want to return
else
#handle failiure
end
end
If you decide to respond in js instead of json, you need to create a view with the same name as your method with a .js or .js.erb extension (instead of .html/.html.erb) and handle the successful response in js. In this view you have access to all the instance variables declared in your method. For example:
# => update.js.erb or your_custom_method_name.js.erb
$('#resource_#{ #your_resource.id }_price').replaceWith('<p>#{ #your_resource.quantity * #your_resource.price }</p>');
If you go this route, remember to delete the success part of your ajax call.

Add a HTML Page To WordPress Site Using Javascript

I'm creating a plugin that will add a custom page to the website (with no template).
I'm struggling to work out how talk to WordPress from inside the Jquery part of my plugin.
At present, there is a variable called res that contains all the HTML for the page.
$.post( templateUrl + "templates/template2.html", function( data ) {
tinyMCE.triggerSave();
var res = data.replace("[([PREHEADER])]", $("#peg-newsletter-preheader").val())
res = res.replace("[([HEADING])]", $("#peg-newsletter-heading").val());
});
Any help is appreciated.
Thanks.
You are using post incorrectly.
This section of the function
function( data ) {
tinyMCE.triggerSave();
var res = data.replace("[([PREHEADER])]", $("#peg-newsletter-preheader").val())
res = res.replace("[([HEADING])]", $("#peg-newsletter-heading").val());
})
is a call back (meaning this is a response you get from WP after you make a successful post). Changing values here only changes the values that you receive rather than wp.
To 'talk' to wp you need to post the data in the body: http://api.jquery.com/jquery.post/
So your jquery post will look like this:
$.post( templateUrl + "templates/template2.html",
{ preHeader: "something", Header: "something" },
function( data ) {
alert("Post successful");
});
However this would assume that your end point allow for a post request to do what you want.
I am not sure what you are trying to achieve though. It looks like you want to change the HTML template of WP? If so I don't know of any rest api that would allow you to do that, as these api's are primarily for pulling WP Posts/Blog data from WP. HTH

How to submit form and update element on the page without refresh, in Rails 4

I'm having a lot of trouble trying to do something that I imagine would be fairly simple.
I have a list of items, let's say, todos. At the bottom of that list I have a text field where I add new items to that list. I want to make it so that the new items are added to the bottom of that list dynamically, without a full page refresh, like in a chat window.
I made the submit form remote: true and it successfully submits without reloading the page, but I can't get the new item to appear at the bottom of the list at the same time. I have to refresh the page to see the changes.
I tried a few different approaches I found on SO (there's no shortage of similar questions here) and the web, and even a gem called Sync, but each of them had errors and problems of their own and I couldn't get any to work properly. Each of them could be its own SO question. So instead I ask: Is there a "recipe" that is sure to successfully implement this in Rails 4?
let's say, now you have a user form to submit,
<%=form_for #user,remote: true%><%end%>
And you also have a controller,
UsersController
In your controller, you have a function,
def create
#something
end
which is for the form.
the only thing you need is to modify the function like
def create
#something
respond_to do |format|
format.js
format.html
end
end
then in your view side, under directory of view/users/ , create a create.js file, in the file, you can do the js action, like get the new record, and append the new record to the users list.
reference:
http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#form-for
There are various ways to do what you are asking. My approach would be:
Create an AJAX call to the controller that passes the parameters of the form
Inside the controller, you save/update things and then return a JSON object
On the success callback of the AJAX function, you append a list item/table row, using the object values
The code could be something like this:
model.js
$(function() {
$("#submit_button").on("click", function(event) {
event.preventDefault();
$.ajax({
type: "POST",
url: "your_controller_url",
data: "your_form_data"
success: function(result) {
// Append the result to a table or list, $("list").append(result)
},
});
});
});
controller.rb
def your_action
# Do your stuff
# return JSON to the ajax call
end
Well, this is just a skeleton. I prefer doing things this way. (Because i hate the js.erb approach)
Here is rails 5, hope it will help someone ( it still works on rails 4 ):
Try this ajax example:
In 'routes.rb':
# set the route that ajax can find the path to what controller in backend
get '/admin/some_great_flow', to: 'great_control#great_flow'
In 'great_control_controller.rb' controller:
# this function in controller will response for ajax's call
def great_flow
# We can find some user or getting some data, model here.
# 'params[:id]' is passed by ajax that we can use it to find something we want.
#user = User.find(params[:id])
# print whole data on terminal to check it correct.
puts YAML::dump(#user.id)
# transform what you want to json and pass it back.
render json: {staff_info: #user }
end
In 'app/views/great_control/index.html.erb' view:
<div>
<label>Staffs</label>
<%=select_tag(:staff, options_from_collection_for_select(#staffs, :id, :name), id:"staff_id", required: true)%>
</div>
<script>
//every time if option change it will call ajax once to get the backend data.
$("#staff_id").change(function(event) {
let staff_id = $("#staff_id").val()
$.ajax({
// If you want to find url can try this 'localhost:prot/rails/info/routes'
url: '/admin/some_great_flow',
type: 'GET',
dataType: 'script',
data: { id: staff_id },
// we get the controller pass here
success: function(result) {
var result = JSON.parse(result);
console.log(result['staff_info']);
// use the data from backend for your great javascript.
},
});
});
</script>
I write it for myself.
You can see the changes using javascript.
For eg lets consider a controller Mycontroller with action index and you are submitting form on index.
Then create a file in views my_controller/index.js.erb
To reflect changes use javascript in this template.
Definately remote sends the ajax call, so to see the changes you need some manipulation using javascript.
Thanks

How can I pull a new request from my index with Backbone.js?

I have an index that creates randomly generated dynamic content.
So everytime you load the index, it'll create a series of view that are dependent on what my Rails model has produced and sent to Backbone.
From backbone, I am curious what I could do to "refresh" the page without doing something like this :
window.location = '/'
I'd like to do it within Backbone.. something like this :
Backbone.history.navigate('/', {trigger: true, replace: true});
But this doesn't necessarily send a new request to the url.
All I would need to do to accomplish my goals is send a GET request to /, which should return a JSON object I can pipe through the rest of my Backbone app.
Is there a way to send this request within Backbone? Or should I just go a traditional jQuery route, and just make a $.get request?
Since your REST api returns a JSON object, simply use a Backbone.Model to structure this data. You can then bind events to do whatever you like in your application.
var RandomData = Backbone.Model.extend({ url: '/' });
var randomData = new RandomData();
// Here, `Backbone` can be substituted by any `View`, `Collection`, `Model...
Backbone.listenTo( randomData, 'change', function() {
//Do something everytime this changes.
});
// When you need to issue a GET '/' request. The following will put the
// JSON response inside of `randomData.attributes`
randomData.fetch();

How to get data returned from Ajax appended to a div? -- JQuery + Rails 3.1

I'm trying to get data returned from a controller and append it to a div. Here is the code I have:
$(this).parent().find('list').append(__WHAT_GOES_HERE?__);
How should I get data to append using ajax in JQuery? I know this is a very basic question -- I'm new to JS :(
PS. Lets assume the controller's path is /ajax_get_items
I assume you want to load it into a class, so list would be .list
Something like:
$.ajax({
url: "/ajax_get_items",
type : "POST",
data : { // If you need data to be posted
id : 12,
num : "test"
},
success : function(result){
$(this).parent().find('.list').append(result);
// If a JSON object is returned, use the following line:
// $(this).parent().find('.list').append(result.html);
}
})
Or if you want to just load data without params (GET method):
$(this).parent().find('.list').load("/ajax_get_items");
If you want more information about ruby rails and jQuery: http://brandonaaron.net/blog/2009/02/24/jquery-rails-and-ajax
This is what you need:
$.ajax({
url: '/ajax_get_items',
success: function(data) {
$('#selector').parent().find('list').append(data)
}
});
Note that you can't use 'this' in this context depending on where this call is made, or you might end up with unexpected results
$('somelink').click(function(e) {
e.preventDefault();
$.ajax(url, data, success:function(resData) {
resultSet = resData.extract(resData);
}
}
Basically this part handles the response from the ajax call and extract is supposed to build up your required html from the returned data.
After this you can simply say
$(this).parent().find('list').append(resultSet);
But this assumes the major work is done in the function extract with the returned data.
There you build up your list (or whatever) html is needed.

Categories