JQuery tokenfield with django not working - javascript

I am trying to incorporate a search field in a django registration form. I would like to use a bootstrap tokenfield that searches a django model for possible matches to the search string. I've been struggling with this for a couple of days now. Here is my code below.
<div class="form-inline" id="keywords_div">
{% csrf_token %}
<input type="text" name="search_text" class="form-control" id="tokenfield" placeholder="Enter keyword" style="width: 50%" />
<button type="button" id="addKeyword-btn" class="btn btn-primary">Add</button>
My JQuery code.
$(function(){
//auto complete ajax code.
$('#tokenfield').tokenfield({
autocomplete: {
//source:['red','blue','green','yellow','violet','brown','purple','black','white'],
delay: 100
},
showAutocompleteOnFocus: true,
}).keyup(function(){
alert('key pressed');
$.ajax({
url: "/user_account/auto_complete_search/",
type: 'POST',
data: {
'search_text': $('#tokenfield').val(),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: function(data){
console.log(data)
},
dataType: 'text'
});
});
});
});
Django View
#This is the function that handle the auto complete search functionality.
def autocomplete_search_view(request):
if request.method == 'POST':
search_text = request.POST['search_text']
else:
search_text = ''
keywords = Keywords.objects.filter(keyword__icontains=search_text)
#data = serializers.serialize('json', keywords, fields=('keyword'))
return HttpResponse('Query completed', content_type='application/text')
user_account/urls.py
url(r'^auto_complete_search/$', autocomplete_search_view, name='autocomplete_search'),
The error from the browser.
What am I doing wrong here?

After a very long time of searching for the answer, I eventually got it right. see the code below. I'm trying to figure out how to make the dropdown menu scrollable but code below does exactly what I wanted.
$('#tokenfield').tokenfield({
autocomplete: {
source: function(request, response){
if(request.term.length >= 5){
$.ajax({
url: "/user_account/auto_complete_search/",
type: 'POST',
data: {
'search_text': request.term,
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: function(data){
if(data != ""){
var dataArr = [];
$.each(data, function(i, jsonObj){
dataArr[i] = jsonObj.fields.keyword;
});
response(dataArr);
}
else{
response([]);
}
},
dataType: 'json'
});
}
else{
response([]);
}
},
delay: 300,
},
showAutocompleteOnFocus: true
});
Django view.
#This is the function that handle the auto complete search functionality.
def autocomplete_search_view(request):
if request.method == 'POST':
search_text = request.POST['search_text']
else:
search_text = ''
return HttpResponse([{}], content_type='application/json')
keywords = Keywords.objects.filter(keyword__icontains=search_text)
data = serializers.serialize('json', keywords, fields=('keyword'))
return HttpResponse(data, content_type='application/json')
The HTML is still the same. Hope this helps somebody in the future.

Related

how do i remember the radio button selection in django

i'm trying to make sure that even if the user refresh the page or goes back and comes back to that page, the radio button is still the same as what the user selects.
N.B: the value of the radio button is saved in sessions
<div class="col-md-1 ps-md-1">
<input class="align-middle h-100" type="radio" name="deliveryOption" id="{{option.id}}"
value="{{option.id}}">
</div>
my ajax
$('input[type=radio][name=deliveryOption]').on('change', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '{% url "checkout:cart_update_delivery" %}',
data: {
deliveryoption: $(this).val(),
csrfmiddlewaretoken: "{{csrf_token}}",
action: "post",
},
success: function (json) {
document.getElementById("total").innerHTML = json.total;
document.getElementById("delivery_price").innerHTML = json.delivery_price;
},
error: function (xhr, errmsg, err) {},
});
});
</script>
my view
def cart_update_delivery(request):
cart = Cart(request)
if request.POST.get("action") == "post":
delivery_option = int(request.POST.get("deliveryoption"))
delivery_type = DeliveryOptions.objects.get(id=delivery_option)
updated_total_price = cart.cart_update_delivery(delivery_type.delivery_price)
session = request.session
if "purchase" not in request.session:
session["purchase"] = {
"delivery_id": delivery_type.id,
}
else:
session["purchase"]["delivery_id"] = delivery_type.id
session.modified = True
response = JsonResponse({"total": updated_total_price, "delivery_price": delivery_type.delivery_price})
return response

Refresh content in a for loop using jquery in Django

