Django dynamic inputs - python

I'd like to create dynamic input system, for example when I enter the folder name - the list of files inside automatically show up another input ChoiceField below, so I can choose the file. The methods are already written, the problem is - How can I make it in Django view?
Here is my view:
def get_name(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
dir_date = format_date(request.POST['date'])
files = os.listdir(os.path.join(path+dir_date))
return render(request, 'inform/show_name.html', {'data': request.POST['your_name'],
'date': format_date(request.POST['date'])})
else:
form = NameForm()
return render(request, 'inform/base.html', {'form': form})
Here is the form class:
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
date = forms.DateField(widget=forms.DateInput(attrs={'class': 'datepicker'}))
flights = forms.ChoiceField(choices=?)
Finally, here is my template.
{% extends 'inform/header.html' %}
{% block content %}
<script>
$( function() {
$( ".datepicker" ).datepicker();
$( "#anim" ).on( "change", function() {
$( "#datepicker" ).datepicker( "option", "showAnim", $( this ).val() );
});
} );
</script>
<div class="container" style="color: red; size: auto;">
<form class="form-vertical" action="get_name" role="form" method="post">
{% csrf_token %}
<div class="form-group" style="display: inherit">
<center>
{{form}}
<input type="submit" value="OK">
</center>
</div>
</form>
</div>
{% endblock %}
Is there any way to dynamically read the data from the Date input and give it to the method inside the view without clicking the submit button or creating several others? If it can be solved only by ajax, jQuery or JS, could you please give me a simple sample of how it's done? I'm pretty much frustrated by the inability of creating a simple form.
Thank you in advance!

So basically you are doing it right. You already know that you need the on(change) function for the datepicker
Now as soon as the user changes a date, your on(change) function is triggered. So all you need to do now is to the get the new date value, which you already have when you do $( this ).val(). After that make an ajax call to the url corresponding to your method get_name in views.py
Something like this:
$( function() {
$( ".datepicker" ).datepicker();
$( "#anim" ).on( "change", function() {
$( "#datepicker" ).datepicker( "option", "showAnim", $( this ).val() );
send_changed_date_value(variable_with_new_date);
});
});
function send_changed_date_value(new_date) {
$.ajax({
type: // "POST" or "GET", whichever you are using
url: "/url in urls.py corresponding to get_name method in views.py/",
data: new_date,
success: function(response){
console.log("Success..!!")
}
});
}
This is how you can send the new date value to your views, everytime it is changed. If you want to submit the complete form data, i.e., your_name and flights data as well, then you may directly send serialzed data of the form in the data attribute of ajax.
Note -> You will have to return a HttpResponse from your get_name view as an ajax call requires a HttpResponse from the backend to complete the ajax call successfully. You may simply return a string in the response.

Related

Sending data from Python to HTML in Django

I have a Django project with a form in an HTML file, and I'd like to update the text on the submit button of that form WITHOUT a page reload. Essentially:
I click submit on the form
Python handles the submit with the form data
The button text is updated to say "show result"
If I understand correctly, I have to use AJAX for this. The problem is that the form submit relies on an API call in Python, so the HTML essentially has to always be "listening" for new data broadcasted by the views.py file.
Here's the code I have (which doesn't work, since when I hit submit I'm greeted by a page with the JSON response data and nothing else):
views.py:
def home(request):
if request.method == "POST":
print("Got form type", request.content_type)
return JsonResponse({"text": "show result"})
return render(request, 'home.html')
home.html:
<div class="content" onload="document.genform.reset()">
<form name="genform" autocomplete="off" class="form" method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="title-sect">
<h1>AJAX Test Form</h1>
</div>
<div class="submit">
<button id="submit" type="submit">Submit</button>
</div>
</form>
</div>
<script type="text/javascript">
function queryData() {
$.ajax({
url: "/",
type: "POST",
data: {
name: "text",
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function(data) {
var text = data['text'];
var button = document.getElementById('submit');
button.innerHTML = text;
setTimeout(function(){queryData();}, 1000);
}
});
}
$document.ready(function() {
queryData();
});
</script>
I've imported jQuery with the script <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>. Any idea why this doesn't work in its current state? Thanks!

How do I use AJAX to both create and edit new posts using the same html template (with Python & Django)?

I'm trying to switch to saving a form with AJAX instead of just Python/Django (I'm an absolute newb, so please forgive my idiocy). Here's what I'm trying to achieve:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.blurb_new, name='blurb_new'),
path('blurb/new/', views.blurb_new, name='blurb_new'),
path('blurb/<int:pk>/edit/', views.blurb_edit, name='blurb_edit'),
]
views.py (the relevant part):
#login_required
def blurb_new(request):
if request.method == "POST":
form = BlurbForm(request.POST)
if form.is_valid():
blurb = form.save(commit=False)
blurb.author = request.user
blurb.save()
return redirect('blurb_edit', pk=blurb.pk)
else:
form = BlurbForm()
return render(request, 'mysite/blurb_edit.html', {'form': form})
#login_required
def blurb_edit(request, pk):
blurb = get_object_or_404(Blurb, pk=pk)
if request.method == "POST":
form = BlurbForm(request.POST, instance=blurb)
if form.is_valid():
blurb = form.save(commit=False)
blurb.author = request.user
blurb.last_edited_date = timezone.now()
blurb.save()
return redirect('blurb_edit', pk=blurb.pk)
else:
form = BlurbForm(instance=blurb)
return render(request, 'mysite/blurb_edit.html', {'form': form, 'blurb': blurb})
blurb_edit.html (the relevant parts):
<form id="myform" method="POST" class="blurb-form">{% csrf_token %}
<input id="blurb-name" name="title"
{% if form.title.value != None %}value="{{ form.title.value }}"{% endif %}
/>
<textarea name="text" id="my-textarea">
{% if form.text.value != None %}
{{ form.text.value }}
{% else %}
Type your blurb here.
{% endif %}
</textarea>
<button type="submit">Save</button>
</form>
Before I used AJAX, views.py was totally doing its job (except for that pesky, unwanted page refreshing).
Because I hate the way the page refreshed every time you saved a blurb edit, I decided to switch to using AJAX.
Here's some AJAX I added in. It works for editing a blurb, but not for creating a new blurb--presumably because a new blurb does not have a pk yet. I'm not sure how to fix this.
AJAX in blurb_edit.html:
<script type="text/javascript">
$(document).on('submit', '#myform', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url:'{% url 'blurb_edit' pk=blurb.pk %}', // <--- THIS "pk" isn't working if it's a new blurb
data:{
title:$('#blurb-name').val(),
text:$('#my-textarea').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:function() {
alert("yay! it worked.")
}
})
});
</script>
So I can edit blurbs fine.
This is the error I get when I load the home page to create a new blurb:
NoReverseMatch at /
Reverse for 'blurb_edit' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['blurb/(?P<pk>[0-9]+)/edit/$']
How can I fix this "pk" issue, so that AJAX can work like views.py was?
Again, please forgive my ignorance (and probably shitty code) here, as I am new to these things and trying to wrap my head around it. Thank you! :)
<script type="text/javascript">
$(document).on('submit', '#myform', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url:'blurb_edit/{{blurb.pk}}/edit/', // check this version of url
data:{
title:$('#blurb-name').val(),
text:$('#my-textarea').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:function() {
alert("yay! it worked.")
}
})
});

