1. The 3.8 code for Fabrik is now available on github, in the 'master' branch. If you are familiar with updating Fabrik from github, we would appreciate it if you could test this code on J! 3.8 for us. Once we have some feedback, we'll build a 3.8 release.

List JavaScript

Aug 22, 2017
List JavaScript
  • Like custom form Javascript, Fabrik list publish several events that you can subscribe to:

    • list.filter
    • fabrik.list.loaded (list)
    • fabrik.list.submit.ajax.complete (list, json)
    • fabrik.list.submit (task, list state(Object))
    • fabrik.list.navigate (list, limitStart)
    • fabrik.list.order (list, orderBy, orderDir)
    • fabrik.list.update (list, data) - Fired when the list is updated via ajax
    • fabrik.list.limit Fired when the # of records to show is changed
    • fabrik.list.row.edit.close (listRef, rowid, formRef) - Fired when a list ajax edit window is closed (since 3.1rc1)
    • fabrik.list.row.view.close (listRef, rowid, formRef) - Fired when a list ajax view details window is closed (since 3.1rc1)
    This example shows how to access the rowid (PK value) for each row when the list is loaded:

    Code (Javascript):

    requirejs(['fab/fabrik'], function() {
        Fabrik.addEvent('fabrik.list.loaded', function(list) {
            var data = list.options.data;
            // data is an array of groups, each group is an object of rows, each row has a data object, each data object has a  __pk_val item which will have the row id
            data.each(function (group) {
                group.each(function (row) {
                    // do whatever you need with row.data.__pk_val
    This example will create an alert message when the list is reordered:
    Code (Javascript):

    requirejs(['fab/fabrik'], function () {
      Fabrik.addEvent('fabrik.list.order', function(list, orderBy, orderDir){
        alert('aha! list' + list.id + ' was ordered ' + orderBy + ' ' + orderDir);
    This will update the list's data when the edit record ajax window is closed:
    Code (Javascript):

    requirejs(['fab/fabrik'], function () {

      // An edit window has been closed
      Fabrik.addEvent('fabrik.list.row.edit.close', function (listRef, rowid, k) {

          // Update the lists data
    This example is intended for use in fabrik 3.x using the default bootstrap list template. It uses jQuery create a 'sticky' header (and footer) - so that as the page is scrolled the list header and footer remains visible at the top /bottom of the page.

    Code (Javascript):

    * Creates Fixed table headers and footer in a Fabrik list using the default bootstrap template.
    * How to use:
    *    1    Open or create the list_#.js file for the list that contains the table you want to have fixed headers
    *    2    Include a call to setHeaders() at the end of the requirejs(['fab/fabrik'] function (as shown below)
    *    3    Copy the jQuery(window).scroll(function(event) and function setHeaders() code into that js file
    *    ( For a default Joomla protostar template using the default Fabrik bootstrap list template
            you can skip steps 4-7 and just replace all instances of '260' in this code with your List id.)
    *    4    Examine the page html and identify the id used for the form object
    *    5    Replace all instances of "listform_260_com_fabrik_260" with that form id
    *    6    Examine the page html and identify the id for the table object
    *    7    Replace all instances of "list_260_com_fabrik_260" with that table id
    *    8    Take note of any remarks in code beginning with /*** for additional options/settings.
    *    Enjoy your 'fixed header'!
    *    NOTE: It may be necessary to include the setHeaders() call in another fabrik *.js file instead
    *    - i.e. if you are also using a Fabrik list or form module on the same page which might affect when this list is shown.

    requirejs(['fab/fabrik'], function () {

    /* this function checks if passed jQuery object is in viewport of browser */
    jQuery.fn.inView = function(){
        //Window Object
        var win = jQuery(window);
        //Object to Check
        obj = jQuery(this);
        //the top Scroll Position in the page
        var scrollPosition = win.scrollTop();
        //the end of the visible area in the page, starting from the scroll position
        var visibleArea = win.scrollTop() + win.height();
        //the end of the object to check
        var objEndPos = (obj.offset().top + obj.outerHeight());
        return(visibleArea >= objEndPos && scrollPosition <= objEndPos ? true : false)

    /* The scroll event listener */

        /* Get the current table vertical position as page is scrolled */
        window.tableFromTop = window.thisTable.getBoundingClientRect().top + window.pageYOffset;

        /* Get the scroll position of entire document */
        var tgBodyTop = jQuery(window).scrollTop();

        /* detach/attach table header */
        if(tgBodyTop > window.tableFromTop) {
            if(jQuery("#listform_260_com_fabrik_260 div.fabrikDataContainer table.temptable").length==0){
                var temphead = jQuery("table#list_260_com_fabrik_260 thead").clone();

                /* Create fixed header */
                var tableclasses = document.getElementById("list_260_com_fabrik_260").className;
                /* The z-index may have to be set higher if the fixed header is not 'on top' */
                jQuery("#listform_260_com_fabrik_260 div.fabrikDataContainer").prepend('<table class="'+tableclasses+' temptable" style="width:'+window.tablewidth+'px;z-index:1"><thead>'+jQuery(temphead).html()+'</thead></table>');

                /* Note: Set the "top:" fixed position for table header in function setHeaders() */
            if(jQuery("#listform_260_com_fabrik_260 div.fabrikDataContainer table.temptable").length){
                jQuery("#listform_260_com_fabrik_260 div.fabrikDataContainer table.temptable").remove();

        /*** Remove this section to not process detach/attach table footer ***/
        if(jQuery("#bottdiv").inView() == true  || tgBodyTop+window.viewHeight < window.tableFromTop+window.theadHeight+window.tfootHeight+1) {
            /* Un-dock footer if table is outside viewport or normal footer would already be in viewport */
            /* Dock the footer if table is in viewport and normal footer is outside of viewport */
            if(tgBodyTop+window.viewHeight-window.theadHeight-window.tfootHeight > window.tableFromTop) {
                jQuery("#list_260_com_fabrik_260 tfoot").addClass("docked");
                /* May need to increase z-index value if any list elements overlay footer when scrolled */


    /* Reset the fixed headers if window gets resized */
    jQuery( window ).resize(function() {

    /* main function call for fixed headers/footer -
       call this function as the last line in the requirejs(['fab/fabrik'], function () */

    function setHeaders() {
        /*** Set window.fixedMenuHeight to the height of fixed page header/menu - 0 if none) ***/
        window.fixedMenuHeight = 34;

        /* clear settings if any are set */
        jQuery("#list_260_com_fabrik_260 tfoot").removeClass("docked");
        jQuery("#listform_260_com_fabrik_260 div.fabrikDataContainer table.temptable").remove();

        /* initialize window variables */
        window.thisTable = document.getElementById("list_260_com_fabrik_260");
        window.tableFromTop = window.thisTable.getBoundingClientRect().top + window.pageYOffset;
        window.theadHeight = document.getElementById("list_260_com_fabrik_260").getElementsByTagName('thead')[0].clientHeight;
        window.tfootHeight = document.getElementById("list_260_com_fabrik_260").getElementsByTagName('tfoot')[0].clientHeight;
        window.viewHeight = jQuery(window).height();

        /* Create an empty div to identify the bottom of the table view, where the footer would normally be */
        jQuery(jQuery("<div>",{id:"bottdiv"})).appendTo("#listform_260_com_fabrik_260 div.fabrikDataContainer");

        /* initializes vars for css styling of each table header (th) - width, padding */
        window.tablewidth = document.getElementById("list_260_com_fabrik_260").clientWidth;
        var xwidth,xpad;
        // sets width and padding of each column as css style so cloned header will have it
        jQuery("table#list_260_com_fabrik_260 thead tr th").each(function (){
            xwidth = jQuery(this).width();
            xpad = jQuery(this).css('padding');

        /*** Note each remark for scrollTop options. ***/
        /* This topPos value would scroll to the top of the list form */
        // var topPos = document.getElementById("listform_260_com_fabrik_260").getBoundingClientRect().top + window.pageYOffset - window.fixedMenuHeight ;
        /* This topPos value would scroll to the top of the table */
        // var topPos = document.getElementById("list_260_com_fabrik_260").getBoundingClientRect().top + window.pageYOffset - window.fixedMenuHeight ;
        /* If you have included a page class in the menu this would scroll to the top of the page (replace "onlinesurvey" with your page class name) */
        var topPos = document.getElementsByClassName("onlinesurvey")[0].getBoundingClientRect().top + window.pageYOffset - window.fixedMenuHeight;
        /*** Remark out the next line or remove this section if you don't want to scroll to the list/table/page on page load ***/
        jQuery("html, body").animate({ scrollTop: topPos });