Refinement of display when all rows are showing

Refinement of display when all rows are showing

jcokerjcoker Posts: 2Questions: 0Answers: 0
edited August 2010 in General
I made some minor changes to our copy of dataTables 1.7.0 which I thought I would post back for possible future inclusion. The display when the table is showing all available rows could be nicer; in particular, I wanted it to say "Showing all N entries" instead of "Showing 1 to N of N entries".

I added a new format string:
[code]
this.oLanguage = {
...
"sInfoAll": "Showing all _TOTAL_ entries",
[/code]
and reorganized the last two if blocks in _fnUpdateInfo into one with inner conditionals:
[code]
if ( oSettings.fnRecordsDisplay() === 0 &&
oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() )
{
/* Empty record set */
jqFirst.html( oSettings.oLanguage.sInfoEmpty+ oSettings.oLanguage.sInfoPostFix );
}
else if ( oSettings.fnRecordsDisplay() === 0 )
{
/* Empty record set after filtering */
jqFirst.html( oSettings.oLanguage.sInfoEmpty +' '+
oSettings.oLanguage.sInfoFiltered.replace('_MAX_', sMax)+
oSettings.oLanguage.sInfoPostFix );
}
else
{
/* Normal record set */
var info;
if ( oSettings._iDisplayStart === 0 &&
oSettings.fnDisplayEnd() === oSettings.fnRecordsDisplay() &&
oSettings.oLanguage.sInfoAll )
{
/* Showing all records */
info = oSettings.oLanguage.sInfoAll.replace('_START_', sStart)
.replace('_END_', sEnd)
.replace('_TOTAL_', sTotal);
}
else
{
/* Showing one page of a larger set */
info = oSettings.oLanguage.sInfo.replace('_START_', sStart)
.replace('_END_', sEnd)
.replace('_TOTAL_', sTotal);
}
if ( oSettings.fnRecordsDisplay() < oSettings.fnRecordsTotal() )
{
/* Record set after filtering */
info += ' ' + oSettings.oLanguage.sInfoFiltered.replace('_MAX_',
oSettings.fnFormatNumber(oSettings.fnRecordsTotal()));
}
info += oSettings.oLanguage.sInfoPostFix;
jqFirst.html( info );
}
[/code]
Note that I'm checking for the presence of the new sInfoAll string and replacing all three members so the previous behavior will occur by either specifying null or using the sInfo value for sInfoAll.

Thanks,
John

Replies

  • allanallan Posts: 63,755Questions: 1Answers: 10,509 Site admin
    Interesting one! Thanks for posting this John! You've made me wonder if it would be worth having a callback function (or dispatch an event) at this point in the code so it would be easy for everyone to customise the language string exactly as needed... I like that :-)

    Nice one - thanks.

    Regards,
    Allan
  • jcokerjcoker Posts: 2Questions: 0Answers: 0
    edited August 2010
    Yeah, I thought about a callback function, but I think your string approach makes localization easier. I guess the best approach would be a callback function with a default implementation that matches the current behavior.

    I did forget one case thought: exactly one row, in which case the best message would be "Showing one entry". I added one more sInfo flavor in my version (sInfoOne). For completeness, there should be an option for exactly two also (see http://en.wikipedia.org/wiki/Plural).

    Here's the code I ended up with. I also adjusted some default messages (since sInfoFiltered made the div wrap, which I thought was ugly). I think there could be a further simplification by just making all the branches of the if set sInfoFmt and then optionally tacking sInfoFiltered on at the end.

    [code]
    "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
    "sInfoEmpty": "Showing no entries",
    "sInfoOne": "Showing one entry",
    "sInfoAll": "Showing all _TOTAL_ entries",
    "sInfoFiltered": "(of _MAX_ total)",
    [/code]

    [code]
    _fnMap( oSettings.oLanguage, oLanguage, 'sInfo' );
    _fnMap( oSettings.oLanguage, oLanguage, 'sInfoEmpty' );
    _fnMap( oSettings.oLanguage, oLanguage, 'sInfoOne' );
    _fnMap( oSettings.oLanguage, oLanguage, 'sInfoAll' );
    [/code]

    [code]
    else
    {
    /* Normal record set */
    var sInfoFmt;
    if ( oSettings._iDisplayStart === 0 &&
    oSettings.fnDisplayEnd() === oSettings.fnRecordsDisplay() &&
    oSettings.fnDisplayEnd() === 1 &&
    oSettings.oLanguage.sInfoOne )
    {
    /* Showing only record */
    sInfoFmt = oSettings.oLanguage.sInfoOne;
    }
    else if ( oSettings._iDisplayStart === 0 &&
    oSettings.fnDisplayEnd() === oSettings.fnRecordsDisplay() &&
    oSettings.oLanguage.sInfoAll )
    {
    /* Showing all records */
    sInfoFmt = oSettings.oLanguage.sInfoAll;
    }
    else
    {
    /* Showing one page of a larger set */
    sInfoFmt = oSettings.oLanguage.sInfo;
    }
    var sInfo = sInfoFmt.replace('_START_', sStart)
    .replace('_END_', sEnd)
    .replace('_TOTAL_', sTotal);
    if ( oSettings.fnRecordsDisplay() < oSettings.fnRecordsTotal() )
    {
    /* Record set after filtering */
    sInfo += ' ' + oSettings.oLanguage.sInfoFiltered.replace('_MAX_',
    oSettings.fnFormatNumber(oSettings.fnRecordsTotal()));
    }
    sInfo += oSettings.oLanguage.sInfoPostFix;
    jqFirst.html( sInfo );
    }
    [/code]
  • allanallan Posts: 63,755Questions: 1Answers: 10,509 Site admin
    Yup it's a tricky one this one when considering every possible combination! sInfo for example needs multiple options as well... What I think I'll do is introduce a callback function after DataTables has tried it's best to render the string - this callback will be given the start, end, display numbers etc, and return a rendered string. This will allow compatibility with all the translations that are already available, and the flexibility for anyone who fancies taking it that step further.

    Regards,
    Allan
This discussion has been closed.