Add Real jQuery Tabs for each table

Hi,

 

I had posted before but didn't get it working when loaded via Knack's AJAX, worked fine with a page load.

 

And it was covering multiple jQuery/Bootstrap Mods so now split for just jQuery Tabs and working correctly which ever way the page loads and I will add the other things Individually too:

 

So basically add the below to your custom JS:

 

$('<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css" media="screen" /><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css" media="screen" />').insertBefore('#knack-dist_1');


var fwg_js_files = ['https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js', 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js', 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'];
LazyLoad.js(fwg_js_files, function () {

 

$(document).on( 'knack-scene-render.any', function(event, view, records) {
var tableLoops = 0;

$('.kn-table').each (function (index, element) {
var tableCount = $('.kn-table').length;
var recordCountTexts = $(this).find(".kn-entries-summary").text();
var recordCountTextsSplit = recordCountTexts.split("of");
var recordCountTotalText = recordCountTextsSplit[1];
var recordCountTotal = $.trim(recordCountTotalText);
tableLoops++;
if (tableCount > 1) {
var iconClassName = $(this).find('.kn-table-table > tbody > tr:first > td:first').find('i').attr('class');
var childID = $(this).attr("id");
var childName = $(this).find('.view-header > h2').text();
if ($("#tabs").length === 0) {
$('.kn-table').first().before('<div id="tabs"><ul>');
}
var parentID = $(this).parent().attr('id');
if (parentID === 'tabcontent-' + childID) {
} else {
$('#kn-' + view.key).find('#tabs > ul').append('<li><a href="#tabcontent-' + childID + '"><i class="'+ iconClassName +'" style="margin-right: 0.4em"></i>' + childName + ' (' + recordCountTotal + ')' + '</a></li>');
$('#kn-' + view.key).find('#tabs').append('<div id="tabcontent-' + childID + '">');
$(this).appendTo('#tabcontent-' + childID + '');

}
if (tableLoops === tableCount) {
jQuery( "#tabs" ).tabs();
tableLoops = 0;
}
}
});

});


});

 

 

 

 

And then add the below to your custom CSS:

#tabs {
margin: 3px;
border: none !important;
}

.ui-tabs-panel {
border: 1px solid #aaa !important;
}

.ui-widget-header {
border: none !important;
background: none !important;
}

.kn-content #kn-app-menu li.active a {
background: #fff !important;
color: #000 !important;
}

ul.ui-tabs-nav li, ul.ui-tabs-nav li a {
background: #074376 !important;
color: #fff !important;
}

ul.ui-tabs-nav li:hover, ul.ui-tabs-nav li a:hover {
background: #2D6CA2 !important;
color: #fff !important;
}

ul.ui-tabs-nav li.ui-state-active, ul.ui-tabs-nav li.ui-state-active a {
background: #fff !important;
color: #000 !important;
outline: none !important;
}

ul.ui-tabs-nav li.ui-state-active:hover, ul.ui-tabs-nav li.ui-state-active a:hover {
background: #fff !important;
color: #000 !important;
outline: none !important;
}

.ui-tabs .ui-tabs-nav {
padding: 0 !important;
}

 

 

It will work on any scene when there is more than one table, so if you want it to work everywhere there is more than one table then just copy and paste without modifying.

You can of course add a scene to the 'knack-scene-render.any" part above in place of the ".any" and then duplicate for the scenes you want to use it on only.

It also uses an icon from the first column of each of the tables in each tab as the icon on the tab shown just before the text, I will add a request for Knack to add an Icon option to the table setup page under options so you could use that in future with an update on the code.

It also shows the number of records in the tab after the text which is the total record not just the ones currently showing based on paging, again this can be modified easily.

 

 

 

 

Thanks

 

Dan

Just tried this out, and it works great!  Is there anyway to hide the title of the table below the tab without losing it on the tab itself?

Minor tweak to get the right number of total records:

var recordCountTotal = Knack.models[$(this).attr('id')].data.total_records

Awesome, thanks for your work on this Brad and Daniel. Looking forward to adding this in. Appreciated 👍

