Hiding columns

In the old kanck builder the code below worked perfectly. Does anyone know why this has chnaged?
 
Thanks
 
Peter
 
//Table Columns
var addTableColumnChoose = function(view) {
// added support for cookies to keep selected columns between renders and sessions
 
var clearFix = $('#'+ view.key +' > div.kn-records-nav.clearfix');
clearFix.append("<div class='clear'><a href='#' class='choose-columns'>Choose columns</a></div>");
var hstring = getCookie("hstring_"+view.key);
if(hstring !=''){
var headers =JSON.parse(hstring);
$.each(headers, function(i, show) {
var cssIndex = i +1;
var tags = $('#'+ view.key +' > table th:nth-child('+ cssIndex +'), #'+ view.key +' > table td:nth-child('+ cssIndex +')');
if(show)
tags.show();
else
tags.hide();
 
});
}
 
 
 
$('#' + view.key + ' .choose-columns').click(function() {
// remove other open columns set dialog on the same page
 
 
if( $('#tableChooseColumns')!=null){$('#tableChooseColumns').remove();}
var headers = $('#'+ view.key +' > table th').map(function(){
var th = $(this);
return{text: th.text(), shown: th.css('display')!='none'};
});
var hs;
h = ['<div id=tableChooseColumns><table><thead><tr><th style="text-align:center;padding:5px;"><button id=done>OK</button></th></tr></thead><tbody><tr>'];
$.each(headers, function() {
h.push('<tr><td style="padding:5px;"><input type=checkbox',
(this.shown ?' checked ':' '),
'/> ',
this.text,
'</td></tr>');
});
h.push('</tr></tbody></table></div>');
hs = h.join('');

 
$('body').append(hs);
var pos = $('#'+ view.key +' .choose-columns').position();
$('#tableChooseColumns').css({'position': 'absolute', 'z-index':'9999','left': '20px', 'top': pos.top,'padding': '5px', 'border': '1px solid #666', 'border-radius':'3px','background': '#fff'});
$('#done').click(function() {
var showHeaders = $('#tableChooseColumns input').map(function(){returnthis.checked;});
var columns =[];
$.each(showHeaders, function(i, show) {
var cssIndex = i +1;
var tags = $('#'+ view.key +' > table th:nth-child('+ cssIndex +'), #'+ view.key +' > table td:nth-child('+ cssIndex +')');
if(show)
tags.show();
else
tags.hide();
columns.push(show);
});
 
$('#tableChooseColumns').remove();
setCookie("hstring_"+view.key,JSON.stringify(columns),100);
returnfalse;
});
returnfalse;
});
}

Kelson,

I tried the code and it partly works and needs some conditions for it to display.

1. The table columns cannot be grouped

2. You cannot have a connect field displayed as it picks up the data rather than the heading of the column

When it does display it as below and clicking on Show/hide does nothing. My old version had cookies to save preferences and worked with groups (as I recall, could be wrong :) ). I sent you an email and happy to discuss giving you access and fee for service.

Pete

Hi Peter, 

That code appears to be pretty old. I went ahead and wrote the functionality using ES6 standards. I also refactored it to be a little bit more legible. Here is a demo: https://projects.knack.com/my-projects#show--hide-table-columns/

Here is the code. Be sure to switch out the 'View_XX' for your view.

I work in Knack building custom plugins nearly full time. Feel free to reach out if you need help
kelson@ksensetech.com
ksensetech.com 

$(document).on("knack-view-render.view_xx", function (event, view, data) {

  showHideTableCols(view.key);

});

