I am trying to serve HTML code if any SocketIO event occurs , so instead of doing :
$(document).ready(function(){
var notification_back = '/notifications';
var callback = 'http://' + document.domain + ':' + location.port + notification_back;
var socket = io.connect(callback);
socket.on('new_test_event', function(data){
var testList = $('#new_test_list');
testList.prepend(
'\
<li>\
<a href="'+data.url_to+'">\
<div class="user-new">\
<p>'+data.title+'</p>\
<span>'+moment(data.timestamp).fromNow()+'</span>\
</div>\
<div class="user-new-left">\
<i class="fa fa-rss"></i>\
</div>\
<div class="clearfix"> </div>\
</a>\
</li>\
'
)
console.log(data);
});
i would prefer to serve that html code from the back-end, so something like this:
#socketio.on('new_test_event', namespace='/notifications')
def raise_new_attack(data):
return Markup("THE HTML CODE GOES HERE")
Is there any way to make that work ? or its not possible ?!
That's not how SocketIO works, you seem to be trying to adapt SocketIO to how HTTP does things, so maybe you should consider if SocketIO is what you want.
There is nothing wrong with returning HTML from a SocketIO event, but you will need to add some JavaScript on the client that receives the HTML and inserts it in the correct place in the page.
The following is an example of an event returning HTML:
#socketio.on('new_test_event', namespace='/notifications')
def raise_new_attack(data):
emit("my_notification", "THE HTML CODE GOES HERE")
Then in the client you would have something like this:
socket.on("my_notification", function(html_code) {
// use jQuery or similar to insert the html in the page
});
Related
Using Ajax and Django, my data get lost when sent back to my template and I can't retrieve them.
Here is my code and the logic :
Following the dependent dropdown lists tutorial offered by ["Simple is Better Than Complex"][1]
I have implemented an Ajax request.
Here is the html code:
<p class="multiple-choice" id="mandate-city" data-url="{% url 'officials:ajax_load_mandate_city' %}">Local Mandate: {{ form.mandate_city }}</p>
The ajax request is fired from this script:
<script>
$("#id_departments").change(function (){
var url = $("#mandate-city").attr("data-url");
var departmentId = $(this).val();
$.ajax({
url: url,
data: {
'department': departmentId
},
success: function (data){
$("#id_mandate_city").html(data);
console.log(data);
}
});
});
</script>
After check with console.log, the data are collected by the script. Then, they reach the view.
Here is my view:
def load_mandate_city(request):
department_id = request.GET.get('department')
mandate_city = MandateCity.objects.filter(department_id=department_id).order_by("department")
return render(request, "officials/mandate_city_list.html", {mandate_city: mandate_city})
With a print, I have checked, and the data are treated as planned.
Then the data are sent back through the url:
path('ajax/load_mandate_city/', views.load_mandate_city, name="ajax_load_mandate_city")
They seem not to reach the template:
{% for mandate in mandate_city %}
<option value="{{ mandate.pk}}">{{ mandate.get_mandate_display }}</option>
{% endfor %}
And I could not track them in my script. :-/
Can somebody let me know where the bug is ?
Thanks.
[1]: https://simpleisbetterthancomplex.com/tutorial/2018/01/29/how-to-implement-dependent-or-chained-dropdown-list-with-django.html
did you try to return the information in a json object and then render it with client side js? in general when you use ajax (or fetch) you wanna use the information returned so it's better to return it as a data type,
if you do want to return the html response you should probably not use ajax but rather a form
I'm making my first webapp using python and flask, it is a simple calculator but I'm currently stuck trying to use more than one button. At the beginning it was abe just to show a graph, here is the python code:
class FormulaForm(Form):
formula = StringField('formula')
graph = SubmitField('graph')
#app.route('/')
def calculate():
form = FormulaForm()
formula = request.args.get('formula','')
points = mp.make_points(formula,0,7)
comp = make_plot(points[0],points[1])
return render_template('index.html',the_script=comp[0],the_div=comp[1],form=form)
And here is the html code:
<form method="GET" action="">
<br />
{{ form.formula }}
<br />
{{ form.graph }}
</form>
So far so good. But I don't know how to add more functionality, for example I would like to add a button that shows the formula evaluated at some value x. I tried adding an extra inputfield and an extra button in the form, something like this:
class FormFormula(Form):
formula = StringField('formula')
graph = SubmitField('graph')
evaluate = StringField('evaluate_at')
evaluate = SubmitField('evaluate')
But then I don't know how to make the view handle two different actions.
I think I found a solution here but it only works when the method is "POST" and that makes the page reload which I don't want. So, is there a way to use multiple buttons in the same view?
#app.route('/start' ,methods=['POST'])
def stop():
"process done here"
return Something
Your app.py like this and and html file this
<script src="static/js/ajax.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$("#start").click(function(event){
$.post(
"/start",
function(data) {
window.alert(data);
}
);
});
});
</script>
<button id ="start" type="button" value = "Load Data">Start</button>
I was trying to make a Backbone Application with Django at its backend. I was following a Backbone tutorial. I used the following code:
Code
<!doctype html>
<html lang = "en">
<meta charset = "utf-8">
<title>IstreetApp</title>
<link rel="stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Book Manager</h1>
<hr />
<div class="page"></div>
</div>
<script type = "text/template" id = "booklist.template">
</script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.10/backbone-min.js"></script>
<script>
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.url = 'http://backbonejs-beginner.herokuapp.com' + options.url;
});
var Books = Backbone.Collection.extend({
url: '/books'
});
var BookList = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var books = new Books();
books.fetch({
success: function(books) {
var template = _.template($('#booklist.template').html(), {books: books.models});
that.$el.html(template);
}
})
}
});
var Router = Backbone.Router.extend({
routes: {
'': 'home'
}
})
var bookList = new BookList();
var router = new Router();
router.on('route:home', function () {
bookList.render();
});
Backbone.history.start();
</script>
</body>
</html>
Since the collection is not defined, the success code doesn't execute. I suppose the collection data should come from the server through Django but I am not sure how and in what form. Kindly help. I am pretty much new to backbone and Django.
When you call fetch on your collection, it makes an AJAX request to:
http://backbonejs-beginner.herokuapp.com/books
However, there is no API set up there. Either one of two things needs to happen:
1) you need to modify your code to point to a different URL, one that does have an existing API (perhaps whatever tutorial you are using has such an API)
2) you need to create such an API yourself on yoursever.com (and then make your Backbone code point to that API's URL instead)
Without a server to support it, operations like save and fetch and such in Backbone simply cannot function.
As a side note, Django is a web site framework. While you can use it to create server-side APIs, that's not really Django's focus. Because of this, several good third party libraries exist for doing RESTful APIs (ie. the kind that Backbone likes) in Django; personally I'd recommend either Django REST Framework (I use it and it works great) or TastyPie (never used it, but it's very popular).
When using a backbone collection you need to return a json array of objects from your api url (http://backbonejs-beginner.herokuapp.com/books)
Example
{[{"name":"bookname", "publisher": "penguin"}, {"name":"bookname", "publisher":"penguin"}]}
You'll also want a model for your collection. A model would look like this
Example:
var Book = Backbone.Model.extend({
defaults: {
"name": "",
"publisher": ""
}
});
The way that the collection works is by parsing the json array and turning each object in the array in to a model that you specific (in this instant an individual book with values for the name and publisher).
When you make a .fetch() on your model you are making a GET request, so make sure that your http://backbonejs-beginner.herokuapp.com/books url is prepared to receive GET requests and respond with the json data in the format I specified up top.
I have a view which returns a chained object of 3 models
def test(request):
output=itertools.chain(
model1.objects.all(),
model2.objects.all(),
model3.objects.all()
)
return render_to_response('test.html', {'output':output})
In the html, I added an anchor and a jQuery script, which should replace the #output with new values just from model1
<html>
<head>...</head>
<body>
<script>
$(document).ready(function() {
$("#switch").click(function() {
$.ajax({
url: $(this).attr("href"),
success: function(result) {
//whatever I put here is not triggered
}
});
});
});
</script>
<a id="switch" href="?model=1">switch to model 1</a>
<div id="output">
{% for item in output %}
<div id="{{item}}">
{{item}}
</div>
{% endfor %}
</div>
</body>
</html>
I tried to put the div#output into a separate template output.html and modified the views.py like so:
def test(request, template='test.html'):
if request.GET.get('model'):
output=model1.objects.all()
else:
output=itertools.chain(
model1.objects.all(),
model2.objects.all(),
model3.objects.all()
)
if request.is_ajax(): template='output.html'
return render_to_response(template, {'output':output})
But everytime I click the link, the whole page is refreshed (with the new values from model1).
Opera returns just the output.html
Been struggling with this for more than 3 days, Im new into Ajax and this is getting very confusing for me.
I hope someone can shed some light!
First, make sure that your view works and that you're getting the expected HTML output when accessing the url directly (you might also want to comment out if request.is_ajax() temporarily).
Then, try replacing the content of the #output div using jQuery.html() method in your ajax call. Here is an example with some animation:
$.ajax({
...
success: function( returnedData ) {
$("#output").css("color", "red").fadeOut(500, function() {
$("#output").html(returnedData);
$(this).css("color", "green").fadeIn(500);
});
}
Also, try monitoring your ajax call using Firebug/Chrome Developer Tools - both tools will allow you to quickly determine the issue.
Thanks to Daniel Rosman for the heads-up I had to prevent the default action of the a#switch. It works like butter now!
Here is the initial question: how to access jQuery.ajax() get parameters in Django views
I want to implement a ajax 'like' button which should increase the like count and not refresh the whole page. I am new to ajax so please help.
urls.py:
(r'^like/(\d+)/$',like),
Below is my views code for like:
def like(request,feedno):
feed=Feed.objects.get(pk=feedno)
t=request.META['REMOTE_ADDR']
feed.add_vote(t,+1)
vote, created = Vote.objects.get_or_create(
feed=feed,
ip=t,
)
feed.likecount+=1
feed.save()
if 'HTTP_REFERER' in request.META:
return HttpResponseRedirect(request.META['HTTP_REFERER'])
return HttpResponseRedirect('/')
Below is my html(like div):
<div class="like_abuse_box">
<p>Likes:<b>{{vote.feed_set.count}}</b> ||
<a class="like" href="/like/{{feed.id}}/">Like</a> |
<a class="abuse" href="/abuse/{{feed.id}}/">Abuse</a> || </p>
</div>
What code should I include to only refresh that particular div and updated like count be shown without the whole page getting reloaded. Need Help. Thanks.
Haven't tested it athough something like that should work. Edit: tested and works, now for multiple elements on a webapage
Javascript
$("a.like").click(function(){
var curr_elem = $(this) ;
$.get($(this).attr('href'), function(data){
var my_div = $(curr_elem).parent().find("b");
my_div.text(my_div.text()*1+1);
});
return false; // prevent loading URL from href
});
Django view
You can add if request is Ajax with:
if request.is_ajax():
First thing: put an id on the html element where the content to be injected.
<div class="like_abuse_box">
<p>Likes:<b id="like_count">{{vote.feed_set.count}}</b> ||
<a class="like" href="/like/{{feed.id}}/">Like</a> |
<a class="abuse" href="/abuse/{{feed.id}}/">Abuse</a> || </p>
</div>
second, in your view you need to return the latest like count. You can't just locally update the count, since there is a chance that someone else may have updated the like count as well.
Lastly. in your page include the jquery
$("a.like").bind("click", function(){
var link = $(this).attr("href");
$.get(link, function(data) {
$(this).parent("div").children('b#like_count').html(data);
});
});
I am not quite certain about the parent child selector, to navigate from hyper linked clicked to its corresponding like count. You may have to play around with JQuery selector to get it right.
ALso, if you are using POST for your view, replace $.get with $.post