Array in jquery retains old data even after ajax submit - javascript

I have a list of brands and categories. One brand can have multiple categories.
{% for brand in brands %}
<li><input type="radio" value="{{brand.title}}" name="brand">{{brand.title}}</li>
{% endfor %}
{% for category in categories %}
<li><input type="checkbox" value="{{category.title}}" name="category" > {{category.title}}</li>
{% endfor %}
<input type="submit" value="submit" id="brand_category">
<script>
var parameter = [];
var brand = [];
var category = [];
$('#brand_category').click(function(event) {
$("input:checkbox[name=category]:checked").each(function(){
if ($(this).prop("checked", true)) {
category.push($(this).val())
}
});
parameter.push({
brand : $("input[type='radio']:checked").val(),
category: category
})
var json = JSON.stringify(parameter);
$.ajax({
type: "post",
url: "{% url 'seller_details' %}",
data: {
'parameter[]' : json ,
csrfmiddlewaretoken: '{{csrf_token}}'
},
contentType: 'application/json; charset=utf-8',
dataType:"json",
success: function(data) {
$('#loading-image').hide();
},
error: function(response, error) { }
});
});
</script>
I tried to send brand and category from the above script but it retains old data in the arrays brand, category and parameter. Is this the correct way to send data for the above scenario?

It sounds like you're defining the category array outside of the click handler and you're not clearing it's values between clicks. Also note that the if statement in the each block is redundant as the selector is only retrieving elements which are checked.
To solve the issue you can either change the code so that the array is defined inside the handler:
$('#brand_category').click(function(event) {
var category = [];
$("input:checkbox[name=category]:checked").each(function(){
category.push($(this).val());
});
// rest of your code...
});
Alternatively you can generate the array from scratch on each click:
var category = [];
$('#brand_category').click(function(event) {
category = $("input:checkbox[name=category]:checked").map(function() {
return this.value;
}).get();
// rest of your code...
});

Related

Checkbox listener not firing

I have set up a checkbox that should appear with each row in the list. I would like to pass row.id and boolean based on checkbox state. But the problem is that it only works for the first checkbox: id and boolean state is passed.
{% for row in list %}
....
<label>
Off
<input name="active{{ row.id }}" id="active{{ row.id }}" type="checkbox" list_id="{{ row.id }}">
<span class="lever"></span>
On
</label>
....
{% endfor %}
I have added javascript to listen to checkbox state and after checking, send a POST request to Flask app. It works but it only fires when the first checkbox is checked, all other checkboxes generated by Jinja2 are ignored.
document.addEventListener('DOMContentLoaded', function () {
var checkbox = document.querySelector('.input[type="checkbox"]');
checkbox.addEventListener('change', function () {
var list_id = $(this).attr('list_id');
if (checkbox.checked) {
req = $.ajax({
url : '/dashboard',
type : 'POST',
data : { id: list_id, active : 'true' }
});
console.log(list_id);
} else {
req = $.ajax({
url : '/dashboard',
type : 'POST',
data : { id : list_id, active: 'false' }
});
console.log(list_id);
}
});
});
You only get the first when you use querySelector
you have a dot in front of the input that should not be there
You have jQuery, so use it - it will take all checkboxes in one go without the need for querySelectorAll
$(function() {
$('input[type="checkbox"]').on('change', function() {
var list_id = $(this).attr('list_id');
console.log(list_id);
req = $.ajax({
url: '/dashboard',
type: 'POST',
data: {
id: list_id,
active: this.checked ? 'true' : 'false'
}
});
});
});

Laravel SortableJS AJAX - How to rearrange order

I just implemented SortableJS in my Laravel project and want to rearrange the order of some elements. I have a list of "Blocks" which all have a database field of "Order" which is an integer. I show these blocks in descending order based on the value of the "Order" field.
Now I want to update these values with SortableJS using Ajax. How can I accomplish this?
Currently, I have a simple list
<div class="block-order-list">
#foreach($blocks as $block)
<div class="list-group-item"><i class="far fa-arrows handle mr-3"></i> {{$block->name}}</div>
#endforeach
</div>
And call an Ajax request like so:
$('.block-order-list').sortable({
animation: 150,
handle: '.handle',
store: {
set: function (sortable) {
let order = sortable.toArray();
console.log(order);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '{{ route('change_order', ['url', $page->url]) }}',
type: 'POST',
data: order,
success: function(data){
console.log(data)
}
})
}
}
});
To my PageController which contains
public function changeOrder($data)
{
return $data;
}
The request now only returns a string that says url which I find odd. In the url of the ajax request, I give a parameter called URL which I need to find the blocks attached to this specific page. My blocks database table looks like this
How can I accomplish this?
I guess you must use ID in your HTML list :
<div class="block-order-list">
#foreach($blocks as $block)
<div class="list-group-item" data-id="{{ $block->id }}>
<i class="far fa-arrows handle mr-3"></i> {{ $block->name }}
</div>
#endforeach
</div>
Then in your JS, build an array with ID => order :
let order = {};
$('.list-group-item').each(function() {
order[$(this).data('id')] = $(this).index();
});
Then in your ajax call :
$.ajax({
url: '{{ route('change_order', ['url', $page->url]) }}',
type: 'POST',
data: {order: order},
success: function(data){
console.log(data)
}
})
And in your controller :
public function changeOrder(Request $request)
{
foreach($request->get('order') as $id => $order) {
Block::find($id)->update(['order' => $order]);
}
}

