I am trying to implement AJAX in django. I have the following file login.html
This file contains the form and ajax script
{% extends 'services/base_visitor.html' %}
{% block title %}Log In{% endblock %}
{% block login_active %}active{% endblock %}
{% block body %}
<div class="container-fluid" style="position: absolute;top:20%;left:35%;width:30%;">
<div class="panel panel-default">
<h3>       Log In</h3>
<center>
<div class="panel-body">
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<!-- action="{% url 'login_user'%}" -->
<form class="form-horizontal" role="form" action="{% url 'login_user'%}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<!-- <label class="control-label col-sm-2" for="id_username">
</label> -->
<div class="col-sm-10">
<strong><span class="glyphicon glyphicon-user"></strong>   
<input id="id_username" maxlength="30" name="id_username" type="text" placeholder="USERNAME" style="font-family: Courier New;font-size: 15px;border: none; border-bottom: 2px solid black;">
<div id="data"></div></span>
</div>
</div>
<div class="form-group">
<!-- <label class="control-label col-sm-2" for="id_password">
</label> -->
<div class="col-sm-10">
<strong><span class="glyphicon glyphicon-asterisk"></strong>   
<input id="id_password" maxlength="30" name="id_password" type="password" placeholder="PASSWORD" style="font-family: Courier New;font-size: 15px; border: none; border-bottom: 2px solid black;"></span>
</div>
</div>
</center>
<div class="form-group">
                   <button type="submit" class="btn btn-success">Submit</button>