Django view return value with AJAX

I am working with Django and AJAX,
I have a template where people can select an option and then click a submit button. The button fires an Ajax function that sends the data to my view where it is processed and should return a value back to the template.
The issue is when the post goes through, it hits the view, and nothing is returned to the template, I am not sure if this is because the view isn't getting any data, but it isn't firing any of my conditional statements, so it acts like its working but doesn't return anything.
My HTML form:
<form method="POST" id="buy_form" name="buy_form" action="{% url 'manage:buy' %}">
{% csrf_token %}
<div class="buy_top_section">
<div class="width">
<div class="spacing">
<h3 class="sell_title">How much do you want to sell?</h3>
<input type="text" id="amount" class="buy_input_top" maxlength="10" name="amount" type="number" required>
<select id="selected" class="buy_selection" name="wanted">
<option value="generate_b">BTC</option>
<option value="generate_e">ETH</option>
<option value="generate_l">LTC</option>
</select>
</div>
<span class="float_clear"></span>
<button id='generate' type="submit" value="currency_details" class="custom_button"l">Generate
</button>
</div>
</div>
</form>
<!-- What needs to be returned from thew view -->
<h1>{{ address }}</h1>
My AJAX
$(document).on('submit', '#buy_form', function (e) {
e.preventDefault()
$.ajax({
type: 'POST',
url:'/manage/buy/',
data:{
currency:$('selected').val(),
amount:$('#amount').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success: function (){
}
})
});
My Django View
def buy_corsair(request):
if request.method == 'POST':
if request.POST.get('wanted') == 'generate_b':
# Get the amount entered
amount = request.POST.get('amount')
# Generate a new B address
new_b_address = client.create_address(b_account_id)['address']
# Point the address at the user
request.user.user_address.b_address = new_b_address
# Save address to current user
request.user.user_address.save()
# Pass the address to the template
context = {'address': new_b_address}
return render(request, context)
urls.py
urlpatterns = [
# Buy Page
path('buy/', views.buy_corsair, name='buy'),
]
Ajax requests run in background, django render function render a template to body, so you can not render this way. You could like this;
dont forget include
from django.http import HttpResponse
def buy_corsair(request):
if request.method == 'POST':
if request.POST.get('wanted') == 'generate_b':
# Get the amount entered
amount = request.POST.get('amount')
# Generate a new B address
new_b_address = client.create_address(b_account_id)['address']
# Point the address at the user
request.user.user_address.b_address = new_b_address
# Save address to current user
request.user.user_address.save()
# Pass the address to the template
return HttpResponse(new_b_address)
in your js;
$.ajax({
type: 'POST',
url:'/manage/buy/',
data:{
currency:$('selected').val(),
amount:$('#amount').val(),
'csrfmiddlewaretoken': "{{ csrf_token }}"
},
success: function (data){
$('h1').html(data);
}
})
});
in your Django view
import json
from django.http import HttpResponse
def buy_corsair(request):
if request.method == 'POST':
if request.POST.get('wanted') == 'generate_b':
# Get the amount entered
amount = request.POST.get('amount')
# Generate a new B address
new_b_address = client.create_address(b_account_id)['address']
# Point the address at the user
request.user.user_address.b_address = new_b_address
# Save address to current user
request.user.user_address.save()
# Pass the address to the template
context = {'address': new_b_address}
return HttpResponse(json.dumps(context))
in your js
$.ajax({
type: 'POST',
url:'/manage/buy/',
data:{
currency:$('selected').val(),
amount:$('#amount').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success: function (response){
console.log(response);
//access the value and print it in console//
var obj=JSON.parse(response)["address"];
alert(obj);
}
})
});