I am creating a website that allows users to search for a list of papers. Once a list of papers is returned, the user can click "like" or "dislike" to one or more papers. The like count should dynamically update as the user click the like button.
I am using jquery to handle the dynamic update of the like count. However, I am not sure how to tell the success function in the ajax WHICH id to update. The reason is that the id is generated on the fly, and it is determined by which papers are returned as search results to the user.
So far, I have the following in the template:
{% for result in results %}
<li >
{{ result.title}},
<span class="like_span fa fa-thumbs-up"></span>
<strong id="like_count_{{ result.pk }}">{{result.likes}} </strong>
</li>
{% endfor %}
As you can see, i specify the id of the part where I want the dynamic update to happen as "like_count_{{ result.pk }}". I am not sure if this is the best way to go about it.
The jquery part looks like this:
<script>
$(document).ready(function(){
$(".like_button").click(function(){
$.ajax({
type: "GET",
data: {'pk': $(this).data('pid'),
'liked': $("span").hasClass('fa fa-thumbs-up') },
url: "{% url 'search:paperpreference' %}",
success: function(response) {
var pk = $(this).data('pid');
$(?????).html(response.likes )
},
error: function(response, error) {
alert(error);
}
});
});
});
</script>
Simply put, I don't know how can i specify the ????? part such that when success, the new like count is only updated to that specific paper, not the first paper in the loop.
The views.py has the following so far:
def paperpreference(request):
# if request.method == "GET":
pid = request.GET['pk']
paper = Paper.objects.get(pk=pid)
likes = paper.likes + 1
paper.likes = likes
paper.save()
data = {'likes': paper.likes}
return JsonResponse(data)
I am new to Jquery, any help would be much appreciated!
Thanks to suggestions by #dirkgroten, the like count can now be dynamically updated by the following jquery function. The trick is to move the pk declaration to before the ajax.
<script>
$(document).ready(function(){
$(".like_button").click(function(){
var pk = $(this).data('pid')
$.ajax({
type: "GET",
data: {'pk': pk,
'liked': $("span").hasClass('fa fa-thumbs-up') },
url: "{% url 'search:paperpreference' %}",
success: function(response) {
$("#like_count_"+ pk).html(response.likes )
},
error: function(response, error) {
alert(error);
}
});
});
});
</script>
another option is return the id from the server.
def paperpreference(request):
# if request.method == "GET":
pid = request.GET['pk']
paper = Paper.objects.get(pk=pid)
likes = paper.likes + 1
paper.likes = likes
paper.save()
data = {'likes': paper.likes,'pid':pid}
return JsonResponse(data)
<script>
$(document).ready(function(){
$(".like_button").click(function(){
var pk = $(this).data('pid')
$.ajax({
type: "GET",
data: {'pk': pk,
'liked': $("span").hasClass('fa fa-thumbs-up') },
url: "{% url 'search:paperpreference' %}",
success: function(response) {
$("#like_count_"+ response.pid).html(response.likes )
},
error: function(response, error) {
alert(error);
}
});
});
});
</script>

AJAX Data not Posting to View in Django

I've implemented a basic checkout wherein a user may select a shipping address from a list of addresses via the 'address' class. It works on the server side, but I would like to use AJAX to avoid having the page refresh with each selection. The code is not posting any data, however. What am I doing wrong?
views.py
def pick_address(request):
if request.method == 'POST':
checkout = Checkout.objects.get(pk=request.POST.get('checkout'))
checkout.shipping_address = ShippingAddress.objects.get(pk=request.POST.get('address'))
checkout.save()
return HttpResponse('success')
pick_address.js
<script>
$('.address').click(function () {
$.ajax({
type: 'POST',
url: '{% url 'pick-address' %}',
dataType:'json',
data: {
checkout: {{ checkout.pk }},
address: {{ address.pk }},
csrfmiddlewaretoken: '{{ csrf_token }}'
},
success: function (data) {
if (data['success']) {
alert('success!');
}
}
});
});
</script>
In views.py
def pick_address(request):
if request.method == 'POST':
checkout = Checkout.objects.get(pk=request.POST.get('checkout'))
checkout.shipping_address = ShippingAddress.objects.get(pk=request.POST.get('address'))
checkout.save()
ctx={'success':True}
return HttpResponse(json.dumps(ctx),content_type='application/json')
in pick_address.js
success: function (data) {
if (data.success) {
alert('success!');
}
}
I was using the slim version of jQuery, which does not support AJAX. The code was otherwise (mostly) correct.

Django Ajax returns whole html page

