Having trouble submitting my form using Dojo - django

I am using Django 1.5 and Dojo 1.8. I am trying to get Dojo to submit a form back to a Django view when I click a button.
Here is my Django view:
def report(request, report_id, report_url=None, template='report_parameters.html'):
if request.method == 'POST':
form = ReportParametersForm(request.POST)
if form.is_valid():
report_params = form.save()
html = "Success!"
return HttpResponse(html)
else:
form = ReportParametersForm()
return render(request,template, {
'form': form,
'report_url': report_url,
'report_id': report_id,
})
Here is the html page:
<div id="report_body">
<form data-dojo-type="dijit/form/Form" id="parameters_form" data-dojo-id="parameters_form">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<p><button id="submit_parameters" dojoType="dijit.form.Button" type="submit">Submit</button></p>
</form>
</div>
<script type="dojo/on" data-dojo-event="submit" data-dojo-args="e">
e.preventDefault();
require(["dojo/dom", "dojo/request", "dojo/dom-form"], function(dom, request, domForm){
on(dom.byId("submit_parameters"), "click", function() {
console.log("Dojo Post");
request.xhr("/report_parameters/report_id/report_url/", {
method: "post",
handleAs: "json",
data: domForm.toJson("parameters_form"),
}).then(
function(response){
alert(response);
dom.byId("report_body").innerHTML = "Report!";
},
function(error){
dom.byId("report_body").innerHTML = "<div class=\"error\">"+error+"<div>";
}
);
});
});
</script>
When I click the Submit button, I want to send a POST request to the url passing the data I have in my form. However, right now when I click Submit, the page reloads with a url looking something like this: /?csrfmiddlewaretoken=Y9gaNMFRWZNXMbJ2L3Ev7A5iKPGTuWeF&param_1=0&param2=0/report_parameters/report_id/report_url/.
I don't see the Dojo Post that should be appearing in my console.
How do I get my form to submit?

This fiddle seems to do what you want.
The major differences seem to be:
The <form> is actually a <div>. The Dojo documentation for Form links to reasons why this is done for IE.
All the related event script is inside the form <div>.
Remove the on(dom.byId("submit_parameters")... code, as there's already a declarative submit event handler.
HTML code:
<div id="report_body"></div>
<div data-dojo-type="dijit/form/Form" id="parameters_form" data-dojo-id="parameters_form" encType="multipart/form-data" action="" method="">
<input name="dummy" value="dummy">
<script type="dojo/on" data-dojo-event="submit" data-dojo-args="e">
console.log("submit");
e.preventDefault();
require(["dojo/dom", "dojo/request/xhr", "dojo/dom-form"], function(dom, xhr, domForm) {
console.log("Dojo Post");
var url = "/report_parameters/report_id/report_url/";
var data = domForm.toJson("parameters_form");
// overwrite url and data for jsfiddle
url = "/echo/json/";
data = {
json: data
};
xhr(url, {
method: "post",
handleAs: "json",
data: data,
}).then(function(response) {
alert(JSON.stringify(response, null, 2));
dom.byId("report_body").innerHTML = "Report!";
}, function(error) {
dom.byId("report_body").innerHTML = "<div class=\"error\">" + error + "<div>";
});
});
</script>
<button data-dojo-type="dijit/form/Button" id="submit_button" type="submit" name="submitButton" value="Submit">Submit</button>
</div>
JS code:
require(["dojo/parser", "dijit/registry", "dijit/form/Form", "dijit/form/Button", "dijit/form/ValidationTextBox", "dijit/form/DateTextBox", "dojo/domReady!"], function (parser, registry) {
parser.parse().then(function () {
console.log("parsed");
console.log(registry.byId("parameters_form"));
console.log(registry.byId("submit_button"));
});
});

I had to modify the above slightly. This is what eventually worked for me:
<div id="report_body"></div>
<form data-dojo-type="dijit/form/Form" id="parameters_form" data-dojo-id="parameters_form" encType="multipart/form-data" action="" method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<script type="dojo/on" data-dojo-event="submit" data-dojo-args="e">
e.preventDefault();
require(["dojo/dom", "dojo/request/xhr", "dojo/dom-form"], function(dom, xhr, domForm){
var url = "/report_parameters/report_id/report_url/"
var data = domForm.toObject("parameters_form")
xhr(url, {
method: "post",
data: data,
}).then(
function(response){
alert(response);
dom.byId("report_body").innerHTML = "Report!";
},
function(error){
dom.byId("report_body").innerHTML = error;
}
);
});
</script>
<p><button id="submit_parameters" dojoType="dijit/form/Button" type="submit" name="submitButton" value="Submit">Submit</button></p>
</form>
Using either the <div> or <form> tags to wrap the whole thing worked for me.

Related

got problem in the ajax form submission code

<form action="" method="post" class="f-color" id="email-form">
{% csrf_token %}
<label>Name</label>
<input type="text">
<label>From</label>
<input type="email">
<label>Message</label>
<button type="submit">Sent</button>
</form>
<div class="mt-5" id="spin" style="display: none;">
<div class="loader"></div>
</div>
<div id="msg"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(document).on("submit", "#email-form", function(event){
event.preventDefault();
$('#spin').show();
$.ajax({
url: "{% url 'contact' %}",
type: "POST",
data: $("#email-form").serialize(),
success: function(data){
$("#spin").hide();
if(data.status == "success"){
$("#msg").html("<p class='alert alert-success'>we will get back to you as soon as possible</p>" );
$("#email-form").reset();
}
}
})
})
})
</script>
using this code I can submit the form successfully, but after the form submission the message(msg) not showing, the 'if condition statement' is perfectly working (for the testing I gave the alert, the alert was worked)
another problem is form reset, for this I'm using
$("#email-form").reset();
but the form dose't reset
how can I solve these problems
try
$('#email-form')[0].reset();
https://stackoverflow.com/a/3786702/8640027
I got a solution for the resetting form after the ajax form submission
$("#email-form").trigger("reset");

