How to send post request to rails action - javascript

I'm new to rails so I don't know if that is the best practice. I'm trying to send user input from index view to the index action using ajax then update the view with user input. I'm not trying to save this input in the database.
The #url always return nil.
NOTE: I try to create a custom action with no luck because it requires a template.
Thanks in advance :)
The index action
def index
#url = params[:option]
end
The index view
<input type="text" id="exampleFormControlInput1">
<p id="resp-result"><%= #url %></p>
<script type="text/javascript">
$(".button").click(function(event){
var userinput = document.getElementById("form").value;
console.log(userinput);
event.preventDefault();
$.ajax({
url:"/responses/",
type: "POST",
data: {option: userinput},
dataType: "text",
success:function(result){
alert("success" + result);
},
error:function(result){
alert("error" + result);
}
});
});
</script>

Yuna you will need to output response in json. lets assume that your ajax script can send data to ruby on rails backend properly.
Try this
at ajax
not this
url:"/responses/",
but
url:"/responses.json",
you can then get result as per
alert("success" + result.myurl);
you can myurl as part of the json response
Finally try this
def index
respond_to do |format|
##url = params[:option]
#url='nancy more url'
format.json do
render json: {myurl: #url}.to_json
end
end
end

Related

Ajax returning empty string in Django view

I am developing a web application through Django and I want to get information from my javascript to a view of Django in order to access to the database.
I am using an ajax call as this post shows.
I am calling the js in html by an onclick event :
sortedTracks.html
...
<form action="{% url 'modelReco:sortVideo' video.id %}">
<input type="submit" value="Validate" onclick="ajaxPost()" />
</form>
...
clickDetection.js
//defined here
var tracksSelected = [];
//function that fill tracksSelected
function tagTrack(track_num){
if(tracksSelected.includes(track_num)){
var index = tracksSelected.indexOf(track_num);
tracksSelected.splice(index, 1);
}else{
tracksSelected.push(track_num);
}};
//ajax function
function ajaxPost(){
$.ajax({
method: 'POST',
url: '/modelReco/sortedTracks',
data: {'tracksSelected': tracksSelected},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked! ");
},
error: function (data) {
alert("it didnt work");
}
});
};
So the information I want to transfer is tracksSelected and is an array of int like [21,150,80]
views.py
def sortedTracks(request):
if request.is_ajax():
#do something
print(request)
request_data = request.POST
print(request_data)
return HttpResponse("OK")
The ajax post works well but the answer I get is only an empty Query Dict like this :
<QueryDict: {}>
And if I print the request I get :
<WSGIRequest: GET '/modelReco/sortedTracks/?tracksSelected%5B%5D=25&tracksSelected%5B%5D=27&tracksSelected%5B%5D=29'>
I have also tried to change to request_data=request.GET but I get a weird result where data is now in tracksSelected[]
I've tried to know why if I was doing request_data=request.GET, I get the data like this tracksSelected[] and get only the last element of it.
And I found a way to avoid to have an array in my data (tracksSelected) on this link
This enables me to have :
in views.py
def sortedTracks(request):
if request.is_ajax():
#do something
print(request)
request_data = request.GET.getlist("tracksSelected")[0].split(",")
print(request_data)
and in clickDetection.js
function ajaxPost(){
tracksSelected = tracksSelected.join();
$.ajax({
method: 'POST',
url: '/modelReco/sortedTracks',
data: {'tracksSelected': tracksSelected},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked! ");
},
error: function (data) {
alert("it didnt work");
}
});
};
This little trick works and I am able to get the array data like this,
print(request_data) returns my array such as [21,25,27]
Thank you for helping me !
According to me to access the data which is sent in the ajax request can be directly accessed .
For Example:
def sortedTracks(request):
if request.method == 'POST':
usersV = request.POST.get('tracksSelected')[0]
for users in usersV:
print users
return HttpResponse("Success")
else:
return HttpResponse("Error")
The correct syntax is data: {tracksSelected: tracksSelected},

Render rails fields_for through ajax call