Started tooling with this for a project and got it working again.  Needed some updates to reflect the newer Knack selectors for tables, and grabbed the recordCountTotal directly from each Knack.model data instead (sometimes tables don't display the summary).  Haven't tested with icons in the tables yet, but the same CSS still works.

Big thanks to 8968668048 for sharing this a few years ago.

$('<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css" media="screen" /><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css" media="screen" />').insertBefore('#knack-dist_1');

var fwg_js_files = ['https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js', 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js', 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'];

LazyLoad.js(fwg_js_files, function () {
    $(document).on( 'knack-scene-render.any', function(event, view, records) {
        var tableLoops = 0;
        $('.kn-table.kn-view').each (function (index, element) {

            var tableCount = $('.kn-table.kn-view').length;
            var recordCountTotal = Knack.models[$(this).attr('id')].data.total_records
            tableLoops++;

            if (tableCount > 1) {
                var iconClassName = $(this).find('.kn-table-table > tbody > tr:first > td:first').find('i').attr('class');
                var childID = $(this).attr("id");
                var childName = $(this).find('.view-header > h2').text();
                if ($("#tabs").length === 0) {
                    $('.kn-table').first().before('<div id="tabs"><ul>');
                }
                var parentID = $(this).parent().attr('id');
                if (parentID === 'tabcontent-' + childID) {
                } else {
                    $('#kn-' + view.key).find('#tabs > ul').append('<li><a href="#tabcontent-' + childID + '"><i class="'+ iconClassName +'" style="margin-right: 0.4em"></i>' + childName + ' (' + recordCountTotal + ')' + '</a></li>');
                    $('#kn-' + view.key).find('#tabs').append('<div id="tabcontent-' + childID + '">');
                    $(this).appendTo('#tabcontent-' + childID + '');
                }
                if (tableLoops === tableCount) {
                    jQuery( "#tabs" ).tabs();
                    tableLoops = 0;
                }
            }
        });
    });
});

This thread stopped about a year ago, thats a shame. Has anyone developed this further?

@DanielYoung this is awesome, great work. Clearly a master of jQuery/JS

Works well, except for some reason that I can't figure. the var recordCountTotal isn't rendering any records.

Any ideas?

Thanks in advance.

Any updates on this?

Very interested in this. Has it progressed any further?

First, thank you Dan for sharing this code!

 

Now, if anyone is struggling to get this to work on embedded knack pages, here is what finally worked for me. :)

At the end of the first line of Javascript code, make sure you update insertBefore('#knack-dist_1') to match the embedded div ID of your particular page. If you're unsure what the div ID is, check the 'Embed Code' snippet that you copy & paste:

For example, my div ID above is knack-dist_3, so my first line of Javascript code now reads:

$('<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css" media="screen" /><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css" media="screen" />').insertBefore('#knack-dist_3');

 

Cheers!

This would be an AMAZING feature that should be built into Knack itself! I've been looking for a way to do this for over a year.

I tried to use this code with the Beta theme and it creates an extra tab for the table itself as shown below. Does anyone know how to adjust this code to include the table under the initial tab?

 This is a great share.  I'm having an issue that I can't figure out with this.  If my record count is less than 10, then the count is not showing up on the tab.  Can anyone help resolve this?

Found the solution of my problem. Instead of jQuery( "#tabs" ).tabs(); in the above code add the below jquery cookie. This simple stores the last active tab as a cookie and when you go back direct you to the last tab you were on. 

jQuery( "#tabs" ).tabs({
active : $.cookie('activetab'),
activate : function( event, ui ){
$.cookie( 'activetab', ui.newTab.index(),{
expires : 10
});
}
});
}
}) 

Hi

Thank you for the wonderful share. I have just one problem and so far unable to fix. 

If you have multiple tabs on one page and user post something or click back. The page starts with 1st tab not the last tab user was at. This could be annoying for users as they expect to go back on last active tab.

Can Anyone point me in the right direction to somehow log the last active tab url in browser memory and when user post something or click back button, it loads the last active tab instead of the first tab.

Thanks 

Thanks Dan!

Hi Marc,

 

I have been waiting for the new Theme to come out of Beta and become stable which I thought would be a few weeks but I guess with holidays it explains why it has been months, once stable I will redo using Bootstrap classes direct.

 

Thanks

 

Dan

Hi Daniel,

Thanks for sharing this great script.

It works like a charm with the 'old' theme designs, but I'm unable to get work with the new beta theme.

Any thought on how the fix this problem?

Thanks,

 

Marc

Hi Brad,

 

Pics added to the main post, just got to solve one issue which is when you add a new record via the modal it updates the "Showing x of y" but I cannot find a call to hook in to so I can update the total in the tab.......

 

Thanks

 

Dan

Fantastic, thanks for sharing Dan.

Got any screenshots you could share here?

Thanks

Brad

Thought I’d resurrect this one - as the code doesn’t seem to be working for me… anyone manage to get this to work recently? Thanks!