jQuery get all rows using table.rows().data().each with pagination - javascript

I can't find a solution online for this. I have my code like this
$('.validation-summary-table').dataTable({ paging: true, ordering: false });
const conflictsArray = pushConflictDatas('#conflict .validation-summary-table tbody tr.odd');
function pushConflictDatas(dataTableTr) {
let radioButtonsConflicts = new Array();
$(dataTableTr).each(function() {
const currentRow = $(this).closest("tr"); // CSV row
const nextRow = currentRow.next(); // DB row
let currentRowObj = {
Name: currentRow.find('td:eq(0)').text().trim(),
isChecked: currentRow.find('td:eq(1) input[type="radio"]').is(':checked')
}
let nextRowObj = {
Name: nextRow.find('td:eq(0)').text().trim(),
isChecked: nextRow.find('td:eq(1) input[type="radio"]').is(':checked')
}
radioButtonsConflicts.push([currentRowObj, nextRowObj]);
});
return radioButtonsConflicts;
}
This worked fine until I found out it wasn't getting all table rows on the next pages when I click a button, only the current page and nothing else. I need to get all the rows and push them to an array for my ajax request. So I found this code from their docs:
var table = $(conflictTable).DataTable();
table.rows('.odd').data().each(function (value, index) {
console.log('index: ', index)
console.log('value: ', value)
} );
However this only selects <tr> on the current page, just like what the old function does. If I move to the next page, it will "append" it. If I remove the selector .odd, it would get all the rows from all paginated pages, but I'm writing a code that targets the next row and I want to only select rows with a specific class name before I do such. How do I do this?

You can use the following code to get all table data:
let table_data = table.rows({ search: 'applied'}).data();

Related

Custom Dependent Dropdown menu inside the Django admin

I have a project foreign key in by Phase model. I'm having hard time Create a dependent drop-down list inside my Django admin page.
I want to when user select a project from (project drop-down) phase of that project show in second dop-down
What would be the best way to achieve this?
It would be great if the dropdowns filter items based on the value of its parent.
class Project(models.Model):
name = models.CharFieldmax_length = 100, unique= True)
short_name = models.CharField(max_length= 4, unique= True)
slug = models.SlugField(max_length= 100, allow_unicode=True, null=True, editable= False)
location = models.OneToOneField(Location, on_delete = models.SET_NULL, null= True, blank= False, verbose_name= 'موقعیت')
start_date = models.DateField(default= timezone.now, null= True, blank= True)
end_date = models.DateField(default= timezone.now, null= True, blank= True)
duration = models.IntegerField(default= 0, editable= False)
class Phase(models.Model):
title = models.CharField(max_length= 20)
class ProjectPhase(models.Model):
project = models.ForeignKey(Project, on_delete= models.CASCADE, related_name= 'phase')
phase = models.ForeignKey(Phase, on_delete=models.CASCADE, related_name= 'project')
start_date = models.DateField(default= timezone.now)
end_date = models.DateField(default= timezone.now)
duration = models.IntegerField(default= 0, editable= True)
1. import a js media file in ModelAdmin for Generaldata:
class YourModelAdmin(admin.ModelAdmin):
form = YourModelForm
#list_display = ['your fields',]
class Media:
js = ("yourapp/selectajax.js",)
admin.site.register(YourModel, YourModelAdmin)
2. create a new js file which saved yourproject/yourapp/static/yourapp/ directory or another proper directory.
jQuery(function($){
$(document).ready(function(){
$("#id_project_select").change(function(){
// console.log(obj.currentTarget.value);
$.ajax({
url:"/get_phases/",
type:"POST",
data:{project: $(this).val(),},
success: function(result) {
console.log(result);
cols = document.getElementById("id_phase_select");
cols.options.length = 0;
for(var k in result){
cols.options.add(new Option(k, result[k]));
}
},
error: function(e){
console.error(JSON.stringify(e));
},
});
});
});
});
3. create a view to process ajax
#login_required
def get_phases(request):
project = request.POST.get('project')
phases = {}
try:
if project:
prophases = Project.objects.get(pk=int(project)).phase
phases = {pp.phase.title:pp.pk for pp in prophases}
except:
pass
return JsonResponse(data=phases, safe=False)
4. add 'get_phases/ to urlpatterns.
Notice that you should modify some codes as your need.
The answer by Blackdoor is a good approach and it's the one we just implemented, but it has a couple of problems:
It's only executed when you change the main select, and I wanted the dependant select to be filtered also on page load.
Does not keep que selected item in the dependant select.
In his solution, in step 2, replace his code with this one and adapt the names (I'm using service and sub_service instead of project / phase):
jQuery(function($){
$(document).ready(function(){
var clone = document.getElementById("id_sub_service").cloneNode(true);
$("#id_service").change(function(){
update_sub_services($(this).val(), clone)
});
update_sub_services($("#id_service").val(), clone)
});
function update_sub_services(service, clone) {
$.ajax({
url:"/chained_dropdowns/get_sub_services/",
type:"GET",
data:{service: service,},
success: function(result) {
var cols = document.getElementById("id_sub_service");
cols.innerHTML = clone.innerHTML
Array.from(cols.options).forEach(function(option_element) {
var existing = false;
for (var k in result) {
if (option_element.value == k) {
existing = true
}
}
if (existing == false) {
$("#id_sub_service option[value='"+option_element.value+"']").remove();
}
})
},
error: function(e){
console.error(JSON.stringify(e));
},
});
}
});
As you can see, now instead of removing all the items from the dependant select and then refilling it (which leaves you without the selected property and any other custom property), it removes the options that should not be there.
I'm not a JS developer and I don't know jQuery so my modifications are in native JS, please feel free to improve it :)

