lundi 21 décembre 2015

Hiding/Displaying columns using jQuery, checkboxes, and local storage

I have a page where a user submits a query using MVC, and the user can select the columns that are shown using checkboxes. After the user selects the query parameters and columns to view, the user is then sent to another page where a roster of individuals are shown. Checkbox data is stored using local storage, and used on the roster page where there are also checkboxes that the user can use to hide or display columns. I have a working version, but the code looks awful and I think there is a better way to do this with less lines of code.

Here are the checkboxes used on the query page:

<div id="grpChkBox">
  <input type="checkbox" class="columnSelect" name="fullName" /> Full Name
  <input type="checkbox" class="columnSelect" name="type" /> Type
  <input type="checkbox" class="columnSelect" name="ID" /> ID Number
</div>

Here is the script used to select columns and set values in local storage:

<script type ="text/javascript">
//Default is that all columns are selected
    $("#grpChkBox input:checkbox").attr("checked", "checked");
    localStorage.setItem("fullName", 1);
    localStorage.setItem("type", 1);
    localStorage.setItem("ID", 1);

  $(function () {
      if (localStorage.getItem("fullName") !== null) {
          $("input[name='fullName']").attr("checked", "checked");
      }
  });
  $("input[name='fullName']").click(function () {
        if ($(this).is(":checked")) {localStorage.setItem("fullName", 1);}
        else {localStorage.removeItem("fullName");}
  });

  $(function () {
      if (localStorage.getItem("type") !== null) {$("input[name='type']").attr("checked", "checked");}
  });
  $("input[name='type']").click(function () {
      if ($(this).is(":checked")) { localStorage.setItem("type", 1); }
      else {localStorage.removeItem("type"); }
  });

  $(function () {
      if (localStorage.getItem("ID")== null) { $("input[name='ID']").attr("checked", "checked"); }
  });
  $("input[name='ID']").click(function () {
      if ($(this).is(":checked")) { localStorage.setItem("ID", 1); }
      else { localStorage.removeItem("ID"); }
  });            

As you can see, I am creating a function for each checkbox and corresponding column, and there should be a way that I can enumerate columns/checkbox to do this with less lines of code. Just not sure how.

This is the HTML for the roster that is generated on the next page:

<table class="MainContent" style="width: 100%;" id="rosterTable">
<tr>
  <th class="fullName" title="Full Name">Name</a></th>
  <th class="type" title="Type">Type</a></th>
  <th class="ID" title="ID Number">ID Number</a></th>
</tr>
<tr>
  <td>Name 1</td>
  <td>Type 1</td>
  <td>ID Number 1</td>
</tr>
<tr>
  <td>Name 2</td>
  <td>Type 2</td>
  <td>ID Number 2</td>
</tr>
</table>

It also has the same checkboxes as the previous page:

<div id="grpChkBox">
  <input type="checkbox" class="columnSelect" name="fullName" /> Full Name
  <input type="checkbox" class="columnSelect" name="type" /> Type
  <input type="checkbox" class="columnSelect" name="ID" /> ID Number
</div>

And here's the script that reads local storage, and hides/displays columns after the roster is generated:

<script type="text/javascript">
// Reads local storage and check or unchecks, hides/displays
$(document).ready(function () {
    if (localStorage.getItem("fullName") !== null) {
        $("input[name='fullName']").attr("checked", "checked");
    }
    else {
        var index = $("#rosterTable th").filter(".fullName").index();
        $("#rosterTable").find('tr :nth-child(' + (index + 1) + ')').hide();
    }

    if (localStorage.getItem("type") !== null) {
        $("input[name='type']").attr("checked", "checked");
    }
    else {
        var index = $("#rosterTable th").filter(".type").index();
        $("#rosterTable").find('tr :nth-child(' + (index + 1) + ')').hide();
    }

    if (localStorage.getItem("ID") !== null) { $("input[name='ID']").attr("checked", "checked"); }
    else {
        var index = $("#rosterTable th").filter(".ID").index();
        $("#rosterTable").find('tr :nth-child(' + (index + 1) + ')').hide();
    }

//After roster is generated users can hide display columns
$(function () {
    var $chk = $("#grpChkBox input:checkbox");
    var $tbl = $("#rosterTable");
    var $tblhead = $("#rosterTable th");

    //$chk.prop("checked", true);


    $chk.click(function () {
        var colToHide = $tblhead.filter("." + $(this).attr("name"));
        var index = $(colToHide).index();
        $tbl.find('tr :nth-child(' + (index + 1) + ')').toggle();
    });
});
</script>

Once again, this should be done with less lines of code than using a case for each column and checkbox. I need to deploy this solution to multiple pages with different columns, so I would like to do this with more dynamic code. I'm pretty sure this could be done with less lines of code.

All help is appreciated




Aucun commentaire:

Enregistrer un commentaire