Don't pick up Django form value to javascript function - javascript

I'm trying to pick up RadioSelectBox value from my Django form to my template with a javascript part. But I don't overcome to get this variable and put it in my template.
I've a very simple form :
def ChoiceTheme(request) :
if request.method == 'POST':
form = ThemeForm(request.POST or None)
if form.is_valid():
theme = form.instance.favorite_theme
print theme
post = form.save()
return HttpResponseRedirect(reverse('accueil'), {"theme":theme})
else:
form = ThemeForm()
context = {
"form":form,
}
return render(request, 'Theme.html', context)
I get exactly the good field value with print theme.
But I want to place this variable in my html template :
{% block content %}
<style>
ul li {
list-style: none;
}
</style>
<div class = "col-sm-8">
<form class = "form" method='POST' action=''> {% csrf_token %}
<h3> <span class="glyphicon glyphicon-file"></span> Choix du thème DatasystemsEC </h3>
<br></br>
{{ form }}
<br></br>
<button> Valider le thème </button>
<script>
theme = "{{ }}"
$(function() {
$('button').click(function() {
alert("Vous avez choisi le thème : " + theme);
});
})(jQuery);
</script>
</form>
</div>
{% endblock content %}
I have theme = {{ theme }} but my alert window just display :
Vous avez choisi le thème :
Do you have any idea ? I'm very sily on this point, because I don't see the way ..

To extract the theme choice in django you would have to do an ajax request similar to this:
$(function() {
$('form').submit(function (event) {
event.preventDefault();
$.ajax({
url: "/choicetheme",
data: $('form').serialize(),
type: 'post',
success: function (data) {
alert(data.theme);
}
});
});
})(jQuery)
However you can also extract the choice before sending it to django in javascript but then you need to know what element are in the form IE the option element where you selected your theme.

Related

How can I replicate **bold** in my django template?

I am trying to replicate how stack overflow allows the user to type text and produces it below at the same time. The code below in the Django Template works for this.
{% block head %}
<script>
function LiveTextUpdate() {
var x = document.getElementById("myInput").value;
document.getElementById("test").innerHTML = x;
}
</script>
{% endblock %}
{% block body %}
<div class = typing_container>
<div class = note_text>
{{ note_form.note }}
</div>
</div>
<div class = output_container>
<div class = output_note_text>
<p id="test" ></p>
</div>
</div>
The following is in the forms.py file:
class NoteForm(ModelForm):
class Meta:
model = NoteModel
fields = [
'note'
]
widgets = {
'note' : Textarea(attrs={'placeholder' : 'Start a new note', 'class' : 'updated_task_commentary', 'id' : 'myInput', 'oninput' : 'LiveTextUpdate()' }),
}
How can I replicate the ability to bold text when the text is surrounded by "**" please?

XMLHttpRequest Synchronous Error in Bootstrap modal and Django