Django ajax redirecting on form submission

I'm trying to return data with an ajax request on a form submission. My goal was too use two views, one too handle the template loading and the other to handle the POST request from the form. In the current state, the form is redirecting to the JSON that is in the callback. That makes sense as it's for the form action url is pointing, however, i want to just pass the data to the current page and not reload the page or be redirected to another page.
Here is the code:
user.html
<form action="{% url 'ajax-user-post' %}" method="post">
{% csrf_token %}
{% for user in users %}
<input type="submit" name="name" value="{{ user }}">
{% endfor %}
views.py
def ajax_user(request):
# get some data..
if request.METHOD == 'POST':
user = request.POST['user']
user_data = User.objects.get(user=user)
data = {'user_data': user_data}
return JsonResponse(data)
def user(request):
return render(request, 'user.html', context)
urls.py
url(r'^user/', user, name="user"),
url(r'^ajax/user/', ajax_user, name="ajax-user-post")
.js
$('form').on('submit', function(){
var name = // the name of the user selected
$.ajax({
type: "POST",
dataType: "json",
url: 'ajax/user/',
data: { 'csrfmiddlewaretoken': csrftoken, 'name': name, 'form': $form.serialize() },
success:function(data) {
// hide the current data
console.log(data);
displayUserData(data)
}
})
});
Thanks for the help in advance!
i want to just pass the data to the current page and not reload the page or be redirected to another page.
That means you need to stop the form submission event with the event.preventDefault() call.
Hence, change this line from:
$('form').on('submit', function(){
to to following two:
$('form').on('submit', function(e){
e.preventDefault();

(Django) Edit db.sqlite3 database on a HTML Contenteditable table using Ajax

I'm trying to create an content editable HTML table that'll update the db.sqlite3 database on keypress. The table can't have an input field in it because I also require it to be able to be filter and search using data-tables. so far I manage to retrieve the input on enter keypress but i don't know how to POST it straight to database (Presumably using AJAX) instead of JSON. Can anyone provide me with complete syntax sample as well, I'm very new to Django
Here's my code :
Model.py
class MyModel(models.Model):
a = models.CharField(max_length=10)
b = models.CharField(max_length=10)
def __str__(self):
return self.a
form.py
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['a', 'b']
view.py
def display_table(request):
context = {
"table_list": MyModel.objects.all(),
"title": "Table_List"
}
return render(request, 'tables/display.html', context)
display.html
<form action="" method="post" id="test_post">{% csrf_token %}
<div id="debug" contenteditable data-name="custom-text">Some text you can edit.</div>
<table id="myTable" class="display">
<thead>
<tr>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
{% for data in table_list %}
<tr >
<td contenteditable="true" data-name="a_name" id="{{data.id}}">{{data.a}}</td>{% csrf_token %}
<td contenteditable="true" data-name="b_name" >{{data.b}}</td>{% csrf_token %}
</tr>
{% endfor %}
</tbody>
</table>
</form>
<script>
document.addEventListener('keydown', function (event) {
var esc = event.which == 27,
nl = event.which == 13,
el = event.target,
data = {};
if (esc) {
// restore state
document.execCommand('undo');
el.blur();
} else if (nl) {
// save
data[el.getAttribute('data-name')] = el.innerHTML;
// we could send an ajax request to update the field
$.ajax({
data: data,
type: "POST"
});
log(JSON.stringify(data));
el.blur();
event.preventDefault();
}
}, true);
function log(s) {
document.getElementById('debug').innerHTML = 'value changed to: ' + s;
console.log(s);
}
</script>
<script>
$(document).ready(function(){
$('#myTable').DataTable();
});
</script>
Thank you very much for everyone's help.
Yes you're right about using AJAX. A few things you will need to modify:
1. Your HTML/JS
$.ajax({
data: data,
type: "POST",
// include URL
url: 'url/to/post/to',
// include response handler here
success: function(response) {
// do whatever you want with response
// you can just console.log(response.data) first
},
error: function(response) {
// error handler to failed AJAX requests
}
});
2. Views
You'll need to change your view to return a JsonResponse instead of using render which creates an HTML response. Note that the JsonResponse will be the exact response received in the AJAX handler above.
Hope this helps.

Categories

Resources