Search code examples
javascriptruby-on-railsrubydatatables

Adding a filter to a table - ruby on rails (Javascript)


Here I'm trying to add a filter for the "organisation" column. This uses datatables library to handle the tables The profiles.js file pass neccessary inputs to the _status_table.erb file .

in profiles.js file I added these extra lines ,

document.addEventListener("DOMContentLoaded", function() {
 //existing code 
  if (!document.querySelector(".profiles.index, .users.admin_edit")) return;

  initDataTable({ tableId: "#profilesTable", orderVal: 1, targetsVal: [0, 4] });
  processCoderIdUpdate();

  $(".menu .item").tab();

  
  initDataTable({
    tableId: "#profilesStatusTable",
    orderVal: 1,
    sortingDirection: "asc",
    targetsVal: [0, 7]
  });

  // I added this below custom event listner for get the value from other file 


    $("#organizationFilterDropdown").dropdown();

  // Attach the change event listener
  $("#organizationFilterDropdown").on("change", function() {
    var selectedOrganizationId = $(this).dropdown("get value");

    // Get the table instance
    var profilesStatusTable = $("#profilesStatusTable").DataTable();

    // Clear any existing filters
    profilesStatusTable.columns().search("").draw();

    // Apply the filter to the "Organisation" column
    profilesStatusTable
      .columns(5)
      .search(selectedOrganizationId, false, false)
      .draw();
  });

and in the _status_table.html.erb I added this dropdown section

<div class="ui fluid labeled search selection dropdown" id="organizationFilterDropdown" data-selected-organization="<%= @selected_organization %>">
  <input type="hidden" id="organizationFilterInput">
  <i class="dropdown icon"></i>
  <div class="default text">Filter by Organization</div>
  <div class="menu">
    <% @organizations.each do |organization| %>
      <div class="item" data-value="<%= organization.id %>"><%= organization.name_or_code %></div>
    <% end %>
  </div>
</div>

Here's the rest of the _status_table.html.erb

<table id="profilesStatusTable" class="ui celled table">  
  <%= render partial: 'profiles/table_actions' %>
  <thead>
    <tr>
      <th>
        <div class="ui checkbox">
          <%= check_box_tag 'select_all', 1, false, class: "select-all", onclick: "toggleAll(this)" %>
          <label></label>
        </div>
      </th>
      <th>Full Name</th>
      <th>Role</th>
      <th>Email</th>
      <th>Confirmed</th>
      <th>Organisation</th>
      <th>Coder ID</th>
      <th>Created at</th>
      <th>Last Updated</th>
      <th>Last Login at</th>
      <th>Login Count</th>
      <th>Actions</th>
    </tr>
  </thead>
  <tbody>
    <% @profiles.each do |profile| %>
      <tr class="<%= cycle('row', 'alt-row') %>">
        <td><%= check_box_tag 'delete[]', profile.user.id %><label></label></td>
        <td><%= profile.user.full_name %></td>
        <td><%= role_as_string(profile.role_key) %></td>
        <td><%= profile.user.email %></td>
        <td>
          <span class="ui <%= profile.user.confirmed ? 'teal' : 'red'%> empty circular label"></span>
        </td>
        <td><%= profile.organisation.name_or_code %></td>
        <td><%= profile.coder_id.present? ? profile.coder_id : 'N/A' %></td>
        <td><%= localise_and_pretty_print(profile.user.created_at) %></td>
        <td><%= localise_and_pretty_print(profile.user.updated_at) %></td>
        <td><%= localise_and_pretty_print(profile.user.last_login_at) %></td>
        <td><%= profile.user.login_count %></td>
        <td>
          <%= link_to admin_edit_user_path(profile.user), class: "icon-action", title: "Edit" do %>
            <i class="edit icon"></i>
          <% end %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

The issue is when I select a value from dropdown it shows empty table, I did enter console.log("selectedOrganizationId"); inside onchange() function and it prints the correct value.

I was referring to this section and implemented above code, please help me if you can


Solution

  • profilesStatusTable has no reference so if you were actually getting to this action it would raise TypeError: profilesStatusTable.column is not a function.

    Since you are saying there are no errors it is possible that this guard clause if (!document.querySelector(".profiles.index, .users.admin_edit")) return; is hiding them from you, as I cannot reproduce your issue. Example.

    document.addEventListener("DOMContentLoaded", function() {
     profilesStatusTable = new DataTable("#profilesStatusTable",{
        tableId: "#profilesStatusTable",
        orderVal: 1,
        sortingDirection: "asc",
        targetsVal: [0, 7]
      });
     $("#organizationFilterDropdown").dropdown(
        {onChange: function() {
            var selectedOrganizationId = $(this).dropdown("get value");
            // Apply the filter to the "Organisation" column
            profilesStatusTable.column(5).search(selectedOrganizationId).draw();
        }})
    });
    

    Note:

    • Since initDataTable is also not a function defined anywhere I used the standard syntax for DataTables.
    • I chose to pass the onChange function to dropdown because it IMO it looks cleaner and contains the associated logic better; however, your implementation would work exactly the same.

    UPDATE Along with the above issues I later noted that the OP is trying to use orginazation.id as a search parameter but is searching against the profile.organisation.name_or_code so the extended solution was also to change

    <div class="item" data-value="<%= organization.id %>">
    

    to

    <div class="item" data-value="<%= organization.name_or_code %>">