How to perform .delete() queryset in Django in a ListView?

Here is what I've done so far:
1.) I've made a javascript function that gets all the id's of the items (using checkbox select) in the database like so (this is DataTables):
function () {
// count check used for checking selected items.
var count = table.rows( { selected: true } ).count();
// Count check.
// Count must be greater than 0 to delete an item.
// if count <= 0, delete functionality won't continue.
if (count > 0) {
var data = table.rows( { selected: true } ).data();
var list = [];
for (var i=0; i < data.length ;i++){
// alert(data[i][2]);
list.push(data[i][2]);
}
var sData = list.join();
// alert(sData)
document.getElementById('delete_items_list').value = sData;
}
}
It outputs something like 1,2,5,7 depending on what rows I have selected.
2.) Passed the values inside a <input type="hidden">.
Now, I've read a post that says you can delete data in Django database using a checkbox, but I'm not sure how exactly can I use this.
I'm guessing I should put it in the ListView that I made, but how can I do that when I click the "Delete selected items" button, I can follow this answer?
I'm trying to achieve what Django Admin looks like when you delete items.
My ListView looks like this:
Yes you can use linked example. Django Admin do it the same way, You send selected ids and django do filtering by given values and after django apply selected action for selected items.
UPDATE
For example.
class List(ListView);
def post(self, request, *args, **kwargs):
ids = self.request.POST.get('ids', "")
# ids if string like "1,2,3,4"
ids = ids.split(",")
try:
# Check ids are valid numbers
ids = map(int, ids)
except ValueError as e:
return JsonResponse(status=400)
# delete items
self.model.objects.filter(id__in=ids).delete()
return JsonResponse({"status": "ok"}, status=204)
And html:
<button id="delete-button">Del</button>
<div id="items-table">
{% for object in objects_list %}
<div class="item" data-id="{{object.id}}">{{ object.name }}</div>
{% endfor %}
</div>
<script>
$(function(){
$('#delete-button').on('click', function(e) {
// Get selected items. You should update it according to your template structure.
var ids = $.map($('#items-table item'), function(item) {
return $(item).data('id')
}).join(',');
$.ajax({
type: 'POST',
url: window.location.href ,
data: {'ids': ids},
success: function (res) {
// Update page
window.location.href = window.location.href;
},
error: function () {
// Display message or something else
}
});
})
})();
</script>

DataTables - Getting the database ID of the current row via click event

