Request: Custom length control plugin using instead of

Request: Custom length control plugin using instead of

tomas_eklundtomas_eklund Posts: 14Questions: 1Answers: 0
edited January 2013 in Plug-ins
I'd like to have a plugin to generate an alternate DataTables length control that creates code similar to this example (if the markup, attributes, class names etc. in the example doesn't make sense, please feel free to use more sensible markup):

[code]
Show
20
50
all
entries
[/code]

So, instead of using and to select the number of records displayed on each page, I just want a number of tags - similar to how the pagination controls are rendered. I will then use CSS to style these as nice looking buttons.

The reason I want this is that a control will break the "look and feel" of the DataTables in the highly "designed" project I'm currently working on - we need "buttons".

It would be really nice if this plugin could be used as a direct replacement for the built-in length control, using and taking into account settings of the Options object such as aLengthMenu, oLanguage.sLengthMenu etc. My idea is that it could be implemented as a feature plug-in and tied to the letter "L" for example.

I'm not sure if it is appropriate to use paid support to make requests such as this one, but I'm giving it a shot.

Replies

  • allanallan Posts: 61,805Questions: 1Answers: 10,119 Site admin
    Sounds like the perfect use case for a feature plug-in :-).

    I've put an example of how this can be done here:
    http://live.datatables.net/iwomen/edit#javascript,html,live

    There are three parts to how it is implemented:

    1. I've use the fnLengthChange API plug-in method to actually do the length changing (DT 1.10 will have a similar method built-in).

    2. A feature plug-in creates the HTML needed, based on the information in the settings object. This is checked on each draw to see if it needs to be updated. The feature plug-in is also registered using the DataTables API.

    3. The table is initialised with the sDom option, where the original length menu option ( `l` ) has been replaced with the new one added by the feature plug-in ( `L` ). This means you could have the length menu at the top and the bottom of the table if your style guide calls for that.

    A little touch of CSS to style it will finish it off :-).

    I've got a blog post about how to create feature plug-ins, which might be useful if you want to go through and deconstruct my code.

    Also worth noting that, normally, yes, new plug-in creation like this falls outside the scope of the DataTables support offering, but this one was relatively simple (plug-ins can suffer feature creep very easily!).

    Regards,
    Allan
  • tomas_eklundtomas_eklund Posts: 14Questions: 1Answers: 0
    Yay! You saved my day! Actually, you probably saved me several days - I'm not sure I would have pulled that off in one sitting. It works great. Now the client will be happy and I can focus on the parts of the project which I actually know how to handle. ;-)

    Thanks!
  • tomas_eklundtomas_eklund Posts: 14Questions: 1Answers: 0
    edited January 2013
    I'm posting Allan's code here so that other forum users may benefit from it.

    [code](function(window, document, $, undefined) {

    $.fn.dataTableExt.oApi.fnLengthChange = function ( oSettings, iDisplay ) {
    oSettings._iDisplayLength = iDisplay;
    oSettings.oApi._fnCalculateEnd( oSettings );

    /* If we have space to show extra rows (backing up from the end point - then do so */
    if ( oSettings._iDisplayEnd == oSettings.aiDisplay.length ) {
    oSettings._iDisplayStart = oSettings._iDisplayEnd - oSettings._iDisplayLength;
    if ( oSettings._iDisplayStart < 0 ) {
    oSettings._iDisplayStart = 0;
    }
    }

    if ( oSettings._iDisplayLength == -1 ) {
    oSettings._iDisplayStart = 0;
    }

    oSettings.oApi._fnDraw( oSettings );
    };


    $.fn.dataTable.LengthLinks = function ( oSettings ) {
    var container = $('').addClass( oSettings.oClasses.sLength );
    var lastLength = -1;
    var draw = function () {
    // No point in updating - nothing has changed
    if ( oSettings._iDisplayLength === lastLength ) {
    return;
    }

    var menu = oSettings.aLengthMenu;
    var lang = menu.length===2 && $.isArray(menu[0]) ? menu[1] : menu;
    var lens = menu.length===2 && $.isArray(menu[0]) ? menu[0] : menu;

    var out = $.map( lens, function (el, i) {
    return el == oSettings._iDisplayLength ?
    ''+lang[i]+'' :
    ''+lang[i]+'';
    } );

    container.html( oSettings.oLanguage.sLengthMenu.replace( '_MENU_', out.join(' ') ) );
    lastLength = oSettings._iDisplayLength;
    };

    // API, so the feature wrapper can return the node to insert
    this.container = container;

    // Update on each draw
    oSettings.aoDrawCallback.push( {
    "fn": function () {
    draw();
    },
    "sName": "PagingControl"
    } );

    // Listen for events to change the page length
    container.on( 'click', 'a', function (e) {
    e.preventDefault();
    oSettings.oInstance.fnLengthChange( parseInt( $(this).attr('data-length'), 10 ) );
    } );
    };

    // Subscribe the feature plug-in to DataTables, ready for use
    $.fn.dataTableExt.aoFeatures.push( {
    "fnInit": function( oSettings ) {
    var l = new $.fn.dataTable.LengthLinks( oSettings );
    return l.container[0];
    },
    "cFeature": "L",
    "sFeature": "LengthLinks"
    } );


    })(window, document, jQuery);


    // DataTables initialisation
    $(document).ready(function() {
    $('#example').dataTable( {
    "sDom": "Lfrtip"
    } );
    } );[/code]
  • allanallan Posts: 61,805Questions: 1Answers: 10,119 Site admin
    I'll add this to the DataTables plug-ins repo if you are okay with that? With 1.11 onwards, I'd like to make DataTables much more flexible with the control that it shows, so you can easily select a plug-in such as this, and a script will build a DataTables package just for you - removing code that isn't needed to keep file sizes down.

    Allan
  • tomas_eklundtomas_eklund Posts: 14Questions: 1Answers: 0
    Absolutely.
This discussion has been closed.