1

Clearing filters on loading a table

I use this snippet to clear the filters for a table (all).  It is under a button.

ui.openTableOld?null:ui.openTableOld=ui.openTable;
ui.openTable = function(...arg) {
    ui.openTableOld(...arg);
    document.querySelectorAll('#exColumnFilter-close')?.forEach( button => button.click())
}
}#;
openTable("PROJECTS", "ALL")


Is it possible to use it somehow within a view?  For example, in PROJECTS which loads with cleared filters I might have a view of EQUIPMENT used for that project.  It would be handy to be able to load PROJECTS clear of filters as well as any views associated with PROJECTS

19 replies

null
    • Ninox developper
    • Jacques_TUR
    • 2 mths ago
    • Reported - view

    Hello Alan,

    I am currently on vacation without a computer. It’s a bit of a detox cure 😂.

    I think it should be possible. You need to check which function is called when a view is selected (openView?).

    It would also be necessary to ask Ninox to fix the bug where, when reopening a table that previously had a filter, the filter is applied but not visible in the filter input field.

    • Ninox developper
    • Jacques_TUR
    • 1 mth ago
    • Reported - view

    Hi Alan,

    I’m back from vacation and I’ve just looked into what can be done. I found this script that can be executed from a button:

    It removes the filters from the view field named fieldName and refreshes the display. The code needs to be executed when the form is opened.

    #{
        let fieldName = 'List of customers';
        ui.getCurrentEditor().currentTab.components.find( c => c.field.caption == fieldName && c.field.base == "view")?.query.cols?.forEach( cl => cl.filter=null);
        ui.getCurrentEditor().currentTab.nodeChanged();
    }#

      • Alan_Cooke
      • 1 mth ago
      • Reported - view

       That's really handy Jacques.  Hope you had a great vacation!!

      • John_Halls
      • 1 mth ago
      • Reported - view

       One day, when you have a bit of time, could you explain this code to me. Thanks John

      • Ninox developper
      • Jacques_TUR
      • 1 mth ago
      • Reported - view

       

      This JavaScript code is condensed to fit within three lines, making it compact but less readable. Below is a detailed line-by-line explanation to better understand how it works.

      Line 1:

      let fieldName = 'List of customers';
      • fieldName: This variable holds the name of the "view" field for which we want to remove the filters applied to each column. In this example, the field is called "List of customers."

      Line 2:

      ui.getCurrentEditor().currentTab.components.find( c => c.field.caption == fieldName && c.field.base == "view")?.query.cols?.forEach( cl => cl.filter=null);
      • ui.getCurrentEditor().currentTab.components: This part of the code retrieves the list of components displayed (components) in the current tab (currentTab) of the form being edited (getCurrentEditor()).
      • .find( c => c.field.caption == fieldName && c.field.base == "view"): Here, the code searches for the component where the field's name (field.caption) matches fieldName and the field's type (field.base) is "view."
      • ?.query.cols: If the component is found, this part of the code returns the list of columns associated with the field.
      • ?.forEach( cl => cl.filter=null): If a list of columns is present, this method iterates over each column (cl) and removes the applied filter by setting it to null.

      Line 3:

      ui.getCurrentEditor().currentTab.nodeChanged();
      • ui.getCurrentEditor().currentTab.nodeChanged(): This line indicates that the current record has changed, triggering a data reload. This is an indirect way to refresh the list display after removing the filters.

      Important Note:

      This code uses core Ninox functions. However, since Ninox may change the accessibility or organization of these functions at any time, this code may become invalid in the future. It is important to stay vigilant regarding platform updates.

      • John_Halls
      • 1 mth ago
      • Reported - view

       Thanks Jacques, excellent description of how it does its magic.

      • Ninox Developer
      • schwendtner
      • 1 mth ago
      • Reported - view

       is there anything else needed (e.g. Ninext) besides pure JS? If i run ui in the inspector-console i get only the following methods:

      • Ninox developper
      • Jacques_TUR
      • 1 mth ago
      • Reported - view

       Indeed, you need to install Ninext to access the core functions of Ninox

    • Mel_Charles
    • 1 mth ago
    • Reported - view

      Very Cool... You should have more vacations - it clearly inspires you ! 😄

    • Alan_Cooke
    • 1 mth ago
    • Reported - view

    Just tried this out to clear filters - Really is a handy bit of code.  Thanks 

    Here is another idea.  Kind of the above but in reverse.  Would it be possible to have a button with code that applies A-Z or Z-A on a column.  Let's say we have a Date field or Invoice number field.  By clicking a button the Date field (FieldName) sorts the column A to Z and another button for Z to A.

    I realise one can do this in a column directly but a button would be a much 'smoother' approach.

      • Ninox developper
      • Jacques_TUR
      • 1 mth ago
      • Reported - view

       

      To set the column used for sorting a list in a specific tab of the editor, you can use the following code:

      var editor = ui.getCurrentEditor(); var customerList = editor.currentTab.components.find(c => c.field.caption == 'List of customers' && c.field.base == "view"); customerList.query.cidxSort = [column_number]; // The column number starts at 0 for the first column.

      This code retrieves the current editor and finds the list component with the caption "List of customers." Then, it sets the column to be used for sorting by specifying the desired column index.

      To change the sort order of the selected column (ascending or descending), use the following code:

      customerList.query.sortDescending = [true or false]; // 'true' for descending order, 'false' for ascending order.

      This code adjusts the sort order of the specified column. When sortDescending is set to true, the column is sorted in descending order; otherwise, it is sorted in ascending order.

      To simulate a display refresh after modifying the sorting settings, use the following command:

      ui.getCurrentEditor().currentTab.nodeChanged();

      This method forces the interface to refresh, applying the sorting changes and updating the display accordingly.

      • Ninox developper
      • Jacques_TUR
      • 1 mth ago
      • Reported - view

       

      ... but in the end, it will be easier and more powerful to create an HTML list by adding your own sorting and filtering options. Here is an example in HTML: https://piccalil.li/blog/styling-tables-the-modern-css-way

      You can also ask ChatGPT to create the table from scratch by providing it with the structure of your data and the interface you want to have.

      As an example, here is what the GPT Ninox by U Man Genius suggested when I asked it to dynamically create a table to display 3 columns from the Customer table, and to allow ascending and descending sorting by clicking on the column headers:

      let customers := (select Customer);
      let tableHTML := "<table id='customerTable' class='table-ninox'>";
      tableHTML := tableHTML + "<thead><tr>";
      tableHTML := tableHTML +
          "<th id='header-0' data-ascending='true' onclick='toggleSort(0)'>First Name</th>";
      tableHTML := tableHTML +
          "<th id='header-1' data-ascending='true' onclick='toggleSort(1)'>Last Name</th>";
      tableHTML := tableHTML +
          "<th id='header-2' data-ascending='true' onclick='toggleSort(2)'>Total</th>";
      tableHTML := tableHTML + "</tr></thead><tbody>";
      for c in customers do
          let total := sum((select Invoice where Customer = c).TOTAL);
          tableHTML := tableHTML + "<tr>";
          tableHTML := tableHTML + "<td>" + c.'First Name' + "</td>";
          tableHTML := tableHTML + "<td>" + c.'Last Name' + "</td>";
          tableHTML := tableHTML + "<td>" + format(total, "$ #,##0.00") + "</td>";
          tableHTML := tableHTML + "</tr>"
      end;
      tableHTML := tableHTML + "</tbody></table>";
      html("<style>
          .table-ninox { width: 100%; border-collapse: collapse; }
          .table-ninox th, .table-ninox td { border: 1px solid #ddd; padding: 8px; text-align: left; }
          .table-ninox th { cursor: pointer; }
          .table-ninox th:hover { background-color: #f1f1f1; }
          .table-ninox th.sortable::after { content: ' ▲▼'; font-size: 12px; margin-left: 10px; }
          </style>
          <script>
          function sortTable(n, ascending) {
              var table, rows, switching, i, x, y, shouldSwitch;
              table = document.getElementById('customerTable');
              switching = true;
              while (switching) {
                  switching = false;
                  rows = table.rows;
                  for (i = 1; i < (rows.length - 1); i++) {
                      shouldSwitch = false;
                      x = rows[i].getElementsByTagName('TD')[n];
                      y = rows[i + 1].getElementsByTagName('TD')[n];
                      if (ascending ? (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) :
                          (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase())) {
                          shouldSwitch = true;
                          break;
                      }
                  }
                  if (shouldSwitch) {
                      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
                      switching = true;
                  }
              }
          }
      
          function toggleSort(n) {
              var header = document.getElementById('header-' + n);
              var ascending = header.getAttribute('data-ascending') === 'true';
              sortTable(n, !ascending);
              header.setAttribute('data-ascending', !ascending);
              header.innerHTML = header.innerHTML.replace(ascending ? '▲' : '▼', ascending ? '▼' : '▲');
          }
          </script>" +
      tableHTML)

      • Alan_Cooke
      • 1 mth ago
      • Reported - view

      Wow!  Thank you but this is way beyond my skill level.  I would not even know how to ask ChatGPT.

      • Rafael Sanchis
      • Rafael_Sanchis
      • 1 mth ago
      • Reported - view

       

      Hi Jacques, ChatGPT gave you this code?

      how you do that ?

      • Alan_Cooke
      • 1 mth ago
      • Reported - view

       If I knew how to do this, I think I would change all my views :-)

      • Ninox developper
      • Jacques_TUR
      • 1 mth ago
      • Reported - view

       
      I used the ChatGPT named Ninox by U Man Genius, available in the GPT Store.

       

      I asked it the following question:

      "Can you create an HTML field that pulls data from the Customer table and displays the columns 'First Name,' 'Last Name,' and Total? I would like the style to resemble a Ninox table, and I want to be able to sort each column by clicking on an up or down arrow for ascending or descending sorting."

      Since the result didn’t dynamically create a table, I added:

      "Can you make sure that the table is built from the records in the Customer table?"

      Then, I simply copied its response into a formula. Sometimes, you may need to ask it for modifications or adjustments, but most importantly, you can also ask it to explain how it did it and to teach you how to do it yourself. Just tell it things simply; it understands natural language and implicit requests very well.

      • Mel_Charles
      • 1 mth ago
      • Reported - view

       No worries - We don't need to know how to ask ChatGBT - We have our own service it's called "ASKJacques" 🤣  

      • Ninox developper
      • Jacques_TUR
      • 1 mth ago
      • Reported - view

       You mean JackGPT ? 🤪

      • Mel_Charles
      • 1 mth ago
      • Reported - view

       Silly me - of course !!! 😄

Content aside

  • 1 Likes
  • 1 mth agoLast active
  • 19Replies
  • 118Views
  • 7 Following