function showHideTableCols(viewKey) {

  //Adds the required dom elements to the dom

  const addDomElements = () => {

    //add css

    const customCSS = Knack.$("#kn-custom-css").text();

    const addition = "\n.hidden{display:none !important}";

    Knack.$("#kn-custom-css").text(customCSS + addition);

    //add new dom elems

    Knack.$(`#${viewKey} .view-header`).append(

      '<a id="show_hide_cols">Show / Hide Columns</a>'

    );

    Knack.$(`#${viewKey} .view-header`).append(

      '<div id="hiddenOptions" class="hidden"></div>'

    );

    const checkBoxesHtml = createCheckboxes();

    Knack.$("#hiddenOptions").append(checkBoxesHtml);

  };

  //Returns an array of obj with column lables and fieldIds

  const getColumns = () => {

    const columnBodyElems = Knack.$(

      `#${viewKey} tbody tr:first-child td[class^=field]`

    );

    //get all the fields by class

    const fields = columnBodyElems.toArray().map((col) => {

      const classes = Knack.$(col).attr("class");

      const position = classes.search("field_");

      const field = classes.split(" ")[position].trim();

      //get the headerlabel

      const headerLabel = Knack.$(`.${field}`)

        .find("span a span")

        .text()

        .trim();

      return {

        headerLabel,

        field,

      };

    });

    return fields;

  };

  const localStorageName = `${viewKey}_hiddenCols`;

  const handleLocalStorage = {

    get: () => {

      let currentLs = localStorage.getItem(localStorageName);

      if (!currentLs) {

        localStorage.setItem(localStorageName, JSON.stringify([]));

        return [];

      }

      return JSON.parse(currentLs);

    },

    add: (fieldId) => {

      const currentLs = handleLocalStorage.get();

      if (!currentLs) {

        const newLs = [fieldId];

        localStorage.setItem(localStorageName, JSON.stringify(newLs));

        return;

      }

      const newLs = [...currentLs, fieldId];

      localStorage.setItem(localStorageName, JSON.stringify(newLs));

    },

    remove: (fieldId) => {

      const currentLs = handleLocalStorage.get();

      const newLs = currentLs.filter((field) => {

        return field !== fieldId;

      });

      localStorage.setItem(localStorageName, JSON.stringify(newLs));

    },

  };

  const createCheckboxes = () => {

    const currentStorage = handleLocalStorage.get();

    let allCheckboxesHtml = "";

    getColumns().forEach((column) => {

      let isChecked =

        currentStorage.indexOf(column.field) > -1 ? "" : "checked";

      allCheckboxesHtml += `

              <div>

                  <input type="checkbox" id="toggle_${column.field}" name="${column.headerLabel}" ${isChecked}>

                  <label for="${column.headerLabel}">${column.headerLabel}</label>

              </div>`;

    });

    return allCheckboxesHtml;

  };

  const addEventListeners = () => {

    //checkbox input

    Knack.$("[id^=toggle_field]").on("click", function () {

      const fieldId = Knack.$(this).attr("id").split("toggle_")[1];

      Knack.$(`.${fieldId}`).toggleClass("hidden");

      if (Knack.$(this).is(":checked")) {

        handleLocalStorage.remove(fieldId);

      } else {

        handleLocalStorage.add(fieldId);

      }

    });

    //anchor elem to show/hide checkboxes

    Knack.$("#show_hide_cols").on("click", function () {

      Knack.$("#hiddenOptions").toggleClass("hidden");

    });

  };

  const hideHiddenCols = () => {

    //get local storage

    const hiddenColumns = handleLocalStorage.get();

    if (hiddenColumns) {

      hiddenColumns.forEach((column) => {

        Knack.$(`.${column}`).addClass("hidden");

      });

    }

  };

  addDomElements();

  hideHiddenCols();

  addEventListeners();

}

Hello!

Not sure if it is because of the new builder (or just that I am not that good with code…) but this is not seeming to work for me. I get the list of columns with check marks and can toggle, but it does nothing. I don’t think there is a button to apply the change maybe for me, or I am not doing it right.

Any thoughts?

Robert,

Kelson did a great job and thanks for his time. However, same issue for me and it only shows if the table is in clean mode. I preferred the old knack builder :slight_smile: at least my code worked across all modes. I have tried all sorts of approaches and still no luck.