Refresh form in Django without reloading page - ajax

Hi I'm new in Ajax and django and I want to refresh my form. I try some code but it didn't work. I'm sure what I want to do is very basic.
Here my html:
<div class="row" style="padding-top:20px;">
<div class="col-md-12" id="testAjax">
{% load crispy_forms_tags %}
{% crispy form %}
</div>
</div>
I want to refresh my form in the div testAjax.
Here my view:
def createPin(request):
error = False
if request.method == "POST":
form = CreatePinForm(request.POST)
if form.is_valid():
pin = form.save(commit=False)
pin.customer = request.user.customer
pin.save()
msg = "pin saved"
return redirect('/pin/CreatePin', {'form': form, 'msg': msg})
else:
error = True
else:
form = CreatePinForm()
return render(request, 'createPin.html', {'form': form, 'error': error,})
My Ajax:
function refresh()
{
$form=$('#createPin');
var datastring = $form.serialize();
$.ajax({
type: "POST",
url: '/pin/CreatePin/',
dataType: 'html',
data: datastring,
success: function(result)
{
/* The div contains now the updated form */
$('#testAjax').html(result);
}
});
}
Thanks alot for your help.

When I need to do some operations and I don't want to reload the page I use a JQuery call to Ajax, I make the pertinent operations in AJAX and then receive the AJAX response in the JQuery function without leaving or reloading the page. I'll make an easy example here for you to understand the basics of this:
JQuery function, placed in the template you need
function form_post(){
//You have to get in this code the values you need to work with, for example:
var datastring = $form.serialize();
$.ajax({ //Call ajax function sending the option loaded
url: "/ajax_url/", //This is the url of the ajax view where you make the search
type: 'POST',
data: datastring,
success: function(response) {
result = JSON.parse(response); // Get the results sended from ajax to here
if (result.error) { // If the function fails
// Error
alert(result.error_text);
} else { // Success
//Here do whatever you need with the result;
}
}
}
});
}
You have to realize that I cannot finish the code without knowing what kind of results you're getting or how do you want to display them, so you need to retouch this code on your needs.
AJAX function called by JQuery
Remember you need to add an url for this Ajax function in your urls.py something like:
url(r'^/ajax_url/?$', 'your_project.ajax.ajax_view', name='ajax_view'),
Then your AJAX function, it's like a normal Django View, but add this function into ajax.py from django.core.context_processors import csrf from django.views.decorators.csrf import csrf_exempt from django.utils import simplejson
#csrf_exempt
def ajax_view(request):
response = []
#Here you have to enter code here
#to receive the data (datastring) you send here by POST
#Do the operations you need with the form information
#Add the data you need to send back to a list/dictionary like response
#And return it to the JQuery function `enter code here`(simplejson.dumps is to convert to JSON)
return HttpResponse(simplejson.dumps(response))
So, without leaving the page you receive via javascript a list of items that you sended from ajax view.
So you can update the form, or any tag you need using JQuery
I know that this can be so confusing at the beginning but once you are used to AJAX this kind of operations without leaving or reloading the page are easy to do.
The basics for understanding is something like:
JQuery function called on click or any event you need
JQuery get some values on the template and send them to AJAX via
POST
Receive that information in AJAX via POST
Do whatever you need in AJAX like a normal DJango view
Convert your result to JSON and send back to the JQuery function
JQuery function receive the results from AJAX and you can do
whatever you need

Related

Django: populate modal with a form through Ajax

I´m trying to show a prepopulated form in a modal so users can click on an item, the modal opens showing a form with that item´s data that users can edit and save.
I can send data from a view to a modal with json serializer but I can´t find how to send a form.
When I test this, I get an error declaring that "Object of type FormularioTareas is not JSON serializable"
The problem seems to be clear, I can´t send the form through a json response. How can I handle this?
Thanks in advance!
The modal call in the template
<form name="form" action="#" id="form_tarea_{{tarea.id}}" method="POST">
{% csrf_token %}
<input name="id" id="tarea_id_submit" type="text" value="{{tarea.id}}" hidden="true"/>
<a href="" id="{{tarea.id}}" class="show_tarea" data-toggle="modal" >Este link</a>
</form>
The Ajax script
Here I´m using now $('#caca').text(tarea_data.caca); only to test I can send some info to the modal correctly. It works.
I guess I should update that "text" type to another one in order to work.
<script>
$(function(){
$('.show_tarea').on('click', function (e) {
e.preventDefault();
let tarea_id = $(this).attr('id');
$.ajax({
url:'/catalog/tareas-detail/',
type:'POST',
data: $('#form_tarea_'+tarea_id).serialize(),
success:function(response){
console.log(response);
$('.show_tarea').trigger("reset");
openModal(response);
},
error:function(){
console.log('something went wrong here');
},
});
});
});
function openModal(tarea_data){
$('#caca').text(tarea_data.caca);
$('#modal_tareas').modal('show');
};
</script>
The view
def TareaDetailView(request):
context = {}
tareas = Tareas.objects.values()
context[tareas] = Tareas.objects.all()
if request.method == 'POST' and request.is_ajax():
ID = request.POST.get('id')
tarea = tareas.get(pk=ID) # So we send the company instance
tareas_form = FormularioTareas(tarea)
caca = ID
return JsonResponse(tareas_form, safe=False)
else:
return render(request, 'catalog/artista.html', context)
Django forms are not json serializable. Either pass your model to json response or return your form as text/json.
return JsonResponse(serializers.serialize('json', tarea), safe=False)
I never use django or phyton before but I will try to help you:
First your ajax, try to use a done insteand of success, in this example you are getting info from some select to fill a form inside a modal with specific
function getData(clientId){
return $.ajax({
method: "POST",
url: "YourUrl",
data: { action: "SLC", clientId: clientId}
})
}
then you get your stuff:
getData(clientId).done(function(response){
//manage your response here and validate it
// then display modal, note: you must have some conditions to get the array
//and fill each input use JSON.parse to get the json array elements
openModal(response);
})
hope it helps

