JQuery DataTables - Row Grouping, Sum, Collapsible

2019-04-17 21:31发布

问题:

I've been using JQuery DataTables for a long time. This is the first time I'll be working with row grouping. I found a good example of where I want to start. - Grouping

  1. How would I add an extra <td> to the grouped row? What if I wanted to display the sum of the grouped salaries on that grouped row? Right now, it looks like you can only display the name of the group.

  1. Can I make these rows collapsible like they are Here and Here? It looks like this is a different plugin than the original grouping code. This look would be my preference, but working with child rows doesn't seem to be the same as grouping.

Additional Info

I will be returning data from an Ajax source.

UPDATE 1

So, I built a table with row grouping and found this example of how to sum up a column. I'm plugging that value into a <td> in that group row. All I need now is how to break that sum amount up into the groups instead of the sum of the entire column. I need help with this.

"drawCallback": function (settings) {
    var api = this.api(), data;
    var rows = api.rows({ page: 'current' }).nodes();
    var last = null;

    //Calculates the total of the column
    var total = api
        .column(5)  //the salary column
        .data()
        .reduce(function (a, b) {
            return a + b;
        }, 0);

    //Groups the Office column
    api.column(2, { page: 'current' }).data().each(function (group, i) {
        if (last !== group) {
            $(rows).eq(i).before(
                '<tr class="group"><td>' + group 
                 + '</td><td></td><td></td><td></td><td>' 
                 + total + '</td></tr>'
            );

            last = group;
        }
    });                  
}

UPDATE 2

It doesn't look to me like DataTables can provide all the functionality I need. Row grouping doesn't have built in subtotals or collapsiblity. Even if I'm able to create something custom to do that, it looks like these group rows aren't picked up during exports, which is another requirement I need. I'll probably have to go another route. Unless someone can fulfill all of these needs, don't bother.

UPDATE 3

I've decided to go with Kendo Grids instead. All of this functionality is built in already.

回答1:

"drawCallback": function ( settings ) {
	var api = this.api(),data;
	var rows = api.rows( {page:'current'} ).nodes();
	var last=null;
	
	// Remove the formatting to get integer data for summation
	var intVal = function ( i ) {
		return typeof i === 'string' ?
			i.replace(/[\$,]/g, '')*1 :
			typeof i === 'number' ?
				i : 0;
	};

	total=new Array();
	api.column(2, {page:'current'} ).data().each( function ( group, i ) {
	    group_assoc=group.replace(' ',"_");
        if(typeof total[group_assoc] != 'undefined'){
            total[group_assoc]=total[group_assoc]+intVal(api.column(5).data()[i]);
        }else{
            total[group_assoc]=intVal(api.column(5).data()[i]);
        }
		if ( last !== group ) {
			$(rows).eq( i ).before(
				'<tr class="group"><td colspan="4">'+group+'</td><td class="'+group_assoc+'"></td></tr>'
			);
			
			last = group;
		}
	} );
    for(var key in total) {
        $("."+key).html("$"+total[key]);
    }
}



回答2:

I have check your code and review your given link with example.

I have also check your UPDATE

I found that the **Kendo Grids** is the best option as per your requirement.

So i suggest to use : UPDATE 3



回答3:

Check out in your code the line.. " if (last !== group) I added 2 buttons:

  • expands->calls function 'abrir'
  • close->calls function 'cerrar'

both recive the group element example: 'MAZDA', 'TOYOTA', 'BMW'

if (last !== group)
{
groupid++;
alert(group);
$(rows).eq(i).before(
'<tr class="group father_' + group + ' text-right"><td class="text-left"><text class="order">'
+ group +
'</text>'+
' <i class="fa fa-plus-square-o" aria-hidden="true" btn btn-default btn-xs" onclick="abrir(\''+group+'\')">'+
' <i class="fa fa-minus-square-o aria-hidden="true"  btn btn-default btn-xs" onclick="cerrar(\''+group+'\')">'+
'</td></tr>');
last = group;
}

Here are the functions 'abrir' and 'cerrar' I put em outside the datatables script

<script>
    function abrir(group) {
        $(".collapse_"+group).collapse("show");
    }

    function cerrar(group) {
        $(".collapse_"+group).collapse("hide");
    }
</script>

Then after drawcallback I use (this is the clue):

"fnRowCallback": function (nRow, aData, iDisplayIndex)
 {
   nRow.className = "collapse collapse_" + aData.LINEA;
   return nRow;
 },

What Im doing here?... For every simple row add the bootstrap class "collapse" and my own class collapse_+aData.LINEA where linea is de field that Im grouping by so finally -> class="collapse collapse_MAZDA" class="collapse collapse_BMW"

This elements may be hidden by default, when you action the buttons on the group rows it will look for the elements that have the class "collapse_MAZDA" AN