I am trying to get the database ID of the current row while clicking a button.
I have seen a few examples relating to this aspect and have tried many but it seems that they mostly relate to the legacy table tools extension whereas I am making use of the Editor.
Using the idSrc option from the Editor manual I recieve a server side response in JSON that contains the databases id/primary key value:
{
"data":[
{
"id":"1",
"name":"Test Name",
}
],
"options":[],
"files":[]
}
Now I am trying to get that value by clicking a button that is attached to row via the API function: row().id()
Within the example for this function it provides a clear example of how the rows id value (now the database id?) can be obtained:
var table = $('#myTable').DataTable();
$('#myTable').on( 'click', 'tr', function () {
var id = table.row( this ).id();
alert( 'Clicked row id '+id );
});
So I have implemented this as follows:
var editor;
$(document).ready(function() {
editor = new $.fn.dataTable.Editor( {
ajax: "/names.php",
table: "#example",
idSrc: "id",
fields: [ {
label: "Name:",
name: "name"
} ]
});
var table = $('#example').DataTable( {
dom: "Bfrtip",
ajax: "/names.php",
columns: [
{ data: "name" }
]
});
$('#example').on( 'click', 'tr', function () {
var id = table.row( this ).id();
alert( 'Clicked row id ' + id );
});
});
The problem here though is that when I click on the row (tr) it prompts as follows: Clicked row id undefined
Why am I getting back an undefined value when it should be sending back the row id?
When instances your DataTable, you must indicate the id field rowId, which should be indicated as the name of your columns
var table = $('#example').DataTable( {
dom: "Bfrtip",
ajax: "/names.php",
columns: [
{ data : "id" },//id is the name of your data
{ data: "name" }
],
rowId: 'id' //Here assign the id to your table
});
Result: https://jsfiddle.net/cmedina/7kfmyw6x/17/
As #CMedina pointed out, rowId stipulates which value in the JSON data is used as each rows id attribute.
Here is the code used to get the rows ID value which is prefixed with row_:
$('#example').on( 'click', 'tr', function () {
// Get the rows id value
var id = table.row( this ).id();
// Filter for only numbers
id = id.replace(/\D/g, '');
// Transform to numeric value
id = parseInt(id, 10);
// So instead of returning the actual id which is row_1
// We get back just the primary key which is 1
alert( 'Clicked row id '+id );
});

dynamically generating checkbox list from json

I'm dynamically generating a list of checkboxes based on the contents of json data:
Format of tempfairway:
[{"FairWay":"A"},{"FairWay":"B"}, {"FairWay":"C"}, {"FairWay":"D"}]
var topics = tempfairway;
var topicContainer = $('ul#fairway_list');
$.each(topics, function (iteration, item) { topicContainer.append(
$(document.createElement("li")).append(
$(document.createElement("input")).attr({
id: 'topicFilter-' + item,
name: item,
value: item,
type: 'checkbox',
checked: true
})
//onclick
.click(function (event) {
var cbox = $(this)[0];
alert(cbox.value);
})
).append(
$(document.createElement('label')).attr({
'for': 'topicFilter' + '-' + item
}).text(item)
)
)
});
The checkboxes generate fine with the correct number but i'm getting [object Object] instead of the name of the fairway.
Any ideas on how to fix this?
Couple of more questions to add to this:
-What if i wanted to display ONLY unique values in tempfairway?
-.Click is set to get the value of that single checkbox, what if i want to iterate through all the checkboxes and get the value of all the ones that were selected in the case that the user unselected any of them?
In the line:
> $.each(topics, function (iteration, item) {
item is an object like {"FairWay":"A"}, so where you have:
> .text(item)
you probably want:
.text(item.FairWay)
and similarly for other uses of item. Or you could store the value in a variable and use that:
var fairwayName = item.FairWay;
...
.text(fairwayName);

Tablesorter can not update table columns

I use table sorter function and need to update one or more cells. I try to do this:
var tr = document.getElementById('myTable').rows;
var table = jQuery(".tablesorter");
table.tablesorter();
.....
.....
for(l=1; l<newData[k].length; l++)
{
if(newData[k][l]!=tr[i].cells[l].innerHTML)
{
try{
$(tr[i].cells[l]).text(newData[k][l]);
table.trigger("updateCell",[this]);
}catch(e){alert(e);
}
}
but this produce the next exception message:
TypeError: cell.parentNode is undefined
Can anybody tell me how can I fix it to update the table columns?

Categories

Resources