Context from Django Render Not Displaying Till Refresh?

I am using an AJAX call to POST a value to my views.
From my views I am finding the product based on the value(id) passed to my view. I add it to my invoice and apply it to my context which I render at the bottom of my view. The context will not be displayed until I refresh, but I can't have that. I am stuck.
...
elif request.is_ajax():
product_id = request.POST.get('value')
if product_id:
product_info = Product.objects.get(id=product_id)
new_invoice_product = InvoiceProduct.objects.create(invoice_product_set=product_info)
invoice.attached_products.add(new_invoice_product)
context['attached_products'] = invoice.attached_products.all()
...
return render(request, 'inventory/invoice_create.html', context)
You can't just re-render client's HTML DOM by your server directly.
Through DjangoTemplate Engine, it just render then respond with HTML itself. This means you can't update client's DOM with ajax unless you update root element, <html>. (and this will be as same as reloading page!)
So you may want to update DOM tree with some data, do with ajax call then update with jsonfile only. If you use JsonResponse, then you can get it with AJAX response object.
Then What you have to do is NOT django template but JavaScript programming.
In your views.py, do like this:
# in your views.py
...
elif request.is_ajax():
product_id = request.POST.get('value')
if product_id:
product_info = Product.objects.get(id=product_id)
new_invoice_product = InvoiceProduct.objects.create(invoice_product_set=product_info)
invoice.attached_products.add(new_invoice_product)
context['attached_products'] = invoice.attached_products.all()
# return render(request, 'inventory/invoice_create.html', context) # NOT render but do like this:
return JsonResponse({
'new_data': {
'id': new_invoice_product.id
# and other informations you want...
}
})
In your HTML, do like this:
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
// in your HTML
// guessing you're using jquery..
$.ajax({
url: "test.html",
context: document.body
}).done(function (json) {
$('yourSelector').append(json['new_data']['id']);
});
</script>
Remember, this code is just snippet not Fully working code. If you want to know further examples, take a look at link:
https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html

How to assign div value to php variable using Jquery Ajax call

I have a href tag, in that i wrote onclick func,
<?php the_post_thumbnail('portfolio_thumbs'); ?>
in the onclick() function the code is,
<script type="text/javascript">
function doThumb(temp)
var tempThmb = temp;
document.getElementById("selectedResult").innerHTML=tempThmb;
return tempThmb;
}
</script>
the returned value, im printing it in an empty div.
<div id="selectedResult" name="selectedResult"></div>';
Now my issue is, im getting the result in the empty div, but i have to pass the value of the div to $my_postid.
$my_postid = "Should pass the value here";//This is page id or post id
$content_post = get_post($my_postid);
How can i achieve this do i have to use ajax jquery, kindly help me....
This is not possible in the way you are doing. PHP is server side language and javascript is client side. One way to do this is to send an ajax request at onclick event of your image. And send the id in ajax request. The ajax will get the post on the base of that id and will return you. Then you can show that post content any where.
update after receiving code of questioner
You don't need to do initial operation in your function. Just change it as below.
function doThumb(temp) {
var $mainCats=temp;
alert ($mainCats);
$.ajax ( {
url:"<?php bloginfo('wpurl'); ?>/wp-admin/admin-ajax.php",
type:'POST',
data:'action=my_special_ajax_callc&main_catidc=' + $mainCats,
onsuccess : function(data) {
$("#selectedResults").removeAttr("disabled");
$("#selectedResults").append(data);
}
} );
}

How do I render a view after POSTing data via AJAX?

