Hide/Show Angular via URL Variables


flickr photo shared by Internet Archive Book Images with no copyright restriction (Flickr Commons)

For some reason I’ve been hiding/showing things a lot recently.

One nice little trick I saw (and have already used) was based on the target class. You can see it working – hidden here and expanded here. Notice the #details piece in the URL. The CSS that makes it work is below. Nice and simple.

#details:not(:target) {
  display: none;
}
#details:target {
    display: block;
}	

That’s nice if it’s one element you can address via an id. It doesn’t work if you want to hide and show multiple items which might have the same id.

I wandered around a bit and found a more interesting way to do it in Angular. The following javascript gets the variable from the URL. It’s straight from this article.

So this URL http://bionicteaching.com/tools/hcps/hcps-tools.html?school=varina_hs would pass varina_hs to the variable school. If the school=varina_hs chunk is gone, then the box is invisible.

var school = getQueryVariable("school");
            console.log(school);

            function getQueryVariable(variable)
                {
                       var query = window.location.search.substring(1);
                       var vars = query.split("&");
                       for (var i=0;i<vars.length;i++) {
                               var pair = vars[i].split("=");
                               if(pair[0] == variable){return pair[1];}
                       }
                       return(false);
                }

I need to add that variable to the Angular scope so it can be accessed in the template.

 $scope.school = getQueryVariable("school");

So now that we have that we can use it. Wandering around a bit I found ng-if. It’s essentially a way to show or hide and element based on whether the statement returns true.

ng-if="entry.gsx$school.$t.indexOf(school) >-1 || entry.gsx$school.$t == 'all'

This code will return TRUE under either of two conditions. If the JSON element entry.gsx$school.$t has the variable returned from the school url in it then the element will show. The indexOf let’s us search across what might be several variables. Since it returns -1 if there’s no match, then anything 0 or above indicates the content was found. It will also show if that JSON element is exactly the word all.

Now this content is fed via a Google Sheet/Form combination. When you check multiple items in a Google form it strings them together like school A, school B, school C. The commas and spaces made my life harder but I felt like keeping the form clean so I figured I’d sanitize things with a Google Script (rather than doing it in Angular). This script will remove the commas and join the school and the level with an underscore. If not school was chosen it’ll set the cell content to ‘all.’

function cleanSchools() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = SpreadsheetApp.setActiveSheet(ss.getSheets()[0]);
  var lastRow = sheet.getLastRow();
  var schoolColumn = 11;
  var schoolsCell = sheet.getRange(lastRow, schoolColumn);
  var schools = schoolsCell.getValue();
  if (schools!=='string')
  { 
    schoolsCell.setValue('all');
  }
  else{
  schools = schools.replace(/(\s\b)/g, '_');//replace spaces
  schools = schools.replace(/,_/g,' '); //replace comma underscore combos
  schools = schools.toLowerCase();
  schoolsCell.setValue(schools);
  }
}