I'm trying to create live search filter,with ajax
$(function() {
$('#search-item').keyup(function() {
$.ajax({
type: "GET",
url: "/toysprices/",
data: {
'query' : $('#search-toy').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: searchSuccess,
dataType: 'html'
});
});
});
function searchSuccess(data, textStatus, jqXHR)
{
console.log(data);
}
and my views.py
f request.method == "GET":
search_text = request.GET['query']
if search_text:
search_text = request.GET['query']
statuss = Status.objects.filter(status__contains = search_text)
else:
statuss = Status.objects.all()
return render(request, 'ajax_search.html', {'statuss':statuss})
it works correctly, but it returns whole html page, how can i make to get only part which I want to render in my template.
Returning the result with JSON will solve your problem.
For Example,
# Django view
def search(request):
if request.method == "GET":
return_array = []
search_text = request.GET.get('query') # Always put request.GET.get('param') instead of request.GET['param']
if search_text:
search_text = request.GET.get('query')
statuss = Status.objects.filter(status__icontains = search_text)
else:
statuss = Status.objects.all()
for i in statuss:
return_sub_array = {}
return_sub_array['status_name'] = i.status_name
return_array.append(return_sub_array)
return HttpResponse(json.dumps(return_array))
# Jquery function
$('#search-item').keyup(function() {
$.ajax({
type: "GET",
url: "/toysprices/",
dataType: 'JSON',
data: {
'query' : $('#search-toy').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: function(data){
if(data.length > 0 )
{
console.log(data);
for (var i = 0; i < data.length ; i++) {
var obj = data[i]['status_name'];
console.log(obj)
// further logic goes here
}
}
else {
console.log("No result found");
}
},
error:function(data){
console.log('error')
console.log(data)
}
});
});
In most cases it is the url which you are using to call, assuming you have the following path in the url.py
path('Import/', views.Import, name='import'),#.....1
path('getMetaData/', views.metaData, name='metadata'),#....2
and your url: http://127.0.0.1:8000/folder/Import/ is using the first path which is showing the page, if you wish to get data from ajax from the metaData function in views.py, if you use path 2 above it will give you html, so your path should be as follows:
path('Import/getMetaData/', views.metaData, name='metadata'),#....3
You are rendering html and returning it in your view. Here's nothing to expect from this view other than html. In order to return JSON object as a response, your view should return response like this:
return JsonResponse({'statuss':statuss})

Show succes message from ajax

I have a question, So I create a sistem that update in database a row when onChange a select box. All goes well, but I want to drop a succes message if update was with succes.
My view :
<form action="" id="updateStatus" method="post">
<select id="statusSelect"
name="{{ gift.id_instant_gagnant }}"
class="form-control"
onChange="updateCadeauStatus({{ gift.id_instant_gagnant }})">
{% for key,statut in form_logistique.statut.choices %}
<option value="{{ key }}"
{% if gift.etat == key %}selected="selected"{% endif %}>
{{ statut }}
</option>
{% endfor %}
</select>
</form>
<script>
function updateCadeauStatus(id) {
var id = id;
var selectedName = $("#statusSelect option:selected").val();
var url_deploy = 'http:localhost/updateStatus'
console.log(id);
console.log(selectedName);
$.ajax({
url: url_deploy,
type: "POST",
async: true,
data: { id_cadeau:id, id_status:selectedName}
});
}
</script>
The controller :
public function updateStatus(){
$iGiftId = $_POST['id_cadeau'];
$iNewStatus = $_POST['id_status'];
$bUpdate = $this->updateStatusByGiftId($iGiftId, $iNewStatus);
return $this->render('logistique.twig');
}
The model :
public static function updateStatusByGiftId($iGiftId, $iStatusId){
$request = sprintf( ' UPDATE `%s` set etat = %d WHERE id = %d ', $table, $iStatusId, $iGiftId);
return Mysqli::query($request, $database);
}
So everything goes well but I want to drop a message after every update, too be displayed in the view. Please help me!!! Thx in advance, sorry for my english.
$.ajax({
url: url_deploy,
type: "POST",
async: true,
data: { id_cadeau:id, id_status:selectedName},
success : function(data){
console.log('success');
},
error: function(){
console.log('error');
}
});
You can drop the response of the check file on ajax.
$.ajax({
url: url,
type: "POST",
...
success: function(response){
window.alert(response);
}
})
To be more specific, if you want to give a message only when you successfully changed the row. Modify the validation file (url:) and print a messagge only when you had success..
There are other ways to do that..
You can print a "message id" and get it with the script and drop a message:
$.ajax({
url: url,
type: "POST",
...
success: function(response){
if(response == '1'){
window.alert('Successfully changed!!');
}else if(response == '0'){
$("#foo").html("Error, not changed :(");
}else{
------ something else ------
}
}
})
Hope I could help !
Im not sure if you have your response in another file.
Cuz your response now is in the var data in the line with the code:
}).done(function(data){
$.ajax({
url: url_deploy,
type: "POST",
async: true,
data: { id_cadeau:id, id_status:selectedName}
}).done(function(data){
$("[SuccesDiv]").append("[Succes MSG]");
});
The text between the [ - ] is ment to put there your own element or data.
[EDIT]
I did'nt look good...
You are not looking when it is changed.
To do that, do this:
$("select").on("change", function(){
$.ajax({
url: url_deploy,
type: "POST",
async: true,
data: { id_cadeau:id, id_status:selectedName}
}).done(function(data){
$("[SuccesDiv]").append("[Succes MSG]");
});
});

Categories

Resources