Using hrefs to filter DataTables data

Using hrefs to filter DataTables data

TsardinesTsardines Posts: 10Questions: 4Answers: 0

I have a categories list and a documents table and both are populated with local JSON data. Each category item corresponds to a document (some documents have multiple categories), and I want to make it so that clicking on a category will filter its documents in the table. For now the categories are href'd but don't do anything.

Since the documents are housed in a DataTable and rendering the categories did not use DataTables, I'm not sure how I would proceed with getting both to work with one another.

I've included a JS snippet below. I haven't been able to get the table to display with JS Fiddle properly, so if you'd like to see the HTML then let me know.

JS snippet:

import $ from 'jquery';

    import JSONfile from '../../../public/JSONfile.json';
    import { basename } from 'path';

    import dt from 'datatables.net';

    var categories = '';
    var tableRes = '';

        export default class {
            constructor() {
                this.loadData();
                this.loadTableData();
            }

Loading the categories:

          loadData() {        
            let res = JSONfile.d.results.filter(function(val) {
              return (val.FileLeafRef.trim().length > 0);
            }).map(function(obj) {
                return {
                  "FileName": obj.FileLeafRef,
                  "Path": obj.EncodedAbsUrl,
                  "Categories": obj.ResourceType.results.map(function(val) {
                      return val.Label;
                  }).join(";")
                };
            });

            JSONfile.d.results.filter(function(val) {
              return (val.FileLeafRef.trim().length > 0);
            }).map(function(obj) {          
              return obj.ResourceType.results.map(function(val) {
                return val.Label;
              })
            });

Showing each Category once:

            let unique = {};
              let temp = JSONfile.d.results.filter(function(val) {
                return (val.FileLeafRef.trim().length > 0);
              }).forEach(function(obj) {
                obj.ResourceType.results.forEach(function(val) {
                  unique[val.Label] = true;
                })
              });    

              let categories = Object.keys(unique).sort();

Turning Categories into hrefs and adds them to .indiv-label

              $(".indiv-label").html(categories.join("<br>"))
                .contents().each(function() {
                  if (this.nodeType == 3) {
                    let elem = $("<a>", {
                      href: "#" + this.nodeValue ///// ---------------------- Not sure what url to put where the # is
                    });
                    $(this).wrap(elem)
                  }
                });



       } // ------------- loadData()

Loading the table

      loadTableData() {
        $.noConflict();
        let tableRes = JSONfile.d.results.filter(function(val) { 
          return (val.FileLeafRef.trim().length > 0);
        }).map(function(obj) {
          return {
            "Path": obj.EncodedAbsUrl,
            "Titles": obj.File.Name,
            "Categories": obj.ResourceType.results.map(function(val) {
              return val.Label;
            }).join(";"),
            "Blank": ''
            }
          });



        $('#km-table-id').DataTable( {
          columns: [
            { data: "Titles" },
            { data: "Categories" } // hidden col-3 categories
          ],
          columnDefs: [
            {
              data: "Path",
              render: function(data, type, row) {
                return $('<a>')
                  .attr({target: "_blank", href: row.Path})
                  .text(data)
                  .wrap('<div></div>')
                  .parent()
                  .html();
              },
              targets: 0
            },
            { searchable: true, targets: [1], visible: false },
          ],
          data: tableRes,
          language: { searchPlaceholder: "Search All Documents" },
          lengthMenu: [ 10, 25, 50, 100, 250, 500 ],
          order: [],
          // pageLength: 500,
          paging: true,
          pagingType: "full_numbers",
          responsive: true,
            scrollCollapse: true,
            scrollX: true,
            scrollY: 450,
              stateSave: true

        });




      } // ------------------ loadTableData

    } // ------------- export default class

Answers

  • kthorngrenkthorngren Posts: 20,269Questions: 26Answers: 4,765

    Thats a lot of code to look through. An example would be good. However it sounds like you are trying to implement a select input search, correct?

    If so then this example may help you get started.
    https://datatables.net/examples/api/multi_filter_select.html

    This example is placing the select inputs in the footer. But you can place the categories input anywhere you want. The basic code will show you how to build the select list and how to execute the search when an option is selected.

    Kevin

  • TsardinesTsardines Posts: 10Questions: 4Answers: 0
    edited January 2019

    Hi @kthorngren ,

    I have a list that's made up of JSON data---I want it so that someone clicks on a list item and the DataTable is updated to only show the documents that correspond with each list item.

    For example, if I click on the list item "Fruit" the table will update to show "Apples, Bananas, Kiwis" and it will hide "Yellow Rollerskates." But if I click on "Yellow Objects" the table will show "Bananas, Yellow Rollerskates." In other words some documents are listed under multiple categories.

    Based on what you're saying and the link you provided, do you think it would it be possible to convert the Select/Drop Down into a regular list (that's still populated by my JSON data), which can then be clicked on to filter the data? Thanks!

  • kthorngrenkthorngren Posts: 20,269Questions: 26Answers: 4,765
    edited January 2019

    I want it so that someone clicks on a list item

    How do you want to present this list? Select (maybe select multiple), checkboxes, etc.

    In other words some documents are listed under multiple categories.

    What does this data structure look like in your Datatable?

    For example:

    | Bananas | [Yellow, Fruit] |
    

    or:

    | Bananas | Fruit  |
    | Bananas | Yellow |
    

    Or something different?

    You should be able to create a custom search function or maybe a Search Plugin to perform the search you want. These examples aren't exactly what you want but maybe they are enough to get you going.

    They are the same search using checkboxes except one uses a function and the other is a search plugin:

    Function:
    http://live.datatables.net/vipifute/1/edit

    Plugin:
    http://live.datatables.net/rosahuka/1/edit

    To create an example for us to help you with just use your fruit and color example. The example doesn't need all the complexity of your above code. It just needs to represent the data structures you have.

    Kevin

  • TsardinesTsardines Posts: 10Questions: 4Answers: 0
    edited January 2019

    Quick update: I looked at your link showing the checkboxes example, and it could work.

    Hi Kevin,

    The list is just an ordered list of items with each one acting as a link.

    I've included a snippet of the JSON data below. Every Document/Name can have multiple Categories/Labels.

    I've been able to render the Labels as a list into one div and the Names into a DataTable.

            {
              "d": {
                "results": [
                  {
                    "__metadata": { ...
                   },
                    "File": {
                      "__metadata": { ...
                      },
                      "Name": "Guide to Product IDs.docx" // -------------------- Doc title
                    },
                    "ResourceType": {
                      "__metadata": {
                        "type": "..."
                      },
                      "results": [
                        {
                          "Label": "Guides \uff06 Protocols", // --------------------- Category
                          "TermGuid": "..."
                        }
                      ]
                    },
                    "EncodedAbsUrl": "..."
                  },
                  {
                    "__metadata": { ...
                    },
                    "File": {
                      "__metadata": { ...
                      },
                      "Name": "Template 1.docx" // -------------------- Doc title
                    },
                "ResourceType": {
                  "__metadata": { ...
                  },
                  "results": [
                    {
                      "Label": "Templates" // --------------------- Category
                    },
                    {
                      "Label": "Guides \uff06 Protocols" // --------------------- Category
                    }
    ...
    ...
    ...
    
This discussion has been closed.