/* CorrLeader Navigator Scripts by Alan Levine https://cog.dog for web viewing of WordPress content via REST API from https://corrleader.jibc.ca */ $(document).ready(function(){ // --------------- set up --------------- $("#gimme").hide(); // hide the more button /* API urls for resources (posts) and courses (custom post types) json is expected to be local cached from https://corrleader.jibc.ca/wp-json/wp/v2/posts?_embed&per_page=100 https://corrleader.jibc.ca/wp-json/wp/v2/portfolio?_embed&per_page=20 */ const urls = [ 'corrleader_resources.json', 'corrleader_courses.json', ]; // pagination of results, could easily be a form element const loop = 10; // for date formatting const doptions = { year: 'numeric', month: 'long', day: 'numeric' , hour:'numeric', minute:'numeric'}; // create holders for future content let results_posts = []; let results_courses = []; let results_all = []; let listclass = ''; // set or restore checkbox settings setCheckboxes(); // --------------- json fetch --------------- // get json data via promises // via Tom Woodward and https://w.trhou.se/bhriv87fql Promise.all(urls.map(url => fetch(url) .then(checkStatus) .then(parseJSON) .catch(error => console.log('API fetching problem!', error)) )) .then(data => { let counter = 0; // simple toggle flag data.forEach(function(results){ // crude but works to load the data in correct arrays counter++; if ( counter == 1 ) { results_posts = results; } else { results_courses = results; } }) // set the update date display update_freshness(); // load the results update_results(); }) // --------------- json utilities --------------- function checkStatus(response) { if (response.ok) { return Promise.resolve(response); } else { return Promise.reject(new Error(response.statusText)); } } function parseJSON(response) { return response.json(); } // --------------- array sorting magic --------------- // This code is copyright 2012 by Gavin Kistner, !@phrogz.net // It is covered under the license viewable at http://phrogz.net/JS/_ReuseLicense.txt (function(){ if (typeof Object.defineProperty === 'function'){ try{Object.defineProperty(Array.prototype,'sortBy',{value:sb}); }catch(e){} } if (!Array.prototype.sortBy) Array.prototype.sortBy = sb; function sb(f){ for (var i=this.length;i;){ var o = this[--i]; this[i] = [].concat(f.call(o,o,i),o); } this.sort(function(a,b){ for (var i=0,len=a.length;i 0) { // no categories to filter? use all data if ( rtype == 'all' ) { // both kinds of data, combine the results to one array results_all = results_posts.concat(results_courses); // sort by date results_all.sortBy( function(){ return this.date } ); // reverse the order for newest first results_all.reverse(); } else if (rtype == 'resources') { results_all = results_posts; } else { results_all = results_courses; } } else { // filter by selected categories // get checkbox selection categories selcats = get_selected_cats_val(); // reset results results_all = []; // filter the resources if (rtype == 'all' || rtype == 'resources') { results_posts.forEach(function(item) { // check intersection of categories to selected checkboxes intersection = item.categories.filter(x => selcats.includes(x)); if (intersection.length > 0 ) results_all.push(item); }); } // filter the courses if (rtype == 'all' || rtype == 'courses') { results_courses.forEach(function(item) { // check intersection of categories to selected checkboxes intersection = item.portfolio_category.filter(x => selcats.includes(x)); if (intersection.length > 0 ) results_all.push(item); }); } // sort by date results_all.sortBy( function(){ return this.date } ); // reverse the order for newest first results_all.reverse(); // include selected categories in the title results_title += ' (in ' + get_selected_cats_names() + ')'; } // limit check for number of results let results_limit = Math.min( $("#results > li").length + loop, results_all.length); // content for results header let results_header = ''; // build the results let list = ''; if (show_compact()) { // compact, text only display listclass = ''; for (var i = start; i < results_limit; i++) { dt = new Date(Date.parse(results_all[i].date)); list += '
  • ' + results_all[i].title.rendered + ' (' + type_labels[results_all[i].type] + ')
    Published: ' + dt.toLocaleString('en-CA', doptions) + '
    ' + getCategories(results_all[i]._embedded['wp:term'][0]) + '
    Link: ' + results_all[i].link + '' + results_all[i].excerpt.rendered + '
  • '; } } else { // full content plus media display listclass = 'list-unstyled'; for (var i = start; i < results_limit; i++) { dt = new Date(Date.parse(results_all[i].date)); list += '
  • ' + (i+1) + '
    ...

    ' + results_all[i].title.rendered + '

    Published: ' + dt.toLocaleString('en-CA', doptions) + '
    ' + getCategories(results_all[i]._embedded['wp:term'][0]) + '
    Link: ' + results_all[i].link + '

    ' + results_all[i].content.rendered + '
  • '; } } if (start) { // add results to existing list $('#results').append(list); // update count $('.result_header span').text(results_limit); // hide more button if no more to show if (results_limit == results_all.length) $("#gimme").hide(); } else { // add results to new list $('#newest').html( results_header + '
      ' + list + '
    ' + results_header ); // check if we should show the more button if (results_limit < results_all.length) { $("#gimme").show(); } else { $("#gimme").hide(); } } // extra CSS for the rich display, classes to make embeds responsive // this hinges on class names used in the theme's output if (!show_compact()) { $(".wpex-roembed").addClass("embed-responsive embed-responsive-16by9"); $(".wpex-oembed-wrap").addClass("embed-responsive embed-responsive-16by9"); $("iframe").addClass("embed-responsive-item"); } } // generate results heading function results_str( num, total, str ) { return ('Showing ' + num + ' out of ' + total + ' ' + str); } // check both feeds for the newest item, use the newest date as a representation // of the most recent content function update_freshness() { dt = new Date(Math.max( Date.parse(results_posts[0].date), Date.parse(results_courses[0].date))); $("#freshness").html("Newest content added to the site " + dt.toLocaleString('en-CA', doptions) + '' ); } // get type of format function show_compact() { return $("#compact_format").prop('checked'); } // a but clumsy but how to deal with top level categories (areas) and sub categories (topics) // This returns HTML to display them as linked items, separated by type for a given // set of category provided function getCategories (terms) { // category ids for areas (hard coded, agrh) let area_ids = [2,3,4,5,6,40,41,42,44,46]; let areas = []; let topics = []; terms.forEach(function(term) { if ( area_ids.includes(term.id) ) { // area category areas.push( '' + term.name + '' ); } else { // topic category topics.push( '' + term.name + '' ); } }) let out = 'Areas: ' + areas.join(', '); if (topics.length) out += '
    Topics: ' + topics.join(', '); return (out); } function get_selected_cats_val() { // return all the values of selected category checkboxes, each with a comma separated set of vals // Join results as into string array, then split back to arrat, convert text to integer // h/t https://stackoverflow.com/a/6116631/2418186 return($("input.leader-cat[type=checkbox]:checked").map( function () {return this.value;}).get().join(",").split(",").map(Number)); } function get_selected_cats_id() { // return IDs of selected category check boxes // h/t https://stackoverflow.com/a/6116631/2418186 return($("input.leader-cat[type=checkbox]:checked").map( function () {return '#' + this.id;}).get().join(",")); } function get_selected_cats_names() { // return names of selected category check boxes return($("input.leader-cat[type=checkbox]:checked").map( function () {return $(this)[0].labels[0].innerText.trim();}).get().join(", ")); } // --------------- manage interplay of checkboxes on filter form --------------- function set_default_checkboxes() { // set all the checkboxes to be ON $('#results_all').attr('checked', 'checked'); $("#toggle_cats").prop('checked', true); $('.leader-cat').prop('checked', true); $('#compact_format').prop('checked', true); // if localStorage not available, disable the save buttons if ( typeof(Storage) == "undefined" ) { $('#saveboxes').prop('disabled', true); $('#clearboxes').prop('disabled', true); } } // set checkbox state for filter form, first try local storage saved settings function setCheckboxes() { // do we have local storage and for this site? if ( typeof(Storage) !== "undefined" && localStorage.rtype ) { // restore the checkboxes restore_selected_cats(); } else { // set radio buttons and check boxes to default ON set_default_checkboxes(); } } // check all topic checkboxes function checkAllTopics() { if ( $('.leader-topic').not(':checked').length === 0 ) { $("#toggle_cats").prop('checked', true); } } // makes the category checkboxes sync to the "Check all" one $("#toggle_cats").click(function(){ $('input.leader-cat[type=checkbox]').not(this).prop('checked', this.checked); }); // if any category checkbox is de-selected we turn off the select all one function toggleCatsOff(obj) { if (! $(obj).prop('checked')) $("#toggle_cats").prop('checked', false); } // manage state of personal area checkbox, if checked, all sub categories are checked $("#personal").click(function(){ $('input.leader-personal[type=checkbox]').not(this).prop('checked', this.checked); checkAllTopics(); toggleCatsOff(this); }); // manage state of relational area checkbox, if checked, all sub categories are checked $("#relational").click(function(){ $('input.leader-relational[type=checkbox]').not(this).prop('checked', this.checked); checkAllTopics(); toggleCatsOff(this); }); // manage state of organizational area checkbox, if checked, all sub categories are checked $("#organizational").click(function(){ $('input.leader-organizational[type=checkbox]').not(this).prop('checked', this.checked); checkAllTopics(); toggleCatsOff(this); }); //manage checkbox states for a personal leadership topic , sync with parent area checkbox $(".leader-personal").click(function() { // deselect the parent if this unchecked if (! $(this).prop('checked')) { $("#personal").prop('checked', false); $("#toggle_cats").prop('checked', false); } // if all checkboxes checked, then check the parent h/t https://stackoverflow.com/a/5541480/2418186 if ( $('.leader-personal').not(':checked').length === 0) { $("#personal").prop('checked', true); } checkAllTopics(); }); //manage checkbox states for a relational leadership topic , sync with parent area checkbox $(".leader-relational").click(function(){ // deselect the parent if this unchecked if (! $(this).prop('checked')) { $("#relational").prop('checked', false); $("#toggle_cats").prop('checked', false); } // if all checkboxes checked, then check the parent h/t https://stackoverflow.com/a/5541480/2418186 if ( $('.leader-relational').not(':checked').length === 0 ) { $("#relational").prop('checked', true); } checkAllTopics(); }); //manage checkbox states for a organizational leadership topic , sync with parent area checkbox $(".leader-organizational").click(function(){ // deselect the parent if this unchecked if (! $(this).prop('checked')) { $("#organizational").prop('checked', false); $("#toggle_cats").prop('checked', false); } // if all checkboxes checked, then check the parent h/t https://stackoverflow.com/a/5541480/2418186 if ( $('.leader-organizational').not(':checked').length === 0) { $("#organizational").prop('checked', true); } checkAllTopics(); }); // --------------- button/form responses --------------- // update output based on checkbox selection changes $( ".triggr" ).change(function() { $("#newest").empty(); // reset the results first update_results(); }); // add more results to output $( "#more" ).click(function() { // update based on current list length update_results( $("#results > li").length ); // nifty trick to scroll to first newly added item $("html, body").animate({ scrollTop: $('#item' + ($("#results > li").length - loop)).offset().top }, 1000); }); $("#saveboxes").click(function(){ // activate local storage if ( confirm( "Save the selections of these categories for the next time you visit this site?" )){ store_local(); $("#storestatus").text('Selection data has been saved and will be preserved when you return to this site on this same device.'); } else { return false; } }); $("#clearboxes").click(function(){ // clear local storage if ( confirm( "Clear the selections saved on this device? The next time you return, all categories will be checked." )){ localStorage.clear(); $("#storestatus").text('Selection data has been deleted. Save again to preserve settings whenever you return to this site on this same device. '); } else { return false; } }); // prevent form submissions on return in text input fields $('#filtering').on('keyup keypress', function(e) { var keyCode = e.keyCode || e.which; if (keyCode === 13) { e.preventDefault(); return false; } }); // --------------- local storage --------------- function store_local() { // store all topic categories localStorage.setItem( "leadercats", get_selected_cats_id()); // store the content type localStorage.setItem( "rtype", $("input[name='results_type']:checked")[0].id); // store the display option localStorage.setItem( "rformat", $("input[name='results_format']:checked")[0].id); } function restore_selected_cats() { // restore the content type radio button if (localStorage.rtype) $('#' + localStorage.rtype).attr('checked', 'checked'); // restore the display format if (localStorage.rformat) $('#' + localStorage.rformat).attr('checked', 'checked'); // restore topic category selections if (localStorage.leadercats) { localStorage.leadercats.split(",").forEach(function(boxid) { $(boxid).prop('checked', true) }); } $("#storestatus").text('Selections set from stored data. Click "Save Selections" again to update.'); } });//ready