The program open Bootstrap Modal and load Django Form to create new permission, this is works. But when i want in the form add new Ajax call to load dynamically elements in Django ChoiceField appears the error and browser not finish the call never.
I open browser inspect console and appears XMLHttpRequest error
url.py:
path('permisos/', general_views.permission_list,name='permission_list'),
path('permisos/crear', general_views.permission_create, name='permission_create'),
path('permisos/<int:id>/editar', general_views.permission_update, name='permission_update'),
path('permisos/<int:id>/detalle', general_views.permission_detail, name='permission_detail'),
path('permisos/<int:id>/borrar', general_views.permission_delete, name='permission_delete'),
path('permisos/crear/cargar_elementos/', general_views.permission_load, name='ajax_load_permissions'),
never get to call this function from ajax
views.py:
def permission_load(request):
type = request.GET.get('type')
if type == 2: # object
list = ['general', 'billing', 'accounting']
elements = ContentType.objects.filter(app_label__in=list)
elif type == 3: # instance
list = ['general', 'billing', 'accounting']
content_type = ContentType.objects.filter(app_label__in=list)
elements = general_models.content_type.model.objects.all()
elif type == 4: # attribute
list = ['general', 'billing', 'accounting']
content_type = ContentType.objects.filter(app_label__in=list)
elements = general_models.content_type.model.objects.all()
# get instance atributtes
else: # module
elements = general_models.Modules.objects.all()
# other aspect is that i dont know how to load view result in the html choicefield
response = { 'element': elements }
json = simplejson.dumps(response)
return HttpResponse(json, mimetype="text/json")
forms.py:
class CustomPermisisonForm(forms.Form):
name = forms.CharField()
ACTION_TYPE = ((1, ('Ver')),(2, ('Añadir')),(3, ('Modificar')),(4, ('Borrar')))
action = forms.MultipleChoiceField(choices=ACTION_TYPE, label='Acciones', initial=1, widget=forms.SelectMultiple())
PERMISSION_TYPE = ((1, ('Módulo')),(2, ('Objecto')),(3, ('Instancia')),(4, ('Atributo')))
type = forms.ChoiceField(choices=PERMISSION_TYPE, label='Tipo', initial=1, widget=forms.Select(attrs={"data-objects-url":"{% url 'ajax_load_permissions' %}"}))
element = forms.ModelChoiceField(queryset=general_models.Module.objects.all())
permissions.html:
{% block javascript %}
<script src="{% static 'js/permissions.js' %}"></script>
{% endblock %}
# this is the line to open modal
<button type="button" onclick="return openModalPermission('{% url 'general:permission_create' %}')" class="btn btn-outline-primary float-right btn-sm">
<span class="fas fa-plus"></span>
</button>
permission_create.html:
{% load static %}
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form method="POST" action="{% url 'general:permission_create' %}">
{% csrf_token %}
<div class="modal-header">
<h4 class="modal-title">Nuevo Permiso</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% include 'permission_form.html' %}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Crear</button>
</div>
</form>
</div>
</div>
# when comment this line the error disappear but don't work js call
<script src="{% static 'js/permissions.js' %}"></script>
permission_form.html:
{% load widget_tweaks %}
{% load static %}
{% for field in form %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" %}
{% for error in field.errors %}
<p class="help-block">{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
permissions.js:
function openModalPermission(url) {
$('#modal-permission').load(url, function() {
$(this).modal('show');
});
return false;
}
$("#id_type").change(function () {
console.log("js function");
var url = $("id_type").attr("data-objects-url");
var type = $(this).val();
console.log(type);
console.log(url);
$.ajax({
url: url,
data: {
'type': type
},
success: function (data) {
$("#id_element").html(data);
},
error: function (qXHR, textStatus, errorThrown) {
console.log(qXHR)
console.log(textStatus)
console.log(errorThrown)
}
});
return false;
});
Anybody know how to solve this problem ?
Thanks in advance.
SOLVED
permissions.html:
<!-- pass this block to the end of the file -->
{% block javascript %}
<script src="{% static 'js/permissions.js' %}"></script>
{% endblock %}

Javascript inside Jinja "for" loop

I'm coding an app in Python Flask and I'm building interactive Like buttons with Javascript.
Here's my route:
#app.route('/jquery')
def jquery():
posts = Post.query.all()
return render_template('jquery.html', posts=posts)
And in the jquery.html template I have:
{% for p in posts %}
{% if p.upvotes %}
{% set pupvotes = p.upvotes %}
{% else %}
{% set pupvotes = 0 %}
{% endif %}
<p>{{ p.author.username }} says: <b>{{ p.body }}</b> <button id="
{{ p.id }}" onclick="document.getElementById('{{ p.id }}').innerHTML = {{
pupvotes }} +1 + ' Likes'">{{ pupvotes }} Likes</button></p>
{% endfor %}
Everything actually works this way, but I would like to save the results of +1 likes clicks and transfer them to a Python variable so that I can add it to the database and the updated Like numbers show up on the page after refresh.
I tried to use JavaScript function this way:
<script>
function myF1() {
document.getElementById('{{ p.id }}').innerHTML = {{ pupvotes }} +1 + '
Likes';
}
</script>
and:
onclick="myF1()"
But then only the last Like on the page gets updated with click, no matter which Like button I click.
OK, I've made it work:
Here's our Flask route:
#app.route('/ulk')
def ulk():
ppp = request.args.get('p', 0, type=int)
lpost = Post.query.filter_by(id=ppp).first()
lpost.upvotes += 1
db.session.commit()
return jsonify(result=ppp)
And here's our HTML page with some jQuery:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<script type=text/javascript>
$(function() {
$('a#like').bind('click', function() {
$.getJSON('/ulk', {
p: pid
}, function(data) {
$("#result2").text(data.result);
});
return false;
});
});
</script>
<br/><br/>
{% for p in posts %}
{% if p.upvotes %}
{% set pupvotes = p.upvotes %}
{% else %}
{% set pupvotes = 0 %}
{% endif %}
<p>{{ p.author.username }} says: <b>{{ p.body }}</b>
<a href="#" id=like>
<button id="{{ p.id }}" onclick="pid={{ p.id }};pvts = {{ pupvotes }} +1;myF1();">{{ pupvotes }} Likes</button>
</a>
</p>
<script type=text/javascript>
function myF1() {
$( "#" + pid ).text(pvts + ' Likes');
$('#' + pid).on('click', function() {
$(this).prop('disabled', true);
});
}
</script>
{%endfor%}
<br/>
<span id=result2>...</span>
</body>
</html>
You are close, however, as #MartijnPieters pointed out, you still need to communicate with the backend to update the number of likes for the post. To do so, slightly change your HTML to include a button to update the likes with a class and id. The id will be the same as the post id, and the class will be generic. Then, utilize jquery with ajax after creating a script.
First, in the Python backend, create a route to handle the updating of the likes for a post:
#app.route('/update_like')
def update_likes():
_id = int(flask.request.args.get('post_id'))
#Do something to update the database
return flask.jsonify({'success':'True'})
I suggest returning a jsonified response so that you can handle errors that may occur, such as a user liking a post twice. If you discover that that is the case, then you could return flask.jsonify({'success':'False'}) and handle that accordingly in the frontend.
Then, in the HTML:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<div class='post_wrapper'>
{%for p in posts%}
<div id='post_{{post.id}}'>
<p>{{p.author.username}} says:</p>
<p>{{p.body}}</p>
{%if p.upvotes%}
<button class='upvote' id='upvote_{{p.id}}'>Like <span id='upvotes_{{p.id}}'>{{p.upvotes}}</span></p>
{%else%}
<button class='upvote' id='upvote_{{p.id}}'>Like <span id='upvotes_{{p.id}}'>0</span></p>
{%endif%}
</div>
{%endfor%}
</div>
<script>
$(document).ready(function(){
$('.post_wrapper').on('click', '.upvote', function(){
var post_id = this.id.match('\\d+');
$.ajax({
url: "/update_like",
type: "get",
data: {post_id: post_id},
success: function(response) {
if (response.success === 'True'){
var like_val = parseInt($('#upvotes_'+post_id).text()) + 1;
$('#upvotes_'+post_id).text(like_val.toString());
}
else{
alert('You already liked that post!');
}
}
});
});
});
</script>
</html>

Using Ajax with Django to call backend and display result

I am taking user input and sending it to Django backend for some text processing. After performing backend operation I want to display results.
I tried but as I am new with ajax,I am not sure where I am making mistake. Can anyone please give me correct way of using ajax for this operation? I appreciate if you can give link to any good reference document.
Current issue - When I click on submut button it removes input text area.
My html report.html -
{% extends 'base.html' %}
{% block content %}
<h1>StopWordsRemoval</h1>
<script type='text/javascript'>
$(document).ready(function(){
$(form).on('submit', function(event){
$.ajax({
url: 'stopwordsremoval/(?P<document1>.+)'
type: 'POST',
data: this.serialize(),
});
});
});
</script>
<div>
<form method = "post" >
{% csrf_token %}
{{ form}}
<button type="submit">stopwordsremoval</button>
</div>
</form>
<div >
<ul>
<li>{{ naturallanguageprocessing }}</li>
</ul>
<a href="{% url 'stopwordsremoval' %}" </a>
<style>
div {
width: 1000px;
border: 5px solid green;
padding: 10px;
margin: 10px;
}
</style>
</div>
</div>
{% endblock %}
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'stopwordsremoval/$', views.stopwordsremoval.as_view(), name='stopwordsremoval'),
url(r'stopwordsremoval/(?P<document1>.+)/$',
views.ReportDetails.as_view(), name='report_details'),
]
forms.py
from django import forms
class ReportForm(forms.Form):
#pdb.set_trace()
text = forms.CharField(widget=forms.Textarea(attrs={'rows': 5, 'cols': 100}))
<script type='text/javascript'>
$(document).ready(function(){
$(button).on('click', function(event){
var form = $(form).serialize()
$.ajax({
url: 'stopwordsremoval/(?P<document1>.+)' // this will not work
type: 'POST',
data: form,
});
});
});
</script>