I have an AJAX call:
$('#enrollment_members').change(function(){
var memberNumber = $(this);
$.ajax({type: 'GET',
url: $(this).href,
type: "get",
data: { members: memberNumber.val() },
error: function(){ alert("There was a problem, please try again.") }
});
return false;
console.log(data);
});
through which I send params[:members] into a new method.
I wanna do something like this:
def new
#enrollment = Enrollment.new
params[:members] ? params[:members].to_i.times { #enrollment.atendees.build } : #enrollment.atendees.build
respond_to do |format|
format.js
end
end
I need this value in order to know how many fields_for to build.
But this being in the new action, how can I update the content of the new view after inputting a value in the members input field?
From that ternary, #enrollment.atendees contains 4 objects.
My new.js.erb :
$("#contact-wrap").html("<%= j render(:partial => 'enrollments/form') %>");
The xhr response contains 4 fields_for forms.
Is the object #enrollment_members the input value you are trying to pass to the controller?
if so, try this:
$('#enrollment_members').change(function(){
var memberNumber = $(this);
$.ajax({type: 'GET',
url: $(this).href,
type: "get",
data: { members: memberNumber.serialize() }, //CHANGE
error: function(){
alert("There was a problem, please try again.")
}
});
return false;
Hmm are you really sure you need a custom made solution for this ? The behavior of dynamically adding/removing children in fields_for is already adressed by several gems like nested_form (no longer maintained) or cocoon (more promising)
I'd suggest to actually reuse their library even if you need to tweak it your way. Because doing an AJAX request is completely pointless. Your AJAX is a GET request that will always do the same thing, unless you have a custom atendees.build which will do weird things for successive calls (like incrementing a global counter somewhere).
Those gems I mentionned above will actually save the HTML fields to generate in a "template" (stored locally in HTML or JS), and just call this template when you want to add a new field.
I got it working by modifying the ajax call:
$('#enrollment_members').change(function(){
var memberNumber = $(this);
$.ajax({type: 'GET',
url: $(this).href,
type: "get",
dataType : "html",
data: { members: memberNumber.val() },
success: function( data ) {
var result = $('<div />').append(data).find('#contact-wrap').html();
$('#contact-wrap').html(result);
$('#atendees-wrap').show();
},
error: function( xhr, status ) {
alert( "Sorry, there was a problem!" );
}
});
return false;
});

Rendering an object passed through Pusher in Rails

I am trying to implement a realtime chat application.
I'm using pusher to notify server about the button click, and then pass the message object as message to a subscriber. What I need to do is, render that message in other user's chat screen(show.html.erb) dynamically. Here is my cycle:
// MessagesController.rb
def create
conversation = Conversation.find(params[:conversation_id])
message = Message.create(content: params[:content], user_id: params[:user_id])
conversation.messages << message
Pusher['test_channel'].trigger('my_event', {
message: message
})
end
And my subscriber is
// show.html.erb
// some html code
<ul class="chats">
<%= render #messages %>
</ul>
// some html code
<script>
// some js code
var channel = pusher.subscribe('some_channel');
channel.bind('some_event', function(data) {
// What to do here?
});
</script>
This assumes you are using jquery. It's also untested so may have a few bugs/syntax errors.
Ajax method:
JS
channel.bind('some_event', function(data) {
$.ajax({
url:'/messages/'+data.message.id,
success:function(html){ $('.chats').append(html)}
});
});
routes:
match '/messages/:id' => "messages#show_no_layout"
controller:
def show_no_layout
#message = Message.find(params[:id])
render "show", layout: false
end
view(show.html.erb):
<%= *whatever you want in here* %>
ICH(read more) method:
This will of course require adding an extra js file which is why its not my first suggestion.
Template:
<script id = "messageTemplate" type = "text/html">
{{ message.content }}
// plus whatever else you want.
</script>
channel.bind('some_event', function(data) {
messageHtml = ich.messageTemplate(data.message);
$('.chats').append(messageHtml);
});
If you are using JQuery,
channel.bind('some_event', function(data) {
$('.message').text(data.message);
});
See this tutorial.

Using AJAX POST from javascript to Rails 4 controller with Strong parameter

I'm newbie with Rails
My purpose is insert song_id and title which received from Javascript via AJAX POST into Database (MySQL)
In my javascript file
var song_id = "23f4";
var title = "test";
$( document ).ready( function() {
jQuery.ajax({
url: 'create',
data: "song_id=" + song_id + "&title=" + title,
type: "POST",
success: function(data) {
alert("Successful");
},
failure: function() {
alert("Unsuccessful");
}
});
} );
In my editor_controller.rb
class EditorController < ApplicationController
def new
#song = Song.new
end
def create
logger.debug("#{params[:song_id]}")
logger.debug("#{params[:title]}")
#song = Song.new(song_params)
if #song.save
redirect_to root_path
else
flash[:notice_song_failed] = true
redirect_to root_path
end
end
private
def song_params
params.require(:song).permit(:song_id, :title)
end
The problem is when I running the Rails app with this code, the Console notices me that
ActionController::ParameterMissing at /editor/create
param is missing or the value is empty: song
I'm trying to use
private
def song_params
params.require(:song).permit(params[:song_id], params[:title])
end
but it doesn't work and notices me the same, moreover in the terminal log told me below
Started POST "/editor/create" for ::1 at 2015-04-01 01:07:23 +0700
Processing by EditorController#create as /
Parameters: {"song_id"=>"23f4", "title"=>"test"}
23f4
test
Completed 400 Bad Request in 1ms
Do I missed something in my code, Thanks for Advance.
You are not sending a song parameter at all. It looks like you need to update the data line in the jQuery.ajax call to include the song parameter like so:
data: {song: {song_id: song_id, title: title}}
This:
params.require(:song).permit(params[:song_id], params[:title])
is saying "require the 'song' parameter, and allow 'song_id' and 'title' through. If you don't pass a song parameter, you'll get a bad request.
You can either:
Change that line of code to remove the require on 'song'
or
Like #infused says, change your ajax call to send a song JSON object.

how to get a variable in the link_to path

I am trying to use a variable in the following link_to call:
<%= link_to '<button type = "button">Players</button>'
.html_safe, live_players_path(:Team => #tmf) %>
but every time i click this it no longer has the value of the variable which was set here:
<select id = "FilterTm">
<option>Select a Team...</option>
<% Abbrv.order("Team").each do |abbrv| %>
<option><%= abbrv.Team %></option>
<% end %>
</select>
using an ajax call:
$(document).ready(function(){
$('#FilterTm').change(function(){
Tm = $('#FilterTm').val();
SelectTm = true;
$.ajax (
{
url: "http://localhost:3000/live_players.json' +
'?TmFilter="+Tm+"&Selected="+SelectTm,
type: "get",
dataType: "json",
cache: true,
success: function(data) {
alert("Loading Players....");
},
error: function(error)
{
alert("Failed " + console.log(error) + " " + error);
}
});
});
});
So in summary, I select a Team from the select dropdown, which triggers the ajax, which set the #tmf variable in the controller, but when clicking the link_to, the variable (#tmf) is nil. How can i get the variable to stay so it can be used later?
This gets rendered on the server & sent to the client during the first request from the user:
<%= link_to '<button type = "button">Players</button>'
.html_safe, live_players_path(:Team => #tmf) %>
The ajax request is a separate request. Changing #tmf on the server during the ajax request only changes #tmf on the server. It has to be sent to the client. You will have to make the server side of the ajax request send the new #tmf value to the client, then write custom javascript to set the value of the href. Something like this:
No need to use rails here...
<a id="playerBtn"><button type="button">Players</button></a>
THe javascript pseudocode:
var playerBtn = $("#playerBtn");
...
success: function(data) {
alert("Loading Players....");
playerBtn.href= "url/?Team=" + data.tmf;
},
Btw for others that see this post I really just used:
$('selector').attr('href', 'url');
selector being the element, and the url being the requested information.

Categories

Resources