I need to do an ajax call in django depending on the values set on two date fields and a select dropdown. In order to do that I have to pass those values into javascript function which will be called when a button is click. I have set the form dates fields as Date type and select as Choice field. How can I pass the current values of these to the javascript function?
form.html (template):
<div class="form-group">
<label class="control-label">* Start Date:</label><br>
{{ form.date1 }}
</div>
<div class="form-group">
<label class="control-label">* End Date:</label><br>
{{ form.date2 }}
</div><br><br>
<div class="form-group">
Category: {{ form.category }}
</div>
<button type="button" class="btn btn-xs btn-warning"
onclick="javascript:check_availability({{ XXX }}, '{% url "find_available" %}');">
Check Now
</button>
Javascript:
function check_availability(date1, date2, category, url) {
$.ajax({
type: 'GET',
url: url,
data: {date1: date1, date2: date2, category: category},
dataType: 'json',
success: available_now,
error: function() {
alert('Unable to find available items')
}
});
}
fucntion available_now () {...}
In form.py (view)
category = forms.ChoiceField(choices=(...))
date1 = forms.DateField(widget=forms.DateInput())
date2 = forms.DateField(widget=forms.DateInput())
How could I pass those three values set in the widgets in place of XXX for the above function call? I need to specifically get the selected value of the dropdown.
This isn't in any way a question about Django, but about Javascript. Since you are using jQuery for your Ajax function, you should use it to get the value of the fields. Also note, you should avoid setting onclick handlers directly in the HTML; you should do that in your jQuery script as well.
<button type="button" id='find-available' class="btn btn-xs btn-warning" data-url='{% url "find_available" %}');">
Check Now
</button>
...
$('form').on('click', '#find-available', function() {
$this = $(this);
$.ajax({
type: 'GET',
url: $this.data('url'),
data: $this.parent().serialize(),
dataType: 'json',
success: available_now,
error: function() {
alert('Unable to find available items')
}
});
});
Related
I'm working with django and javascript, I'm trying to follow and unfollow multiple users without refreshing the page. therefore i'm using ajax. The problem which i'm facing right now is that the first follower is getting follow and unfollow no matter if i click on that user or on other user.. its an obvious behavior because i couldn't understand how to get specific id of user from the for loop so that i can use that user in a js function.
{% if follower.user in request.user.userprofile.follower.all %}
<span><a class="btn btn-success" id="follow-button{{follow.id}}" toggle="{{follower}}" type="submit">{% csrf_token %}UnFollow</a></span>
{% else %}
<span><a class="btn btn-warning" id="follow-button{{follow.id}}" toggle="{{follower}}" type="submit">{% csrf_token %}Follow</a></span>
{% endif %}
</div><!--/ followers-body -->
{% endfor %}
<script>
$(document).on('click','a[id^=follow-button]', function (e) {
var user = $('#follow-button').attr('toggle'); //this user is coming the first use of looping object..no matter if i click on the 2nd or 3rd user of the loop.
console.log(user,'im im im tested');
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "profiles:toggle" %}',
data: {
user_toggle: user,
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'POST',
},
success: function (json) {
result = json['result']
console.log(result,"maii mai maima maima a")
if (result) {
document.getElementById("is_following").innerHTML = '<a class="btn btn-success" id="follow-button" toggle="{{user.userprofile}}" type="submit">{% csrf_token %}UnFollow</a>'
}
else
document.getElementById("is_following").innerHTML = '<a class="btn btn-warning" id="follow-button" toggle="{{user.userprofile}}" type="submit">{% csrf_token %}Follow</a>'
},
error: function (xhr, errmsg, err) {
}
});
})
</script>
It is more of JS/JQuery question than a Django one, but here is what I think you are missing.
When you add a listener to an element, you have an option to get the element that was interacted with using the saved word this.
Your problem in the code is that line where you retrieve user. If you replace $('#follow-button') with $(this) then you will get the user that was clicked.
From there you can retrieve the id easily.
<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");
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 %}
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,
}
I am working on a simple CRUD app using ember js. I have a template with a input form which sends data to the server and server responds with success response.
input form data: "user": {"id": 1, "name": "John"};
server response: {"message":"Created successfully", "nextId": 2}.
I want to display the success message on the same template(one with the input form). Because template refers to the user model and user model does not have a message attribute. How can it be done? Please help.
Here is my code:
var Manager = Ember.Application.create();
Manager.Router.map(function() {
this.resource('users');
this.resource('user', {path: '/users/:user_id'});
this.resource('home', {path: '/'});
});
Manager.UserRoute = Ember.Route.extend({
model: function(params) {
return jQuery.getJSON("http://localhost:8085/users/"+ params.user_id);
},
actions :{
insert : function(){
var user = this.modelFor("User");
$.ajax({
url: "http://localhost:8085/Users",
data: JSON.stringify(user),
type: "POST",
contentType: "application/json",
})
.done(function(data){
//set data.message to display on UI
})
}
}
});
and my template looks like this:
<script type="text/x-handlebars" data-template-name="user">
<form class="form-horizontal" role="form" {{action "insert" on="submit"}}>
<div class="form-group">
<label for="userId" class="control-label col-xs-2">User Id</label>
<div class="col-xs-4 input-group">
{{input type="number" value=_id class="form-control" id="userId" placeholder="Identity"}}
</div>
</div>
<div class="form-group">
<label for="name" class="control-label col-xs-2">Name</label>
<div class="col-xs-4 input-group">
{{input type="text" value=name class="form-control" id="name" placeholder="Name"}}
</div>
</div>
{{#if message}}
<div class="alert alert-success input-group" role="alert">{{message}}</div>
{{/if}}
<div class="form-group button-center">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
</script>
Set the message property on your controller to the response that comes back.
actions :{
insert : function(){
var user = this.modelFor("User");
var self = this;
$.ajax({
url: "http://localhost:8085/Users",
data: JSON.stringify(user),
type: "POST",
contentType: "application/json",
})
.done(function(data){
//set data.message to display on UI
self.controllerFor('user').set('message', data.message);
})
}
}