How to solve problem "Must be a valid json" - Django + Vue js

I try to create object in Django with vue js + axios but somehowe this not work for me. I try in two ways and always I see in vue dev tools empty data. When I fill the data model in vuedev tools I see "Invalid value "Must be a valid Json"".
First way. I create a view that return jsonresponse.
#login_required
def save_embed(request):
if request.method == "POST":
form = SubmitEmbed(request.POST)
if form.is_valid():
url = form.cleaned_data['url']
r = requests.get('http://iframe.ly/api/oembed?url='+ url + '&api_key=' + IFRAMELYKEY)
data = r.json()
serializer = EmbedSerializer(data=data, context={'request': request})
if serializer.is_valid():
embed = serializer.save()
return JsonResponse(serializer.data, status=201, content_type="application/json", safe=False)
return JsonResponse(serializer.errors, status=400)
else:
form = SubmitEmbed()
return render(request, 'embed/embedadd.html', {'form': form})
Template:
<script>
new Vue({
el: '#app',
delimiters: ['!!', '!!'],
data () {
return {
url: "http://example.com"
}
},
methods: {
formSubmit(e) {
e.preventDefault();
let currentObj = this;
this.axios.post('http://wege.local:8000/recipes/recipe/embed/add/', {
url: this.url,
})
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
}
}
});
</script>
Form:
<div id="app">
!! url.title !!
<form method="post" class="margin-bottom-25" #submit="formSubmit">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-success-gradiant">Dodaj link</button>
</form>
</div>
In the url field has been added v-model "url".
as you can see in the screenshot below, when I fill in the url field, nothing happend
Second way is to create endpoint with rest framework in Django and then create templateview with code:
<div id="app">
<form method="post" class="margin-bottom-25" #submit="formSubmit">
{% csrf_token %}
<div class="form-group">
<label for="formGroupExampleInput">Adres przepisu*</label>
<input type="url" class="form-control" id="formGroupExampleInput" placeholder="Url" v-model="embed.url">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Tytuł</label>
<input class="form-control" id="formGroupExampleInput2" placeholder="Title" v-model="embed.title">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Description</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Description" v-model="embed.description">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Thumbnail_url</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Tthumbnail_url" v-model="embed.thumbnail_url">
</div>
<button type="submit" class="btn btn-success-gradiant">Dodaj link</button>
</form>
!! embed.title !!
!! embed.url !!
</div>
Vue js:
<script>
new Vue({
el: '#app',
delimiters: ['!!', '!!'],
data () {
return {
embed:{
url: 'http://example.com',
title: '',
description: '',
thumbnail_url: '',
}
}
},
methods: {
formSubmit(e) {
e.preventDefault();
let currentObj = this;
this.axios.post('http://wege.local:8000/recipes/embeds/', this.embed)
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
}
}
});
</script>
In the second case the same problem, in vue tools the fields are still empty after completing the form.
I think your response is okay.
When/where do you define or gloabally bind axios to this? You keep trying this.axios, which does not exist. More on Vue instance properties here.
Unless I'm missing where you bind this.axios...
You need to import axios from "axios"; and do axios.post(...)
To see if your request is going out, try looking at the network tab in dev tools and see the requests that go out with the data! I see you're using firefox, check out the docs here