I've built an app that works, and uses forms to submit data. Once submitted, the view then redirects back to display the change. Cool. Django 101. Now, instead of using forms, I'm using Ajax to submit the data via a POST call. This successfully saves the data to the database.
Now, the difficult (or maybe not, just hard to find) part is whether or not it's possible to tell Django to add the new item that has been submitted (via Ajax) to the current page, without a page refresh. At the moment, my app saves the data, and the item shows up on the page after a refresh, but this obviously isn't the required result.
If possible, I'd like to use exactly the same view and templates I'm using at the moment - essentially I'd like to know if there's a way to replace a normal HTTP request (which causes page refresh) with an Ajax call, and get the same result (using jQuery). I've hacked away at this for most of today, so any help would be appreciated, before I pull all of my hair out.
I had a very similar issue and this is how I got it working...
in views.py
from django.utils import simplejson
...
ctx = {some data to be returned to the page}
if ajax == True:
return HttpResponse(simplejson.dumps(ctx), mimetype='json')
then in the javascript
jQuery.ajax({
target: '#id_to_be_updated',
type: "POST",
url: "/",
dataType: 'json',
contentType: "text/javascript; charset=\"utf-8\"",
data: {
'foo':foo,
'bar':bar,
},
success: function(data){
$("#id_to_be_updated").append(data.foo);
}
});
Here's how I did it:
The page that has the form includes the form like so
contact.html
{% include "contact_form.html" %}
This way it's reusable.
Next I setup my view code (this view code assumes the contact form needs to be save to the db, hence the CreateView):
class ContactView(CreateView):
http_method_names = ['post']
template_name = "contact_form.html"
form_class = ContactForm
success_url = "contact_form_succes.html"
There are a few things to note here,
This view only accepts pots methods, because the form will be received through the contact.html page. For this view I've setup another template which is what we included in contact.html, the bare form.
contact_form.html
<form method="POST" action="/contact">{% crsf_token %}
{{ form.as_p }}
</form>
Now add the javascript to the contact.html page:
$("body").on("submit", 'form', function(event) {
event.preventDefault();
$("#contact").load($(this).attr("action"),
$(this).serializeArray(),
function(responseText, responseStatus) {
// response callback
});
});
This POSTS the form to the ContactView and replaces whatever is in between #contact, which is our form. You could not use jquery's .load function to achieve some what more fancy replacement of the html.
This code is based on an existing working project, but slightly modified to make explaining what happens easier.

How to avoid redirect after form submission if you have a URL in your form's action?

I have a form that looks like this:
<form name="formi" method="post" action="http://domain.name/folder/UserSignUp?f=111222&postMethod=HTML&m=0&j=MAS2" style="display:none">
...
<button type="submit" class="moreinfo-send moreinfo-button" tabindex="1006">Subscribe</button>
In the script file I have this code segment where I submit the datas, while in a modal box I say thank you for the subscribers after they passed the validation.
function () {
$.ajax({
url: 'data/moreinfo.php',
data: $('#moreinfo-container form').serialize() + '&action=send',
type: 'post',
cache: false,
dataType: 'html',
success: function (data) {
$('#moreinfo-container .moreinfo-loading').fadeOut(200, function () {
$('form[name=formi]').submit();
$('#moreinfo-container .moreinfo-title').html('Thank you!');
msg.html(data).fadeIn(200);
});
},
Unfortunately, after I submit the datas, I'm navigated to the domain given in the form's action. I tried to insert return false; in the code (first into the form tag, then into the js code) but then the datas were not inserted into the database. What do I need to do if I just want to post the data and stay on my site and give my own feedback.
I edited Eric Martin's SimpleModal Contact Form, so if more code would be necessary to solve my problem, you can check the original here: http://www.ericmmartin.com/projects/simplemodal-demos/ (Contact Form)
Usually returning false is enough to prevent form submission, so double check your code. It should be something like this
$('form[name="formi"]').submit(function() {
$.ajax(...); // do your ajax call here
return false; // this prevent form submission
});
Update
Here is the full answer to your comment
I tried this, but it didn't work. I need to submit the data in the succes part, no?
Maybe, it depends from your logic and your exact needs. Normally to do what you asking for I use the jQuery Form Plugin which handle this kind of behavior pretty well.
From your comment I see that you're not submitting the form itself with the $.ajax call, but you retrieve some kind of data from that call, isn't it? Then you have two choices here:
With plain jQuery (no form plugin)
$('form[name="formi"]').submit(function() {
$.ajax(...); // your existing ajax call
// this will post the form using ajax
$.post($(this).attr('action'), { /* pass here form data */ }, function(data) {
// here you have server response from form submission in data
})
// this prevent form submission
return false;
});
With form plugin it's the same, but you don't have to handle form data retrieval (the commented part above) and return false, because the plugin handle this for you. The code would be
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$(form[name="formi"]).ajaxForm(function() {
// this call back is executed when the form is submitted with success
$.ajax(...); // your existing ajax call
});
});
That's it. Keep in mind that with the above code your existing ajax call will be executed after the form submission. So if this is a problem for your needs, you should change the code above and use the alternative ajaxForm call which accepts an options object. So the above code could be rewritten as
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$(form[name="formi"]).ajaxForm({
beforeSubmit: function() { $.ajax(...); /* your existing ajax call */},
success: function(data) { /* handle form success here if you need that */ }
});
});

Resources