Do not print media from django form

I created a custom widget and included a Media class.
class MyWidget(forms.MultiWidget):
class Media:
css = {
'all': ('path-to-css.css',),
}
js = (
'path-to-js.js',
)
def __init__(self, visible_input_attrs=None, hidden_input_attrs=None):
widgets = (
TextInput(attrs=visible_input_attrs),
HiddenInput(attrs=hidden_input_attrs),
)
super(MyWidget, self).__init__(widgets)
def decompress(self, value):
if value:
return ['', value]
return [None, None]
In my form I use this widget as follows
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = [
'first_name',
'last_name',
'email',
'phone_number',
]
widgets = {
'phone_number': MyWidget(),
}
My template file
{% extends "base.html" %}
{% load static i18n crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<form id="my-form" action="" method="post" enctype="multipart/form-data">
<h2>Contact details</h2>
{% crispy user_form %}
</form>
</div>
</div>
{% endblock content %}
{% block javascript %}
{{ block.super }}
{{ user_form.media.js }}
{% endblock %}
In my template file I include the form with {% crispy user_form %} (using crispy forms). Django hereby automatically adds the CSS and JS files at the beginning of the form. Since I load JS files at the very end of every HTML page and since the included path-to-js.js file requires jQuery, I append {{ user_form.media.js }} to my javascript block in my template. As a consequence, path-to-js.js appears more than once on my page and leads to error messages because the first time path-to-js.js is loaded, jQuery is not loaded yet.
How can I avoid to load the JS files when I use {% crispy user_form %}?
Set include_media = False in your helper class.
class UserForm(forms.ModelForm):
...
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.include_media = False

Categories