Django and Ajax refreshing a div

I am very new to JS/Ajax and a relative novice to Django. I am testing to see how I can get information back and forth from an Ajax call to my view, and back to Ajax to replace a header string as a simple test.
I can receive information back to my view (h1, which is "AJAX TEST"). What I can't seem to get is the h2text to change to "HEADER CHANGED".
Any help is appreciated as I don't know if it's my Django return function or my Ajax function.
Here is my ajax_test.html:
<div class="content">
<div class="center">
<h1 id="h1">AJAX TEST</h1>
<div>
<button id="btn">PRESS ME</button>
</div>
</div>
<div id="update_div">
{% include "ProdPlat/ajax_test_div.html" %}
</div>
</div>
<script type="text/javascript" src="{% static 'ProdPlat\js\ajax_test.js' %}"></script>
{% endblock %}
My ajax_test_div.html (which I'm trying to refresh):
<div class="content">
<div class="center">
<h2 id="h2">{{h2text.h2text}}</h2>
</div>
</div>
My views_test.py:
def test_ajax(request):
h2text = {'h2text': "INITIAL HEADER"}
if request.method == 'POST':
logger.debug('POST request')
text = request.POST.get('text')
logger.debug('text = {}'.format(text))
h2text = "HEADER CHANGED"
dict = {
'h2text': h2text,
}
# return JsonResponse(dict)
# return render(request, 'ProdPlat/ajax_test_div.html', {'h2text': h2text})
return render_to_response('ProdPlat/ajax_test_div.html', dict)
return render(request, 'ProdPlat/ajax_test.html', {'h2text': h2text})
And finally my Ajax call:
$(document).on('click', 'button', function(){
var csrftoken = getCookie('csrftoken');
console.log('Button Clicked!');
var text = $('h1').text()
console.log('h1 text = ' + text);
$.ajax({
type : 'POST',
url : "/ProdPlat/Ajax_Test/",
dataType: 'json',
data: {'text' : text,
'csrfmiddlewaretoken': csrftoken,
},
success: function(data) {
console.log('data = ' + data);
console.log('data.h2text = ' + data.h2text);
$('#update_div').load(' #update_div')
console.log('Success!');
},
failure: function(data) {
console.log('Failed!');
console.log('data = ' + data);
},
})
})

Django - POST method not working for those forms created within a FOR loop in template

I'm using a for loop in a template to create multiple forms with method="post" that work with Ajax. But only the form for the first element of items_list works fine, the rest do not work at all showing error 405 0 Method Not Allowed. I think they all should work the same way. And just wondering if this issue was caused by a for loop or something else.
cart_items.html:
<script>
$(document).ready(function () {
$("#remove").click(function (event) {
event.preventDefault();
$.ajax({
url: '{% url "cart:remove_from_cart" %}',
type: "POST",
dataType: 'json',
data: {bookID: $('#idInput').val()},
success: function (response_data) {
alert('works fine')
},
error: function (response_data) {
console.log('error occurred');
}
});
});
});
</script>
{% for book in items_list %}
<div class="items">
<p id="title"> {{ book.book.title }}, quantity: {{ book.quantity }} </p>
<form method="post">
{% csrf_token %}
<input id="idInput" value="{{ book.book.id }}" >
<button id="remove" type="submit"> Remove</button>
</form>
</div>
{% endfor %}
The code in the function body below is just for testing. Once the first form works, I guess the problem was not caused by the function view.
cart/views.py:
#csrf_exempt
def remove_books(request):
cart = Cart.objects.get(user=request.user)
if request.method == 'POST':
passed_id = request.POST['bookID']
secured_id = int(passed_id)
response_data = {
'quantity': secured_id
}
return JsonResponse(response_data)
<script>
$(document).ready(function () {
$(".remove").click(function (event) {
// event.preventDefault(); // don't think it should be required with button type=button
var book_id = $(this).parent().find('.idInput').val(); // find correct input box.
var csrf = $('input[name="csrfmiddlewaretoken"]').val(); // get csrf token in variable.
// there are multiple ways to get csrf token, I personally like this ^^, see https://docs.djangoproject.com/en/2.1/ref/csrf/#ajax for more
$.ajax({
url: '{% url "cart:remove_from_cart" %}',
type: "POST",
dataType: 'json',
data: {
bookID: book_id,
csrfmiddlewaretoken: csrf // add csrf token to post data
},
success: function (response_data) {
alert('works fine')
},
error: function (response_data) {
console.log('error occurred');
}
});
});
});
</script>
{% csrf_token %} <!-- It will render a hidden input field with csrf token in it. Keep it outside for loop but in html. No need to render exactly same element multiple times. -->
{% for book in items_list %}
<div class="items">
<p class="title"> {{ book.book.title }}, quantity: {{ book.quantity }} </p>
<form method="post">
<input class="idInput" value="{{ book.book.id }}" > <!-- use class not id -->
<button class="remove" type="button"> Remove</button> <!-- you can use button type=button to avoid form submit and hence avoid event.preventDefault(); in js -->
</form>
</div>
{% endfor %}

Does Making an AJAX call make a DJANGO form Invalid?

I make an ajax call to my server using the change event on a select widget. Does this cause the Django Form to be invalid? Here is an example of the code.
JAVASCRIPT
<form class="form-horizontal" action="{% url 'accountSelections' %}" method="post">
{% csrf_token %}
<div class="form-group">
<div class="row">
<div class="col-md-4">
{{ account_selection_form|crispy }}
<input class="btn btn-primary" id="button" type="Submit" value="Next >>">
</div>
<div class="col-md-4">
</div>
<div class="col-md-4">
<div id="grid"></div>
</div>
</div>
</div>
</form>`
$( document ).ready(function() {
$("#id_excludeClassification").SumoSelect();
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
$( "#id_acctFilterName" ).change(function() {
var data = "";
$.ajax({
type:"GET",
url : "../filter",
data : "id="+$(this).val(),
csrfmiddlewaretoken: token,
success : function(response) {
$("#grid").kendoGrid({
data: response,
height: 550,
groupable: true,
sortable: true,
columns: [
{
field: "acctCd",
title: "Code"
}, {
field: "shortName",
title: "Account Name"
}]
});
var grid = $("#grid").data("kendoGrid");
dataSource = new kendo.data.DataSource({
data: response
});
grid.dataSource = dataSource;
dataSource.read();
grid.refresh();
data = response;
return response;
},
error: function() {
alert('Error occured');
}
});
});
});
Does a form submit after cause this to make the form invalid?
My understanding is that you can submit multiple times with the same CSRF token, so it shouldn't be a problem.
you put your csrfmiddlewaretoken variable out data object that you send to your server then it can't work.
Here is what you have to do :
data : {
id : $(this).val(),
csrfmiddlewaretoken: token,
}