Django :: Create new object in javascript - javascript

I want to be able to create a new Django object called 'Comment' in javascript.
(I understand that you can't simply declare a new object as you would do in a view method)
I need to allow the user to be able to reply to an existing comment.
I have done the bit where if user presses 'reply' button a comment, a form appears below and saves the id of the comment which the user wants to reply to in a js variable.
However, I am struggling to find a way to finally submit all this so that I can post a new sub-comment.
Is there a simple way to achieve this?

I would do that with ajax. If you are using jQuery you could work on something like that:
Lets say you have an template called home.html, which is where you are managing the comments and everything.
home.html
<ul class="comments">
<li data-id="1">This is a comment...</li>
</ul>
<textarea id="new_comment"></textarea>
<button type="button" id="send">Post comment!</button>
urls.py
url(r'^comment/$', 'core.views.comment', name='comment'),
views.py
def comment(request):
c = Comment()
c.text = request.GET.get('text')
c.save()
return render(request, 'core/partial_comment.html', { 'comment': c })
core/partial_comment.html
<li data-id="{{ comment.id }}">{{ comment.text }}</li>
Now you will need a jQuery snippet to send an async request to the server so you can create a new comment:
$(function () {
$("#send").click(function () {
$.ajax({
url: '/comment/',
data: { 'text': $("#new_comment").val() },
type: 'get',
cache: false,
success: function (data) {
$(".comments").append(data);
}
});
});
});
So let's understand what just happened here:
The user come and writes his comment on the textarea with id new_comment
The button with id "send" is listening to the click event
When the user clicks on this button it will send an ajax request to the server with this data which we called "text". Then you are on the server and you can create your Comment object. After saving it, you will return the response to the client. The "data" variable inside the ajax call will catch the result, which is "<li data-id="2">what ever he commented...</li>". Then you append it to the element where is storing your comments on the html view

Related

How to pass arguments from javascript to django view?

I'm trying to do page with simple calculator. I made calculator in js, and now, when I click button I want to pass arguments from js to django. Count them there and print on redirect page.
I have problem with redirect page. When I dont put button in form, js script call calc view, but dont redirect page. I want redirect page and print a result there.
html code:
<form action="calc/" method="post">
{% csrf_token %}
<input id='btn' type="submit" value="CALC" onclick="change()">
</form>
javascript code:
function change(){
var foo = 1;
var foo1 = [1, "tralal", true, ''];
$.ajax({
url: 'calc/',
data : {
'foo': foo,
'foo1': foo1,
},
success: function (data) {
alert("it worked!");
}
}
)};
urls in django
path('calc/', views.calc, name='calc')
view in django
def calc(request):
foo = request.GET.get('foo')
print(foo)
foo1 = request.GET.getlist('foo1[]')
print(foo1)
context = {'data': foo1}
return render(request, 'calc.html', context)
If you want to redirect to another page, you have to do it explicitly from the javascript when the success callback is called. You can see here some answers on how to redirect the page from javascript. To do so, you will have to have another view for serving the result page.
The results of the calculation can be kept in the server (cached), or communicated from the client.
But, I wonder why you are using an Ajax request for that. Ajax requests are useful if you want to do some async http requests to the server without refreshing (or redirecting) the page. So I would say, don't use an Ajax request here, just simply submit the form. You can have a look for example here to see how forms work in javascript. You can also check this Django tutorial about using forms. Django has some tools for handling forms that can be quite convenient when for instance you want to update or create new instances in your database model. It can be a bit confusing at the beginning, but I think it is worth spending some time understanding Django forms.
I do something like this, it work, but I dont know is it correct.
views.py
def link(request):
global matrix
matrix = request.GET.getlist('foo1[]')
return HttpResponseRedirect('/calc/')
def calc(request):
if request.is_ajax:
global matrix
context = {'data': matrix}
return render(request, 'calc.html', context)
else:
return HttpResponseRedirect('/')
urls.py
path('link/', views.link, name='link'),
path('calc/', views.calc, name='calc'),
js function
$(document).ready(function() {
$("#btn").click(function(e) {
var foo = 1;
var foo1 = [1, "tralal", true, ''];
$.ajax({
url: 'link/',
data : {
'foo': foo,
'foo1': foo1,
},
success: function (data) {
window.location.href = "calc/"
}
});
});
});
html code
<input id='btn' type="submit" value="COUNT">
calc.html
{% for d in data %}
<p>"{{ d }}"</p>
{% endfor %}
Page redirect to calc/ and show correct not none matrix.
Result
What you get when using window.location.href = "127.0.0.1:8000/calc" is normal. You are just redirecting to the same page without any url query parameters.
So, you basically want to redirect to the same page?
Why then do you want to redirect? This does not make much sense to me. And again, if you wanna redirect, don't use AJAX, and follow the "normal" approach for submitting forms.
So what I think makes more sense, is to not redirect, but use the data you receive from the the AJAX request and show the information. You can still use some Django tempting en return some rendered HTML that you will then add dynamically with some Javascript code.
It could be something like that:
Javascript
$.ajax({
url: 'link/',
data : {
'foo': foo,
'foo1': foo1,
},
success: function (data) {
$('#result-container').html(data) // add the data in the div container
$("#your-form").trigger('reset'); //you should reset your form
}
});
Main HTML at "/" should contain
<div id="result-container"></div>
And you should just get rid of your link view and have the other somehow like that
def calc(request):
if request.is_ajax:
matrix = request.GET.getlist('foo1[]')
context = {'data': matrix}
return render(request, 'calc.html', context)
But I tell you again, you should use Django forms for what you are doing. See this tutorial for example.
I hope it helps.

Form not rendering on Second Submit AJAX

I have an HTML form that is trigged with AJAX to submit using a Rails backend. However, after submitting the first time, the form stops submitting. From reading other posts, I realize part of the problem is that the issue is related to including $(document) and not the form submit handler in the JQUERY call, but changing it to something like $('.new_todo form').submit will return the page as a JSON object instead of just the instantiated object {} response that I get with using $(document) in the Jquery.
I'm essentially trying to create an object and then to keep appending it to the index page, which works on the first submit, but as noted not on subsequent ones.
I'd really appreciate any insight because I've been staring at this for hours and while tons of answers address similar challenges (unbinding etc), nothing I found successfully addresses this use case.
The current AJAX call is:
$(document).on('submit', '.new_todo', (e) => {
e.preventDefault()
$.ajax({
type: "POST",
url: "/todos",
data: {
'authenticity_token': $("input[name='authenticity_token']").val(),
'todo': {
'name': $("#todo_name").val()
}
},
success: function(response) {
$("#todo_name").val("")
$("#todo_location").html("")
$("#todo_date").html("")
let newTodo = new Todo(response)
let todoHtml = newTodo.formatIndex()
$('.todo-list').append(todoHtml)
}
})
})
The controller action for my create is:
def create
#todo = Todo.new(todo_params)
#todo.save
render json: #todo
end
Thank you!!

How to pass a JavaScript var into a Rails Controller

I'm looking to pass a JavaScript variable into a Rails Controller. The interesting part is that the variable is generated inside Canman, and I cannot use it (yet) outside of it.
This is probably just JavaScript and not necessarily related with Canman. But I'm just not sure what it is happening here.
The approach I'm following (but completely open if there is a better way) is to populate a hidden field with jQuery, just to access the data via params from the controller.
If possible (and if this is a good practice) I will like to avoid the form, and just call some JavaScript on click and then pass that variable to the controller.
View
= form_for #post do |form|
= form.hidden_field :base64
= form.submit
JavaScript
$('form').submit(function(event){
Caman('#canvas', img, function() {
var imageBase64 = this.toBase64();
alert(imageBase64); // works fine
$('#post_base64').val(imageBase64);
});
alert(imageBase64); // nothing
});
PostsController
def update
#post = Post.find(params[:id])
raise '¯\_(ツ)_/¯'
...
end
post_params
=> {"base64"=>""}
Also, I read that an option could be to make an AJAX request. However, I'm not sure how to proceed with that, yet.
At some point, I tried with a text_area instead of a hidden_field. The text_area got populated with the right data. However, params never got the data. If I got back via the browser button, the data was in the text_area, and clicking on submit one more time, populates the params as expected.
Thanks in advance!
Short answer: Ajax.
The goal was to send the value of a variable (a base64 image) to my rails controller, and once there, keep going just with Ruby.
At the end, I created a simple Ajax function to send data from my client (Image from browser) to my server (Rails Controller) via params
save_canvas.js
$(document).on('click', '.save_canvas', function() {
event.preventDefault()
var base64Data = canvas.toDataURL('png')
$.ajax({
type: "POST",
url: "http://localhost:3000/pictures/",
data: { image: base64Data },
success: function(post){ console.log('success') },
error: function(post){ console.log(this) }
})
})
pictures_controller.rb
def create
#picture = Picture.new(image: params[:image])
#picture.save
redirect_to #picture
end
I got support to achieve this here

On click jQuery -> write element to database with PHP

I am creating a CMS that uses an MVC-structure to create/modify/delete pages of a website.
I have lots of objects where I store my data in.
E.g. a $sitemodel with:
$site-id
$page-template
etc.
To create a new page, I added a button in the HTML:
<ul class="nav nav-pills nav-stacked nav-bracket">
<li class="_add-page">
<a href="#user/sites/new">
<i class="fa fa-plus"></i>
<span> Voeg een pagina toe</span>
</a>
</li>
</ul>
I use jQuery to create an event:
$(document).ready(function(){
$("#test-id").click(function(ev){
ev.preventDefault();
$(".site_creator").load("add_page.php");
});
});
The add_page.php calls the following function:
$pagecontroller->new_page($sitemodel->ID);
This on its turn calls the following function:
public function new_page($site-ID)
{
$pagemodel = new page_model;
$page_ID=$pagemodel->insert_pagemodel($site-ID);
return $page_ID;
}
And finally the SQL function from the pagemodel:
public function insert_pagemodel($site-ID)
{
$sSQL = "INSERT INTO `pages` (object) VALUES (".$site-ID.");
if (mysql_query($sSQL)) {$this->ID = mysql_insert_id();} else {return false;}
return $this->ID;
}
What I am trying to understand is: how do I get to use the methods from my $page-controller and $site-controller in add_page.php?
From my research I find two options:
$_SESSION variable (rather not, because then I have to add session to all my files)
Adding them into the .load function, after ("add_page.php",{})
I am trying to use option 2, but I have no idea how to get my data from PHP into the JavaScript?
And is it even possible to add the methods of the classes into the ajax call?
I am trying to see the whole picture here, but it looks to me like I am missing something?
How do I get the data and methods from my objects into the create_page.php?
You need to create an AJAX call from your page which targets the PHP file on your server : -
$(document).ready(function(){
$("#test-id").click(function(ev){
ev.preventDefault();
$.ajax({
method: "POST",
url: "add_page.php/new_page",
data: { // any data you wish to pass to the function }
})
.done(function( data ) {
// You code for when the function has completed
});
});
});
This should get you started- however, you need to work out how you will send the variable you need to use in the PHP & SQL methods ie. $sitemodel->ID.
#Abayob I'm not quite sure of what you want to do, but:
How do I get the data and methods from my objects into the
create_page.php?
You can pass data, but you can't pass methods to php and vice versa.
The best way to pass data from php to js is by using json:
php -> http://php.net/manual/en/function.json-encode.php
check here for a example on how it works:
https://jonsuh.com/blog/jquery-ajax-call-to-php-script-with-json-return/

Pass variable from JavaScript to Ruby session

I have a simple input text field:
<input type="text" id="master_password" size="20" placeholder="Master Password" />
<a class="btn btn-default" id="master_submit" href="#">Submit</a>
And some javascript listening:
$(document).ready(function() {
$('#master_submit').click(function() {
alert("sometext");
});
});
The alert works, obviously. I want to store the text field (#master_password) in session[:master_pass] as I will be using it to decrypt many passwords stored in the database. I'm pretty sure I have to use some AJAX, but not familiar with it at all. What code would I replace the alert with in the js file (or view, or controller, of course) to store the data as a Ruby variable?
Assuming you're using Rails, you could use javascript to make an AJAX request to the Rails app, and then in Rails, you could set the session value.
In Javascript (jQuery):
var data = "password=" + encodeURIComponent($('#master_password').val());
$.ajax({
url: '/my_controller/action',
data: data,
type: 'post'
})
.done(function(response) {
// Do something with the response
})
.fail(function(error) {
// Do something with the error
});
And in Rails, setup a controller with the appropriate route, and in the action:
class MyController < ApplicationController
...
def action # << name whatever you like
session[:password] = params[:password]
end
...
end

Categories