</div>
</form>
</div>
<div class="panel-footer">
Don't have an account? Click here to register.
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
<script>
$("#id_username").change(function(){
alert("The text has been changed.");
});
$("#id_username").change(function () {
var username = $("#id_username").val();
console.log(username);
$.ajax({
type:"POST",
url: '/ajax/validate_username/',
data:{
str:username,
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
dataType: 'json',
success: function (data) {
// alert("done")
$("#data").html(data);
}
});
});
</script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
{% endblock %}
Following is my urls.py
look for validate_username
from django.conf.urls import url
from . import views
from django.contrib import admin
from django.urls import path
from services import views as user_views
app_name = 'services'
urlpatterns = [
path('admin/', admin.site.urls),
path('register/', user_views.register, name='register'),
path('base/', user_views.base, name='base'),
path('login/', user_views.login_user, name='login_user'),
path('index/', user_views.index, name='index'),
path('login/', user_views.logout_user, name='logout_user'),
# path(r'^signup/$', views.SignUpView.as_view(), name='signup'),
url(r'^ajax/validate_username/$', user_views.validate_username, name='validate_username'),
]
Following is my views.py
I check if the user is already present, if yes, then I return Success else I return Not Success.
from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth import logout
from .forms import UserForm
from .models import UserProfile, Customer, Seller, User
from django.http import *
def validate_username(request):
if request.method == 'POST':
username = request.POST.get('str',None)
# print(username)
data = {
'is_taken': user.objects.filter(username=username).exists()
}
if data.is_taken:
return HttpResponse("Success!")
else:
return HttpResponse("NOT Success!")
Whenever the user enters any text in username field my ajax request should come in action. However, this intended action is not done. Anyone, please clarify.
I also tried to print alerts using jquery, but it also doesn't seem to be working.
I think the problem is the binding try this:
window.onload = function() {
// add your code change here
$("#id_username").change(function(){
alert("The text has been changed.");
});
$("#id_username").change(function () {
var username = $("#id_username").val();
console.log(username);
});
}
or
$(document).ready= function() {
// add your code change here
$("#id_username").change(function(){
alert("The text has been changed.");
});
$("#id_username").change(function () {
var username = $("#id_username").val();
console.log(username);
});
}
Related
I have an error on login form after upgrading version Vue JS, Axios, Laravel.
This project code working well with old version. Anyone can explain this serious errors.
Thanks you for your help!
And I stuck with it many days. I've search for similar post error, but only seen this(POST http://127.0.0.1:8000/ 422 (Unprocessable Entity)).
<template>
<div class="back-img" :style="`background-image: url('${appUrl}/images/background/default-background.jpg')`">
<div class="container-fluid">
<div class="row">
<div class="col-12 col-md-6 offset-md-6 col-lg-4 offset-lg-8 col-xl-4 offset-xl-8 pl-0">
<div class="sign-in-sign-up-content">
<form class="sign-in-sign-up-form">
<div class="text-center mb-4 application-logo">
<img :src="publicPath+'/uploads/logo/'+appLogo" alt="" class="img-fluid logo">
</div>
<div class="form-row">
<div class="form-group col-12">
<h3 class="text-center mb-0">
{{ trans('lang.hi_there') }}
</h3><br>
<label class="text-center d-block">
{{ trans('lang.sign_in_to_your_dashboard') }}
</label>
</div>
</div>
<div v-if="alertMessage.length>0" class="alertBranch">
<div class="alert alert-warning alertBranch" role="alert">
{{alertMessage}}
</div>
</div><br>
<div class="form-row">
<div class="form-group col-12">
<label for="username" style="font-size: 20px;"> {{ trans('lang.login_username') }}</label>
<input id="username"
v-validate="'required'"
v-model="username"
type="text"
name="username"
class="form-control"
:placeholder="trans('lang.enter_username')"
:class="{ 'is-invalid': submitted && errors.has('username') }">
<div class="heightError" v-if="submitted && errors.has('username')">
<small class="text-danger" v-show="errors.has('username')">
{{ errors.first('username') }}
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-12">
<label for="password" style="font-size: 20px !important;">{{ trans('lang.login_password') }}</label>
<input id="password"
v-validate="'required'"
ref="password"
v-model="password"
name="password"
type="password"
class="form-control"
:placeholder="trans('lang.enter_password')"
:class="{ 'is-invalid': submitted && errors.has('password') }">
<div class="heightError">
<small class="text-danger" v-show="errors.has('password')">
{{ errors.first('password') }}
</small>
</div>
</div>
</div>
<div class="form-row loginButton">
<div class="form-group col-12">
<common-submit-button class="btn-block text-center auth-button"
style="font-size: 20px !important;"
:buttonLoader="buttonLoader"
:isDisabled="isDisabled"
:isActiveText="isActiveText"
buttonText="login"
v-on:submit="loginPost"/>
</div>
</div>
<!-- <div class="form-row">
<div class="form-group col-12">
<a href="#"
#click="forgetPassword"
class="bluish-text">
<i class="fa fa-lock"/>
{{ trans('lang.forgot_password') }}
</a>
</div>
</div> -->
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axiosGetPost from '../../helper/axiosGetPostCommon';
export default {
extends: axiosGetPost,
props: ['checkusername', 'checkpass'],
data() {
return {
username: this.checkusername,
name: '',
password: this.checkpass,
remember: true,
buttonLoader: false,
isActiveText: false,
isDisabled: false,
preLoaderType: 'load',
hidePreLoader: false,
isActive: 'active',
alertMessage: '',
submitted: false,
}
},
methods: {
loginPost() {
this.submitted = true,
this.$validator.validateAll().then((result) => {
if (result) {
this.inputFields = {
username: this.username,
password: this.password,
};
this.buttonLoader = true;
this.isDisabled = true;
this.isActiveText = true;
this.loginPostMethod('/', {
username: this.username,
password: this.password,
}
);
}
});
},
forgetPassword() {
let instance = this;
instance.redirect('/password/reset');
},
loginPostSucces(response) {
let instance = this;
instance.redirect("/sales");
},
loginPostError(response) {
let instance = this;
instance.buttonLoader = false;
instance.isDisabled = false;
instance.isActiveText = false;
instance.alertMessage = response.data.errors.username[0];
},
}
}
</script>
File: resources\assets\js\js\bootstrap.js
window._ = require('lodash');
window.Popper = require('popper.js').default;
import axios from "axios";
try {
window.$ = window.jQuery = require('jquery');
require('bootstrap');
} catch (e) {}
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
if (document.querySelector('meta[name="csrf-token"]')) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
}
You have to pass the csrf token in Ajax request.
data: {
"_token": "{{ csrf_token() }}",
other form data
}
OR
You can create csrf token in header using meta element and access that value in while sending ajax request.
<meta name="csrf-token" content="{{ csrf_token() }}" />
// Access in ajax request like below
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
Laravel + Vue + Axios
Laravel has configurd the default token header in resources/js/bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
So you have to just import axios like.
import axios from 'axios';
In http://127.0.0.1:5000/:
If defaults are "0", message in each field: "This field is required".
There are the message "csrf_token CSRF Token" above "compute0" and "compute1".
Only compute0 works.
click on compute0 shows the resulted.
click on compute1 showns nothing.
form and form1 have 3 inputs.
compute0 and compute1 call (math.sin(r))* t + u.
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import TextField, BooleanField, PasswordField, TextAreaField, validators
from compute import compute
from model import InputForm, InputForm1
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Thisisasecret'
#app.route('/', methods=['GET', 'POST'])
def index():
form = InputForm(request.form)
form1 = InputForm1(request.form)
if form.validate_on_submit():
if request.method == 'POST':
r = form.r.data
t = form.t.data
u = form.u.data
s = compute(r,t,u)
else:
s = None
return render_template("view.html", form=form, form1=form1, s=s)
if form1.validate_on_submit():
if request.method == 'POST':
r1 = form1.r1.data
t1 = form1.t1.data
u1 = form1.u1.data
s1 = compute(r1,t1,u1)
else:
s1 = None
return render_template("view.html", form=form, form1=form1, s1=s1)
return render_template("view.html",form=form, form1=form1)
if __name__ == '__main__':
app.run(debug=True)
from flask_wtf import FlaskForm
from wtforms import validators, StringField, PasswordField,FloatField, validators
class InputForm(FlaskForm):
r = FloatField(label='var_r',default=0,validators=[validators.DataRequired()])
t = FloatField(label='var_t',default=0,validators=[validators.DataRequired()])
u = FloatField(label='var_u',default=0,validators=[validators.DataRequired()])
class InputForm1(FlaskForm):
r1 = FloatField(label='var_r1',default=0,validators=[validators.DataRequired()])
t1 = FloatField(label='var_t1',default=0,validators=[validators.DataRequired()])
u1 = FloatField(label='var_u1',default=0,validators=[validators.DataRequired()])
import math
def compute(r,t,u):
return (math.sin(r))* t + u
<form method="post" action="">
{{ form.csrf_token }}
{% for field in form %}
<dt>{{ field.name }}
<dd>{{ field|safe }} {{field.label }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}</ul>
{% endif %}</dd>
{% endfor %}
<p><input type=submit value=Compute0></form></p>
<h5> Valor: </h5>
<p>
{% if s != None %}
{{ s }}
{% endif %}
</p>
<form method="post" action="">
{{ form.csrf_token }}
{% for field in form1 %}
<dt>{{ field.name }}
<dd>{{ field|safe }} {{field.label }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}</ul>
{% endif %}</dd>
{% endfor %}
<p><input type=submit value=Compute1></form></p>
<h5> Valor: </h5>
<p>
{% if s1 != None %}
{{ s1 }}
{% endif %}
</p>
if i understand your description, you have 2 independent forms on the same page that both send POST requests to the same view function to process.
you want to update the placeholder below of each form depending on which form is already submitted, here i think you need to perform an ajax call since (based on your code above) there's no way to keep or persist the data of the other form (database for e.g)
so to do:
update the code of the Form InputForm
since the 2 forms have the same fields you need just one for this use case and then adapt and extend the logic for other forms with different set of fields
from flask_wtf import FlaskForm
from wtforms.fields import FloatField, SubmitField
from wtforms.validators import DataRequired
class InputForm(FlaskForm):
r = FloatField('r', validators=[DataRequired()])
t = FloatField('t', validators=[DataRequired()])
u = FloatField('u', validators=[DataRequired()])
submit = SubmitField('Submit')
update the template
<!-- the first form -->
<form class="form" id="form-1" method="POST" novalidate>
{{ form_1.csrf_token }}
<div class="row">
<div class="col">
<div class="form-group row">
<div class="col-sm-3">
{{ form_1.r.label(class="col-form-label") }} <span class="text-danger">*</span>
</div>
<div class="col-sm-9">
{{ form_1.r(class="form-control rounded-0 shadow-none", **{"placeholder":"0"}) }}
<div class="invalid-feedback"></div>
</div>
</div>
</div>
<div class="col">
<div class="form-group row">
<div class="col-sm-3">
{{ form_1.t.label(class="col-form-label") }} <span class="text-danger">*</span>
</div>
<div class="col-sm-9">
{{ form_1.t(class="form-control rounded-0 shadow-none", **{"placeholder":"0"}) }}
<div class="invalid-feedback"></div>
</div>
</div>
</div>
<div class="col">
<div class="form-group row">
<div class="col-sm-3">
{{ form_1.u.label(class="col-form-label") }} <span class="text-danger">*</span>
</div>
<div class="col-sm-9">
{{ form_1.u(class="form-control rounded-0 shadow-none", **{"placeholder":"0"}) }}
<div class="invalid-feedback"></div>
</div>
</div>
</div>
</div>
<div class="form-group row d-flex justify-content-between border bg-light p-3">
{{ form_1.submit(class="btn btn-sm btn-primary rounded-0 shadow-none") }}
<span class="placeholder">sin(r) * t + u = 0.00</span>
</div>
</form>
<!-- the second form -->
<form class="form" id="form-2" method="POST" novalidate>
{{ form_2.csrf_token }}
<div class="row">
<div class="col">
<div class="form-group row">
<div class="col-sm-3">
{{ form_2.r.label(class="col-form-label") }} <span class="text-danger">*</span>
</div>
<div class="col-sm-9">
{{ form_2.r(class="form-control rounded-0 shadow-none", **{"placeholder":"0"}) }}
<div class="invalid-feedback"></div>
</div>
</div>
</div>
<div class="col">
<div class="form-group row">
<div class="col-sm-3">
{{ form_2.t.label(class="col-form-label") }} <span class="text-danger">*</span>
</div>
<div class="col-sm-9">
{{ form_2.t(class="form-control rounded-0 shadow-none", **{"placeholder":"0"}) }}
<div class="invalid-feedback"></div>
</div>
</div>
</div>
<div class="col">
<div class="form-group row">
<div class="col-sm-3">
{{ form_2.u.label(class="col-form-label") }} <span class="text-danger">*</span>
</div>
<div class="col-sm-9">
{{ form_2.u(class="form-control rounded-0 shadow-none", **{"placeholder":"0"}) }}
<div class="invalid-feedback"></div>
</div>
</div>
</div>
</div>
<div class="form-group row d-flex justify-content-between border bg-light p-3">
{{ form_2.submit(class="btn btn-sm btn-primary rounded-0 shadow-none") }}
<span class="placeholder">sin(r) * t + u = 0.00</span>
</div>
</form>
in your view function (here i just i isolated the logic in Blueprint #bp):
from flask import Blueprint, render_template, request, jsonify
from .forms import InputForm
from .utils import compute
bp = Blueprint(
'home',
__name__,
static_folder='static',
static_url_path='/home/static',
template_folder='templates',
# url_prefix=None,
# subdomain=None,
# url_defaults=None,
# root_path=None,
# cli_group=<object object>
)
#bp.route('/', methods=['GET', 'POST'])
def index():
form_1 = InputForm()
form_2 = InputForm()
if request.method == 'POST':
# we handle the "POST" request of the submitted "form_1"
if form_1.validate_on_submit():
r = form_1.r.data
t = form_1.t.data
u = form_1.u.data
s = compute(r,t,u)
return jsonify(s=s if s else 0, errors={})
else:
return jsonify(s=0, errors=form_1.errors)
# we handle the "POST" request of the submitted "form_2"
if form_2.validate_on_submit():
r = form_2.r.data
t = form_2.t.data
u = form_2.u.data
s = compute(r,t,u)
return jsonify(s=s if s else 0, errors={})
else:
return jsonify(errors=form_2.errors)
return render_template("home/index.html", form_1=form_1, form_2=form_2)
the ajax part:
i suggest you my answer on how to take advantage of jinja2 template inheritance to insert locally a js (the same with css) blocks for particular page.
base on, i assume your are using jquery and since we want jinja2 to render this javascript line url: "{{ url_for('home.index') }}", so in your template add this code
$(document).ready(function() {
"use strict";
$('.form').submit(function(e) {
e.preventDefault();
// get the id of the form currently submitted
let id = $(this).attr('id');
$.ajax({
url: "{{ url_for('home.index') }}",
type: 'POST',
cache: false,
dataType: 'json',
data: $('#' + id).serialize(), // serialize the form
success: function(data) {
// console.log(data);
// sanitize the form before processing the submitted fields
if( ! data.errors.hasOwnProperty('r')){
$('#' + id + ' input[name=r]').removeClass('is-invalid').next(".invalid-feedback").text('');
}
if( ! data.errors.hasOwnProperty('t')){
$('#' + id + ' input[name=t]').removeClass('is-invalid').next(".invalid-feedback").text('');
}
if( ! data.errors.hasOwnProperty('u')){
$('#' + id + ' input[name=u]').removeClass('is-invalid').next(".invalid-feedback").text('');
}
// #see https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
if( ! jQuery.isEmptyObject(data.errors)) { // Errors (data.errors = {})
console.log('Errors');
if(data.errors.hasOwnProperty('r')){
$('#' + id + ' input[name=r]').addClass('is-invalid').next(".invalid-feedback").text(data.errors['r']);
}
if(data.errors.hasOwnProperty('t')){
$('#' + id + ' input[name=t]').addClass('is-invalid').next(".invalid-feedback").text(data.errors['t']);
}
if(data.errors.hasOwnProperty('u')){
$('#' + id + ' input[name=u]').addClass('is-invalid').next(".invalid-feedback").text(data.errors['u']);
}
// update placeholder with the returned value
$('#' + id + ' .placeholder').html('sin(r) * t + u = ' + data.s);
} else { // Passed
console.log('Passed');
// get the submitted fields
let r = $('#' + id + ' input[name=r]').val();
let t = $('#' + id + ' input[name=t]').val();
let u = $('#' + id + ' input[name=u]').val();
// update placeholder with the returned value
$('#' + id + ' .placeholder').html('sin(' + r + ') * ' + t + ' + ' + u + ' = ' + data.s);
// reset fields
$('#' + id + ' input[name=r]').val('');
$('#' + id + ' input[name=t]').val('');
$('#' + id + ' input[name=u]').val('');
}
}
});
});
});
and finally this a
hope this solves your issue.
i am trying to insert data into the database using django and ajax.
i have a form that allow user to enter data into the text fileds and to choose between 2 options using radio button.
the problem is when i try to enter the path the system display the below error :
ValueError at /addperson/ The view map.views.addperson didn't return
an HttpResponse object. It returned None instead.
models.py
class Person(models.Model):
boolChoice = (
("Male","M"),("Female","F")
)
name = models.CharField(max_length=50)
date = models.DateField()
description = models.TextField()
gender = models.BooleanField(choices= boolChoice)
def __str__(self):
return str(self.name)
addPerson.html
{% extends 'base.html' %}
{% block content %}
<div class="hero__content">
<form method="POST" class="form-style-9">{% csrf_token %}
{{ form.as_p }}
<ul>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<li>
<h2>Add Member</h2>
</li>
<li>
<input type="text" name="name" class="field-style field-split align-right" placeholder= "enter ur name " id="name"/>
</li>
<li>
<input type="date" name="date" class="field-style field-full align-none" placeholder= " your birthdate" id="birthdate" />
</li>
<li>
<input type="radio" name="gender" id="male" value="male"> Male<br>
<input type="radio" name="gender" id="female" value="female"> Female<br>
</li>
<li>
<textarea name="description" class="field-style" placeholder= "introduce yourself " id="description"></textarea>
</li>
<li>
<input type="submit" class="field-style field-full align-none" id="save" value="ADD" />
<script type="text/javascript">
$(function(){
$('#save').on('click',function(e){
e.preventDefault()
name=$('#name').val()
birthdate=$('#birthdate').val()
description=$('#description').val()
radioValue = $("input[name = 'gender']:checked").val()
alert("radioValue =", radioValue)
$.ajax({
url:'/addperson/',
method:'POST',
data: {
na:name,
bi:birthdate,
de:description,
ra:radioValue
},
headers:{
'X-CSRFToken':'{{csrf_token}}'
}
}).done(function(msg) {
document.location = "/home.html"
alert('data saved')
}).fail(function(err){
alert('failed')
})
})
})
</script>
</li>
</ul>
</form>
</div>
{% endblock %}
views.py
def addperson(request):
if request.method == "POST":
name = request.POST['na']
birthdate = request.POST['bi']
description=request.POST['de']
radiovalue=request.POST['ra']
person=Person.objects.create(
name=name,
date=birthdate,
description=description,
gender=radiovalue
)
person.save()
return render(request,'./home.html')
urls.py
from django.urls import path, include
from django.contrib import admin
from map import views as mapviews
admin.autodiscover()
urlpatterns = [
path('admin/', admin.site.urls),
path('', mapviews.index),
path('addperson/',mapviews.addperson),
]
i solved the problem because i was getting the form using GET method so i create a path that allow the user to get the form by POST method
What I am trying to do ?
I am trying to display a comment after posting it without page refresh.
What is the problem ?
I am able to successfully post the comment but I am not able to display it without page refresh.
My code:-
html
// This is where you can write a comment.
<form id='articleCommentForm'>{% csrf_token %}
<textarea placeholder='write comment'></textarea>
<button type="submit"> Comment </button>
</form>
// This is where previous comments get displayed
{% for comment in comments %}
<br /> <br />
<div class="row" class="commentStyle">
<div class="col-xs-10">
<span class="userName"> {{ comment.user }} </span>
<br /> <br />
<div class="comment-box">
<textarea class="form-control" readonly> {{ comment.text }} </textarea>
</div>
<br />
<div class="row">
<div class="col-xs-6">
<span class="comment-footer-text"> {{ comment.date }} </span>
</div>
<div>
<div class="comment-control">
<span> {{ comment.likes }} </span>
<span></span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
ajax
$('#articleCommentForm').on('submit',function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '/articles/postComment/',
data: {
'comment': $('#articleCommentForm textarea').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
},
dataType: 'json',
success: function(data){
var comment = JSON.parse(data['comment']);
$('.commentStyle .userName').val(comment.user);
$('.commentStyle textarea').val(comment.text);
$('.commentStyle .comment-footer-text').val(comment.date);
$('.commentStyle .comment-control span:first-child').val(comment.likes);
}
});
)};
views.py
def postComment(request):
if request.user.is_authenticated():
comment = Comment()
comment.user = request.user
comment.text = request.POST.get('comment')
comment.date = datetime.now()
comment.save()
curComment = serializers.serialize('json', [comment])
data['comment'] = curComment
return JsonResponse(data)
Any help would be highly appreciated.
For this functionality we should take a new partial template to render the comment and return the rendered html to be added to the HTML DOM.
single_comment.html
<div class="col-xs-10">
<span class="userName"> {{ comment.user }} </span>
<br /> <br />
<div class="comment-box">
<textarea class="form-control" readonly> {{ comment.text }} </textarea>
</div>
<br />
<div class="row">
<div class="col-xs-6">
<span class="comment-footer-text"> {{ comment.date }} </span>
</div>
<div>
<div class="comment-control">
<span> {{ comment.likes }} </span>
<span></span>
</div>
</div>
</div>
</div>
views.py
from django.shortcuts import render
def postComment(request):
if request.user.is_authenticated():
comment = Comment()
comment.user = request.user
comment.text = request.POST.get('comment')
comment.date = datetime.now()
comment.save()
return render(request, 'partial/comment.html', {'comment': comment})
ajax
$.ajax({
type: 'POST',
url: '/articles/postComment/',
data: {
'comment': $('#articleCommentForm textarea').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
},
dataType: 'json',
success: function(data){
$('.commentStyle').append(data)
}
});
I'm creating my first Userfrosting app and trying a few simple things but falling at the first hurdle. I am trying to create a form which adds bands to a database table:
CREATE TABLE `uf_band` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`band_name` text NOT NULL,
`band_description` longtext NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
initialize.php:
$table_band = new \UserFrosting\DatabaseTable($app->config('db')['db_prefix'] . "band", [
"band_name",
"band_description",
"created_at",
"modified_at"
]);
index.php for the routes:
$app->get('/bands/new/?', function () use ($app) {
$controller = new UF\BandController($app);
return $controller->newBand();
});
The New Band form using GET works fine.
BandController.php
public function newBand(){
if (!$this->_app->user->checkAccess('uri_bands')){
$this->_app->notFound();
}
$this->_app->render('bands/new.twig', []);
}
and if I add this to the newBand Controller to test, it writes to the database when I load the new band form, which is fine:
$new_band = new Band([
"band_name" => "band_name",
"band_description" => "band_description"
]);
$new_band->save();
$id = $new_band->id;
The problem is the Save using Post. Even if I hard code in the values and do not even try to read the POST data, all I get is a blank screen. There are no error messages and nothing in the apache error.log:
index.php
$app->post('/bands/new/?', function () use ($app) {
$controller = new UF\BandController($app);
return $controller->saveBand();
});
BandController.php
public function saveBand(){
$new_band = new Band([
"band_name" => "band_name",
"band_description" => "band_description"
]);
$new_band->save();
$id = $new_band->id;
}
If I replace my POST route with
$app->post('/bands/new/?', function () use ($app) {
echo 'post';
})
I still just get a blank screen.
Here's bands/new.twig though I think the problem is before this:
{% extends "layouts/layout-dashboard.twig" %}
{% set page_group = "dashboard" %}
{% block page %}
{% set page = page | merge({
"title" : "Add New Band",
"description" : ""
}) %}
{{ parent() }}
{% endblock %}
{% block content %}
<h1>{{page.title}}</h1>
<p>{{page.description}}</p>
<div class="row">
<div class="col-lg-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-users"></i>Add New Band</h3>
</div>
<div class="panel-body">
<form class="form-horizontal" role="form" name="bands" action="{{site.uri.public}}/bands/new" method="post">
<div class="form-group">
<label for="input_band" class="col-sm-4 control-label">Band Name</label>
<div class="col-sm-8">
<input type="text" id="input_title" class="form-control" name="band_name" placeholder="Please enter the band name">
<!--<p class="help-block">Enter the band name here</p>-->
</div>
</div>
<div class="form-group">
<label for="input_title" class="col-sm-4 control-label">Description</label>
<div class="col-sm-8">
<textarea type="text" id="input_title" class="form-control" name="band_description" placeholder="Please enter a description of the band. This may be displayed publically"></textarea>
<!--<p class="help-block">This will become the new title for all users in the selected group.</p> -->
</div>
</div>
<div class="form-group">
<label for="input_group" class="col-sm-4 control-label">Genre</label>
<div class="col-sm-8">
<select id="input_group" class="form-control select2" name="genre_id">
{% for group in groups %}
<option value="{{group.id}}">{{group.name}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group text-center">
<button type="submit" class="btn btn-success text-center">Add Band</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block page_scripts %}
<script>
$(document).ready(function() {
// Load the validator rules for this form
var validators = {{validators | raw}};
ufFormSubmit(
$("form[name='add_band']"),
validators,
$("#userfrosting-alerts"),
function(data, statusText, jqXHR) {
// Reload the page on success
window.location.reload(true);
}
);
});
</script>
{% endblock %}
Thanks for any thoughts. With no error messages, this is driving me nuts!
Seems like you have forgotten the csrf token.
You can add this hidden input field:
<input type="hidden" name="{{csrf_key}}" value="{{csrf_token}}">
and read more here.