Fields with HTML tags are not sorting properly
Fields with HTML tags are not sorting properly

The data in the "Course Name" columns looks like this:
[code]
Course Name that should be 2nd
A Course that should be first
[/code]
I've set everything up correctly as far as I can tell, but fields with html tags in each field are still being sorted by the raw data including markup and not the displayed data.... which basically means they are sorted by the id number passed to the Course_Details.php page.
You can view this in action here: http://blogs.wiueacademy.org/courseenroll/Course_Listing.php
Here is the javascript on this page:
[code]
var oTable;
$(document).ready(function() {
/* Init the table */
oTable = $('#datatables').dataTable( {
"bProcessing": false,
"bServerSide": true,
"bStateSave": true,
"sAjaxSource": "DataTables/AjaxSources/ajax_Course_Listing.php",
"bJQueryUI": true,
"bPaginate": false,
//"sPaginationType": "full_numbers",
// or
"bScrollInfinite": true,
"bAutoWidth": false,
"sScrollY": "250px",
//"bScrollCollapse": true,
"aoColumns": [
/* Course Name */ { "sType": 'html', "sWidth": "25%", "sSortDataType": "dom-text" },
/* Course Type */ { "sType": 'html', "sWidth": "13%", "sSortDataType": "dom-text" },
/* Teacher */ { "sType": 'html', "sWidth": "17%", "sSortDataType": "dom-text" },
/* Host District */ { "sType": 'html', "sWidth": "15%", "sSortDataType": "dom-text" },
/* Number Enrolled */ { "sType": 'html', "sWidth": "10%", "sSortDataType": "dom-text" },
/* Start Date */ { "sType": 'date', "sWidth": "10%", "sSortDataType": "dom-text" },
/* End Date */ { "sType": 'date', "sWidth": "10%", "sSortDataType": "dom-text" }
],
// Sort first by course name, then by course type, then by start enroll date
"aaSorting": [[0, "asc"], [1, "asc"], [4, "asc"]],
"sDom": '<"H"Tfr>t<"F"ip>',
"oTableTools": {
"sRowSelect": "single",
"aButtons": [
{
"sExtends": "copy",
"sButtonText": "Copy to Clipboard"
},
{
"sExtends": "xls",
"sButtonText": "Save for Excel"
},
{
"sExtends": "pdf",
"sButtonText": "Save as PDF",
"sPdfOrientation": "landscape",
"sPdfMessage": "Course Listing - Generated <?php echo date("F d, Y"); ?>"
}
],
"sSwfPath": "DataTables/extras/TableTools/media/swf/copy_cvs_xls_pdf.swf"
}
} );
} );
[/code]
[code]
Course Name that should be 2nd
A Course that should be first
[/code]
I've set everything up correctly as far as I can tell, but fields with html tags in each field are still being sorted by the raw data including markup and not the displayed data.... which basically means they are sorted by the id number passed to the Course_Details.php page.
You can view this in action here: http://blogs.wiueacademy.org/courseenroll/Course_Listing.php
Here is the javascript on this page:
[code]
var oTable;
$(document).ready(function() {
/* Init the table */
oTable = $('#datatables').dataTable( {
"bProcessing": false,
"bServerSide": true,
"bStateSave": true,
"sAjaxSource": "DataTables/AjaxSources/ajax_Course_Listing.php",
"bJQueryUI": true,
"bPaginate": false,
//"sPaginationType": "full_numbers",
// or
"bScrollInfinite": true,
"bAutoWidth": false,
"sScrollY": "250px",
//"bScrollCollapse": true,
"aoColumns": [
/* Course Name */ { "sType": 'html', "sWidth": "25%", "sSortDataType": "dom-text" },
/* Course Type */ { "sType": 'html', "sWidth": "13%", "sSortDataType": "dom-text" },
/* Teacher */ { "sType": 'html', "sWidth": "17%", "sSortDataType": "dom-text" },
/* Host District */ { "sType": 'html', "sWidth": "15%", "sSortDataType": "dom-text" },
/* Number Enrolled */ { "sType": 'html', "sWidth": "10%", "sSortDataType": "dom-text" },
/* Start Date */ { "sType": 'date', "sWidth": "10%", "sSortDataType": "dom-text" },
/* End Date */ { "sType": 'date', "sWidth": "10%", "sSortDataType": "dom-text" }
],
// Sort first by course name, then by course type, then by start enroll date
"aaSorting": [[0, "asc"], [1, "asc"], [4, "asc"]],
"sDom": '<"H"Tfr>t<"F"ip>',
"oTableTools": {
"sRowSelect": "single",
"aButtons": [
{
"sExtends": "copy",
"sButtonText": "Copy to Clipboard"
},
{
"sExtends": "xls",
"sButtonText": "Save for Excel"
},
{
"sExtends": "pdf",
"sButtonText": "Save as PDF",
"sPdfOrientation": "landscape",
"sPdfMessage": "Course Listing - Generated <?php echo date("F d, Y"); ?>"
}
],
"sSwfPath": "DataTables/extras/TableTools/media/swf/copy_cvs_xls_pdf.swf"
}
} );
} );
[/code]
This discussion has been closed.
Replies
I'm just not sure how to implement it. Where should the code listed go? I tried adding it to the multiple locations in the section of the webpage, but nothing seemed to make a difference.
I also noticed that filtering is broken too... If you type "hidden" into the search box, nothing should be displayed, but since that is part of the html tags, everything matches and is shown.
HELP?
Is anyone out there?
I sure wish I could get an answer or at least an acknowledgement. It feels like the forums are meant to suck on purpose to force people into "donating" to get help. I love open source software and I'm all for donations, but come on. If I would receive adequate and prompt support for simple questions THEN I would gladly donate... but not the other way around.
Anyway, sorry about that. Anyone out there have any ideas?
Thanks.
Sorry you haven't had an answer to your question yet - I'm just one person and simply can't answer the 30+ questions that I get every single day unfortunately while also trying to continue development of DataTables. I do try my best to get through as many as possible though...
From your initialisation you are using server-side processing, which means that the sorting is being done on the server-side, and not on the client-side by DataTables. So the answer to your question lies in PHP and SQL (note that the sType property that you've set has no effect on that, since sType is client-side only).
So... how is the data stored in your database? I'm going to guess that the HTML is in there since you are saying that it sorted by that, and the SQL engine will be doing that sorting. Is that right, or are you rendering in the HTML somewhere else? Ideally it would be the latter since then the sort is trivial! If you could elaborate on that, perhaps I'll be able to offer a solution (hopefully promptly :-) ).
Regards,
Allan
[code]
SELECT concat ("", c.name, "" ), c.courseType, concat( "", t.firstName, " ", t.lastName, "" ) fullname, concat( "", d.shortName, "" ) district, c.startDate, c.endDate
FROM courses c, teachers t, districts d
WHERE t.teacherID = c.teacherID
AND d.districtID = c.districtID
[/code]
This is done using all the variables in the standard example php file like this:
[code]
$q1 = "'";
$q2 = '"';
$courseName = "concat ( ".$q2."
The client-side code _could_ sort it, but since the client-side only has the information for each individual page that is shown and not the full dataset (when using server-side processing) then you would only be sorting that single page, and not the full data set - which would result in incorrect behaviour.
Is there a reason why you are doing the concat in SQL and not in PHP? It seems to me that you are really doing the operation twice at the moment (building the query and then having the SQL engine do the concat). Can you do the rendering of the HTML return to DataTables after you've done the SQL queries needed? That should also result in the ordering being correct (since at the moment I would guess the resultant query is actually doing ORDER BY contact(...).
Allan
Allan
New server-side code follows:
[code]
<?php
$aColumns = array( 'c.courseID', 'c.name', 'c.courseType', 't.email', 't.firstName', 't.lastName', 'd.websiteURL', 'd.shortName', 'c.enrollmentCount', 'c.maxEnrollment', 'c.startDate', 'c.endDate');
$sIndexColumn = "c.courseID";
$sIndexTable = "courses c";
$sTable = "courses c, teachers t, districts d";
$sWhere = "WHERE c.teacherID = t.teacherID AND c.districtID = d.districtID";
/* Database connection information removed*/
$gaSql['link'] = mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password'] ) or
die( 'Could not open connection to server' );
mysql_select_db( $gaSql['db'], $gaSql['link'] ) or
die( 'Could not select database '. $gaSql['db'] );
$sLimit = "";
if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
{
$sLimit = "LIMIT ".mysql_real_escape_string( $_GET['iDisplayStart'] ).", ".
mysql_real_escape_string( $_GET['iDisplayLength'] );
}
if ( isset( $_GET['iSortCol_0'] ) )
{
$sOrder = "ORDER BY ";
for ( $i=0 ; $i $iFilteredTotal,
"aaData" => array()
);
while ( $aRow = mysql_fetch_array( $rResult ) )
{
$row = array();
for ( $i=0 ; $i
[/code]
Allan
[code]
SELECT SQL_CALC_FOUND_ROWS c.courseID, c.name, c.courseType, t.email, t.firstName, t.lastName, d.websiteURL, d.shortName, c.enrollmentCount, c.maxEnrollment, c.startDate, c.endDate
FROM courses c, teachers t, districts d
WHERE c.teacherID = t.teacherID AND c.districtID = d.districtID
ORDER BY c.courseID asc
[/code]
With the results array being:
[code]
Array
(
[0] => 1
[courseID] => 1
[1] => Algebra II
[name] => Algebra II
[2] => Mathematics
[courseType] => Mathematics
[3] => asdasd@asdasd.com
[email] => asdasd@asdasd.com
[4] => Joe
[firstName] => Joe
[5] => Smith
[lastName] => Smith
[6] => http://www.bellevernonarea.net/bvasd/site/default.asp
[websiteURL] => http://www.bellevernonarea.net/bvasd/site/default.asp
[7] => BVASD
[shortName] => BVASD
[8] => 5
[enrollmentCount] => 5
[9] => 20
[maxEnrollment] => 20
[10] => 02/02/2011
[startDate] => 02/02/2011
[11] => 06/03/2011
[endDate] => 06/03/2011
)
[/code]
Using the SQL concat() function gives me this query:
[code]
SELECT SQL_CALC_FOUND_ROWS concat ( " ", c.name ), c.courseType, concat( "", t.firstName, " ", t.lastName, "" ), concat( "", d.shortName, "" ), concat( c.enrollmentCount, " of ", c.maxEnrollment ), c.startDate, c.endDate
FROM courses c, teachers t, districts d
WHERE c.teacherID = t.teacherID AND c.districtID = d.districtID
ORDER BY concat ( " ", c.name
[/code]
With these results:
[code]
Array
(
[0] => Algebra II
[concat ( " ", c.name )] => Algebra II
[1] => Mathematics
[courseType] => Mathematics
[2] => Joe Smith
[concat( "", t.firstName, " ", t.lastName, "" )] => Joe Smith
[3] => BVASD
[concat( "", d.shortName, "" )] => BVASD
[4] => 5 of 20
[concat( c.enrollmentCount, " of ", c.maxEnrollment )] => 5 of 20
[5] => 02/02/2011
[startDate] => 02/02/2011
[6] => 06/03/2011
[endDate] => 06/03/2011
)
[/code]
I guess I'll have to modify the received ORDER BY string to sort by the correct field... I was just hoping DataTables would save me the trouble of hard-coding this for each "combined" column.
I have described a method to use all of datatables default features with any data source and no extra coding in the back-end as shown here. Its still experimental, but I managed to put in a full fledged CRUD today.
I think I've found a solution however... not really ideal, but I'm testing it now. once complete I will post back.
I went back to the concat() method and I modified the the ordering section to this:
[code]
/*
* Ordering
*/
if ( isset( $_GET['iSortCol_0'] ) )
{
$sOrder = "ORDER BY ";
for ( $i=0 ; $i= 1){
$sOrder .= "c.name ".mysql_real_escape_string( $_GET['sSortDir_'.$i] ).", ";
}else{
$sOrder .= $aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."
".mysql_real_escape_string( $_GET['sSortDir_'.$i] ) .", ";
}
}
}
$sOrder = substr_replace( $sOrder, "", -2 );
if ( $sOrder == "ORDER BY" )
{
$sOrder = "";
}
}
[/code]
I just look for part of the column string's data that would be unique to the first columns contents ("
Regards,
Allan
1%, 5%, 30%.
It would sort like,
1%, 30%, 5%.
it is in link href tag and has a % sign. it does not sort properly. what should i do?
Allan
I´m new using this plug-in. I need to use a big query taht contains like 8 INNER JOIN. The case is that when I try to use the same structure as compcentral on one March post, I'm getting the "Unknown column 'u.id' in 'field list'" error...which I haven't been able to figure out.
My values for those variables are:
$aColumns = array('u.firstname', 'u.lastname', 'u.email', 'u.city', 'u.country',
'd.data', 'u.institution', 'c.fullname', 'p.finalgrade',
'ci.code', 'qt.Quizes_tomados', 'cu.Quizes_del_curso', 'FROM_UNIXTIME(u.lastaccess)' );
/* Indexed column (used for fast and accurate table cardinality) */
$sIndexColumn = "u.id";
$sIndexTable = "mdl_user u";
/* DB table to use */
$sTable = "((((((mdl_user u LEFT JOIN mdl_user_info_data d ON u.id = d.userid AND d.fieldid=1)
LEFT JOIN (SELECT mdl_grade_grades_history.userid, mdl_grade_grades_history.itemid, mdl_grade_grades_history.finalgrade
FROM mdl_grade_grades_history INNER JOIN (SELECT userid, itemid, max(timemodified) UltimaFechaQuiz
FROM mdl_grade_grades_history
GROUP BY userid, itemid) UltimosQuicesUsuarios
ON mdl_grade_grades_history.userid = UltimosQuicesUsuarios.userid
AND mdl_grade_grades_history.itemid = UltimosQuicesUsuarios.itemid
AND mdl_grade_grades_history.timemodified = UltimosQuicesUsuarios.UltimaFechaQuiz
WHERE mdl_grade_grades_history.rawgrademax=100 AND mdl_grade_grades_history.finalgrade is not null) p ON u.id = p.userid)
LEFT JOIN mdl_grade_items g ON p.itemid = g.id)
LEFT JOIN mdl_course c ON g.courseid = c.id)
LEFT JOIN mdl_certificate_issues ci ON ci.userid = u.id AND ci.classname = c.fullname)
LEFT JOIN (Select Usuarios_Cursos.userid, Usuarios_Cursos.course, Cursos.Quizes_del_curso
From (Select distinct mdl_quiz_grades.userid, mdl_quiz.course
From mdl_quiz_grades inner join mdl_quiz on mdl_quiz_grades.quiz = mdl_quiz.id) Usuarios_Cursos
inner join (Select mdl_quiz.Course, Count(1) Quizes_del_curso
From mdl_quiz
Group by mdl_quiz.Course) Cursos on Usuarios_Cursos.Course = Cursos.Course
) cu ON u.id = cu.userid AND c.id = cu.course)
LEFT JOIN (Select mdl_quiz_grades.userid, mdl_quiz.course, Count(1) Quizes_tomados
From mdl_quiz_grades inner join mdl_quiz on mdl_quiz_grades.quiz = mdl_quiz.id
Group by mdl_quiz_grades.userid, mdl_quiz.course
) qt ON u.id = qt.userid AND c.id = qt.Course";
Please someone help to fix these error. I know it may be a stupid error but still all I've tried isn't enough to fix it. Thanks!
That sounds like an SQL error to me. You might be best asking on an SQL forum or on SO where people more knowledgable in SQL than me will be.
Allan
thanks for your quick answer, I did find some answer to this.
Now I'm having the same as problem as you did, I mean I'm getting JSON code when I called the script, but unfortunately the "DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error." dialog box error still appears.
May you tell me what I can do to fix that problem???? or can anyone help me?
Thanks!
Yes - return valid JSON from the server :-). Your JSON can be validated using http://jsonlint.com .
Allan