I created a checkbox in each row of the table. After selecting multiple check boxes, click the Add Teacher button to add the currently logged in user name (request.user.first_name) to the 'teacher' field of the checked row. I succeeded in getting the id to the page with the table using ajax, but it keeps failing to add the field value of obejct(teacher field) at once. view.py needs to be edited, does anyone know how to fix it?
[urls.py]
path('/study/add_teacher/', views.add_teacher, name='add_teacher'),
path('/study/student/', views.student), ----> page with table
[views.py]
def add_teacher(request):
if request.method == 'POST':
ids = request.POST.getlist('chkArray')
for id in ids:
student = Student.objects.get(pk=id)
student.teacher = request.user.first_name
student.save()
return HttpResponseRedirect(f'/study/student/') ----> page with table
[stduent.js]
$(function () {
('button.addteacher').on('click',function () {
$checkbox = $('.Checked');
var chkArray = [];
var updateTeacher = confirm("업데이트하시겠습니까?");
chkArray = $.map($checkbox, function(el){
if(el.checked) { return el.id };
});
var csrftoken = $('[name="csrfmiddlewaretoken"]').val();
$.ajax({
type:'post',
url: '/study/add_teacher/',
headers: {"X-CSRFTOKEN": "{{ csrf_token }}"},
data:{
"chkArray" : chkArray.toString(),
"csrfmiddlewaretoken": "{{ csrf_token }}",
},
success:function(data){
console.log(chkArray);
},
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText);
}
});
});
});
Related
I'm trying to validate a field while typing based on another question (How to validate django form field while it is typing?).
The js doesn't cal validation view
form
{{ form.num }}
<p id="validate_number" class="help is-danger is-hidden ">nome já utilizado</p>
js
<script>
$('#id_num').on('input', function () {
var id_number = $(this).val();
$.ajax({
url: '{% url 'validate-num' %}',
data: {
'num': id_number
},
dataType: 'json',
success: function (data) {
if (data.is_taken) {
$("#validate_number").show();
document.getElementById('id_num').style.borderColor = "red";
document.getElementById("submit_change").disabled = true;
}
else {
$("#validate_number").hide();
document.getElementById('id_num').style.borderColor = "#e7e7e7";
document.getElementById("submit_change").disabled = false;
}
}
});
});
</script>
url.py
urlpatterns = [
# ...
path('validatenum/', validate_inventory_number, name='validate-num'),
# ...
]
view
def validate_inventory_number(request):
number = request.GET.get('num', None)
data = {
'is_taken': InventoryNumber.objects.filter(num=number).exists()
}
return JsonResponse(data)
Each form's input is associated with a unique data-comment-pk. I'm trying to access the value of data-comment-pk of the input which is submitted. Currently, the AJAX success function's alert(comment_pk) is only fetching me the comment_pk of the first form. How can I access the comment_pk of the form which is submitted instead of getting the comment_pk of the first form?
html template
{% for comment in object_list %}
<h3>{{comment.comment}} by {{comment.username}}</h3>
<form class="score-form">
<input type="submit" value="Up" name="up" class="Up" data-comment-pk="{{comment.pk}}" />
<input type="submit" value="Down" name="down" />
</form>
{% endfor %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
$(".score-form").submit(function (e) {
e.preventDefault();
var comment_pk = $(".Up").attr("data-comment-pk");
var url = comment_pk + "/vote";
console.log(url)
$.ajax({
type: 'GET',
url: url,
data: { "up": 'UP' },
success: function (response) {
if (response["valid"]) {
alert(comment_pk);
}
},
error: function (response) {
console.log(response)
}
})
})
</script>
models.py
class CommentModel(VoteModel, models.Model):
comment = models.TextField()
username = models.ForeignKey(User, on_delete=models.CASCADE)
views.py
class CommentView(ListView):
model = CommentModel
def comment_vote(request, comment_id):
if request.is_ajax and request.method == "GET":
# do some stuff
return JsonResponse({"valid": True}, status=200)
Here is the solution to this problem :
var comment_pk = $(".Up", this ).attr("data-comment-pk");
Using this will return the current HTML element.
try: add "this" to before .Up in the comment_pk.
let me know if it works.
this- will get the currect form that have been submit and get the .Up Class
<script>
$(".score-form").submit(function (e) {
e.preventDefault();
var comment_pk = $("this .Up").attr("data-comment-pk");
var url = comment_pk + "/vote";
console.log(url)
$.ajax({
type: 'GET',
url: url,
data: { "up": 'UP' },
success: function (response) {
if (response["valid"]) {
alert(comment_pk);
}
},
error: function (response) {
console.log(response)
}
})
})
</script>
I have lot of posts generated using loop in django, and want to delete specific post (like Facebook delete works). I am able to get id of post using jquery but i am not sure what I am doing wrong to delete post. I have also implemented delete function in class based view.
Delete Post Button
existing-dashboard.html
{% for i in all_posts %}
... ///rest of the code
<span class="username">{{ i.first_name }} {{i.surname}}
<span class="more" id="more-icon">{{i.post_id}}
<div class="more-menu" style="margin-top: 30px;">
<span class="delete" id="{{i.post_id}}">delete</span>
</div>
</span>
... /// rest of the code
</span>
{% endfor%}
Ajax
$('.delete').on('click', function(){
var post_id = $(this).attr('id');
alert(post_id)
$.ajax({
url: 'http://127.0.0.1:8000/existing-delete/' + post_id +'/',
type: 'DELETE',
data: {},
contentType: 'application/json',
dataType: 'text',
error:
function(result){
alert(result)
},
success:
function(result){
alert(result)
}
})
})
views.py
class ExistingStudentDashboard(TemplateView):
.../// rest of the code
def delete(self, request, pk, format=None):
post1 = Existing_student_posts.objects.filter(id = pk).first()
post2 = Future_student_posts.objects.filter(id = pk).first()
post3 = Teacher_posts.objects.filter(id = pk).first()
post4 = Employee_posts.objects.filter(id = pk).first()
if post1:
post1.delete()
elif post2:
post2.delete()
elif post3:
post3.delete()
else:
post4.delete()
get_context_data()
urls.py
path('existing-delete/,<int:pk>', views.ExistingStudentDashboard.as_view(), name = 'existing-delete'),
Getting Error in Console like bellow
Not Found: /existing-delete/61/
Browser Console Error
Browser Console Error
What I am doing wrong to delete post. Feel free to ask about more clarification. Any help will be appreciated :)
You have a typo in your path, change it to this
path('existing-delete/<int:pk>', views.ExistingStudentDashboard.as_view(), name = 'existing-delete'),
Edit:
Use this to get the csrf token in javascript
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
Then while making the ajax request, pass that on the headers.
headers: {"X-CSRFToken":csrftoken }
I have a code written which dynamically add a list when the user clicks on the add button.
for eg two lists are created-
<ul>
<li>samsung galaxy</li>
<li>xiaomi redmi note 5</li>
</ul>
code of frontend for adding li
<div class="compare_val"> <input type="text" id="txtVal" placeholder="write
to add">
<button onclick="addLi()" class="btn">Add</button></div>
<ul id="list">
<li>{{ Brand }}</li>
</ul>
<button id="Com_action" class="btn btn-danger ml-3"
onclick="ComAction()">Compare</button>
<script>
function addLi()
{
var txtVal = document.getElementById('txtVal').value,
listNode = document.getElementById('list'),
liNode = document.createElement("LI"),
txtNode = document.createTextNode(txtVal);
liNode.appendChild(txtNode);
listNode.appendChild(liNode);
}
</script>
now I want to send the li data as a list
['samsung galaxy', 'xiaomi redmi note 5'] to the view
when the user clicks on the compare button.
please help me to achieve this.
You will need to modify your scripts to include csrfmiddlewaretoken and send data using XmlHttpRequest (I'm assuming you are not using jquery):
<script>
// Standard django function to get csrf_token. More info:
// https://docs.djangoproject.com/en/2.2/ref/csrf/#acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const listNode = document.getElementById('list');
let brands = [];
function addLi() {
let txtVal = document.getElementById('txtVal').value,
liNode = document.createElement("LI"),
txtNode = document.createTextNode(txtVal);
liNode.appendChild(txtNode);
listNode.appendChild(liNode);
// Save newly added brand to array
brands.push(txtVal);
}
function ComAction() {
// Prepare AJAX request
let xhr = new XMLHttpRequest(),
data = new FormData();
// Add token
data.append('csrfmiddlewaretoken', getCookie('csrftoken'));
// Add all brands
brands.forEach(function (brand) {
data.append('brand', brand);
});
// We are sending it via POST request to url '/'
xhr.open('POST', '/', true);
xhr.onload = function () {
if (xhr.status === 200) {
alert('Data received successfully. Brands are ' + xhr.responseText);
} else if (xhr.status !== 200) {
alert('Request failed.');
}
};
// Actually send request
xhr.send(data);
}
</script>
Your django endpoint can process brands like this:
views.py:
def index(request):
if request.method == 'POST':
brands = request.POST.getlist('brand')
return HttpResponse(", ".join(brands))
return render(request, 'index.html')
If you want django to send data and redirect user, modify script:
// ...
xhr.open('POST', '/', true);
xhr.onload = function () {
if (xhr.status === 200) {
data = JSON.parse(xhr.responseText);
alert('Data received successfully. Brands are ' + data.brands);
window.location.replace(data.redirect_url);
} else if (xhr.status !== 200) {
alert('Request failed.');
}
};
xhr.send(data);
and django:
views.py:
def index(request):
if request.method == 'POST':
brands = request.POST.getlist('brand')
response_data = {
'brands': brands,
'redirect_url': '/new_url'
}
return JsonResponse(response_data)
return render(request, 'index.html')
First get the list -
var lis = document.getElementById("selectedli").getElementsByTagName("li");
now store them to an input -
<input name="id_selected" type="text" hidden>
Now, you can't pass the array directly, Use jQuery.param(yourObject).
document.getElementById("id_selected").value = jQuery.param(lis)
The param() method creates a serialized representation of an array or an object that can be understandable by various frameworks like php, ruby, django etc.
For again converting it to python
from urllib import parse
value = parse.parse_qs(self.request.POST.get('name'))
If you want to use ajax you can. This code is not tested by me, so report if any error occurs.
I use this light sortable plugin to sort my data by drag and drop
http://farhadi.ir/projects/html5sortable/
Now, how to update my sort order
$('.sortable').sortable().bind('sortupdate', function() {
//Triggered when the user stopped sorting and the DOM position has changed.
});
views.py
def filter_order(request):
if request.method == 'POST':
order = request.POST.getlist('filter[]')
count = 0
for id in order:
count += 1
filter = FilterModel().objects.get(pk=id)
filter.sort_order = count
filter.save()
return HttpResponse('Successfully updating rules order.')
else:
return HttpResponse("Error updating rules order.")
urls.py
urlpatterns = patterns('transactions.views',
............
url(r'^filter-order/$', 'filter_order',
name='filter_order'),
)
rules.html
<ul class="sortable" id="filter-items">
{% for filter in filters %}
<li id="{{ filter.id }}">{{filter.rules}}</li>
{% endfor %}
</ul>
<script>
$('.sortable').sortable().bind('sortupdate', function() {
datas = new Array();
var i = 0;
$('#filter-items li').each(function() {
datas[i] = $(this).attr('id');
i++;
});
$.ajax({
type: "POST",
data: {
'filter[]': datas,
'csrfmiddlewaretoken': '{{csrf_token}}'
},
url:"/transactions/filter-order/",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function(data) {
notify('', 'Successfully updating rules order.', { autoClose: true, delay: 1000 });
},
error: function(ts) {
notify('', ts.responseText, { autoClose: true, delay: 1000 });
}
});
});
</script>