auto check checkboxes for matching result in ajax call

I'm trying to make it so that when my ajax call is returned with an object/array, I can match up the results to checkboxes so that if there is a match I auto check the boxes
Here are my checkboxes
<input type="checkbox" name='Magazine' data-md-icheck />
<input type="checkbox" name='Website' data-md-icheck />
<input type="checkbox" name='Advertisement' data-md-icheck />
Now my ajax call is successful
I get back:
0: {}
type: "Magazine"
1: {}
type: "Website"
so in my ajax success, what I would like to do is take any result in that object, whether just one or all 3, and if the type matches the 'name' of the checkbox I want to check that box.
Here is my function that makes the successful ajax call. I just can't figure out a way to loop the return that I get so that I can match up any result that comes through
function getDetails(ID) {
console.log(ID);
$.ajax({
url: "/details",
data: {ID:ID},
_token: "{{ csrf_token() }}",
type: "POST",
success: function (data) {
},
});
};
So in this case, how would I modify my ajax success to check the magazine and website boxes?
Here is a pure JS and simple solution to this:-
// Assuming you get the response as an array of objects, which has a key as type
success: function (data) {
data.forEach(obj => {
let ele = document.getElementsByName(obj.type)[0];
if(ele) {
ele.checked = true;
}
});
}
This is how I would tackle it:
function getDetails(ID) {
console.log(ID);
$.ajax({
url: "/details",
data: {ID:ID},
_token: "{{ csrf_token() }}",
type: "POST",
success: function (data) {
for(var i=0;i<data.length;i++){
var item = data[i].type;
var checkbox = $('input[name="'+item+'"]);
if (checkbox.length){
checkbox.prop('checked', true);
}
}
},
});
};
Assume the result is pure text exactly the same as you provided (ES6+)
let a = 'result...'
['Magazine', 'Website', 'Advertisement'].filter(item => a.indexOf(item) != -1).forEach(item => {
let inputs = document.getElementsByName(item)
if (inputs.length > 0)
inputs[0].checked = true
})

Django select a valid choice error when populate select in the template

I get a validate error when I create a form with an empty select field:
area_sp = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control', 'id':'area_select'}))
then I populate the select in the template using ajax:
$.ajax({
url: '/endpoint/load_areas/',
type: 'post',
dataType: 'json',
data: {
'postcode': postcode
},
headers: {
'X-CSRFToken': "{{ csrf_token }}"
},
success: function (data) {
var ret = JSON.parse(data.result);
for (x in ret) {
$("#area_select").append(new Option(x, ret[x]));
}
},
error: function(data) {
alert("error");
}
});
Finally, when I submit the form I get the following error:
area_sp: Select a valid choice. 26835 is not one of the available choices.
Any idea?
Looks like you've just forgotten to define the valid choices. You have to tell the ChoiceField, otherwise you'll get a ValidationError. The docs about ChoiceField:
Validates that the given value exists in the list of choices.
So just set the choices attribute to whatever the form shall accept:
area_sp = forms.ChoiceField(
widget=forms.Select(
attrs={'class': 'form-control', 'id':'area_select'}
),
choices=[(value1, repr1), (value2, repr2), ...]
)

Django returning None after request.POST.get

I'm new to Django and AJAX and I'm trying to send the ID of a dropdown list to the Django View with an ajax POST. This ID is then used in a queryset filter to return with AJAX the row, based off the ID. I'm getting stuck with applying the filter to the query set, as it seems to be posting the ID and then a variable with None. When I print to console the variable sent in the POST I get the ID, followed by none, e.g.:
1748
None
My HTML is:
<select id="drugSet">
{% for dose in dose_set %}
<option id="{{ dose.pubmed_id }}">{{ dose.drug_name }}</option>
{% endfor %}
</select>
<span id="drugName"></span>
Javascript:
function NeedDrugInformation() {
var elementID = document.getElementById("drugSet");
var strUser = elementID.options[elementID.selectedIndex].id;
$.ajax({
type: "POST",
url: "drugsanddoses/",
dataType: "text",
async: true,
data: { csrfmiddlewaretoken: '{{ csrf_token }}', drugID: strUser },
});
$.ajax({
type: "GET",
url: "drugsanddoses",
dataType: "text",
async: true,
data: { csrfmiddlewaretoken: '{{ csrf_token }}' },
success: function (json) {
$('#drugName').html(json.drugInfo);
// $('.ajaxProgress').hide();
}
})
}
views.py:
def drugsanddoses(request):
drugIdentifier = request.POST.get('drugID')
print(drugIdentifier)
drugInfo = RiskCalculator.objects.values('drug_name', 'l_dose', 'h_dose', 'risk', 'pubmed_id', 'updated')
response_data = {}
try:
response_data['drugInfo'] = str(drugInfo)
except:
response_data['result'] = 'No details found'
response_data['message'] = 'There is currently no information in the database for this drug.'
return HttpResponse(json.dumps(response_data), content_type="application/json")
You're making two Ajax requests; one a POST, where the ID is present, and one a GET, where the ID is absent so it prints None. I don't really understand why you're making two requests, but that is what you are doing.

Categories