PRO: Simple Faceted Search with JSON and JCI

Challenge:

You have a JSON-API which gives realtime-data. The user should be able to search this data with a faceted search to set options for selecting items.
Click here for an ADVANCED Faceted Search.

In action:

see PRO: Simple Faceted Form in Action


Example-Data:

See https://api.json-content-importer.com/extra/json/meetup/create-cpt.json
This is a list of Events with their Venues. The challenge is to list all venues and make the Events selectable.
For that, you must create 2 JCI templates and 2 Pages. Thats it.


Page 1: The search results

This page puts together the results depending on what the user selected. This is a Shortcode of a new WordPress Page:

[jsoncontentimporterpro nameoftemplate="facetedresults"]

Name this page “get-faceted-results” and publish it. The URL then should be DOMAIN/get-faceted-results/

Yet this page should give you the message that there is no such JCI-Template.
Now we create this JCI template:

facetedresults

URL:

https://api.json-content-importer.com/extra/json/meetup/create-cpt.json

urlparam4twig (parameters for the search):

ch#page#stxt

Template-Text / twig-code: {#… #} are comments you might change for your individual JSON:

{#  you might display the selected search parameter #}
{#
Search Text: {{urlparam.stxt}}<br>
md5-Hashes of the selected options: {{urlparam.ch}}<br>
#}
{% set nof = 0 %}
{% set out = '' %}
{% set stxt= '' %}{% if urlparam.stxt %}{% set stxt = urlparam.stxt %}{% endif %}
{% for i in _context   %}
    {% if  (urlparam.ch=="") or (urlparam.ch matches '/'~  (i.venue.name | trim | md5) ~'/') %}
    {# here you define where the Search-Text is used #}
    {% if  (urlparam.stxt=="") 
        or (i.name matches '/'~(urlparam.stxt)~'/i') 
        or (i.venue.name matches '/'~(urlparam.stxt)~'/i') 
        or (i.venue.address_1 matches '/'~(urlparam.stxt)~'/i') 
        or (i.venue.city matches '/'~(urlparam.stxt)~'/i') 
    %}
    {# add only valid JSON-items to the result, and not those without valid data #}
    {% if i.name %}
        {% set nof = nof + 1 %}
        {# define result HTML snippet #}
        {% set out = out ~ '<b>' ~ nof  ~ ": " ~ i.name ~ '</b><br>' %}
        {% set out = out ~ ((i.time/1000) | date("d.m.Y, H:i")) ~ '<br>' %}
        {% set out = out ~ 'Venue: ' ~ i.venue.name ~ '<br>' %}
        {% set out = out ~ i.venue.address_1 ~ ', '~ i.venue.city ~'<br>' %}
        {% set out = out ~ '<hr>' %}
    {% endif %}
    {% endif %}
    {% endif %}
{% endfor %}
{% if nof >0 %}
    <div id="resultareaitems"></div>
{% else %}
    Nothing found, change selection please
{% endif %}
<script type="text/javascript">
   {# url_encode neded, otherwise some chars effect crashing #} 
   var outitems = '{{out | url_encode }}'; 
   doPag();
   function doPag() {
        let textout = decodeURIComponent(outitems);
        $j("#resultareaitems").html(textout);
    }
<\/script>

Leave the other settings, like cache, twig-parser, etc., as they are (default settings).

Page 2: Create a page with the facet search form and the results

Create a new WordPress page with this shortcode:

[jsoncontentimporterpro nameoftemplate="facetedform"]

You can set the URL and Title of this page as you like. This is the later Search Page for the users.

As with Page 1, we must create a 2nd JCI template:

Name:

facetedform

URL:

https://api.json-content-importer.com/extra/json/meetup/create-cpt.json

Template-Text / twig-code:

{# URL to HTML snippets with results #}
{% set urltoresults = "/get-faceted-results/?show=oc" %}
{# JSON node to loop #}
{% set loop = _context %}
{# populate a list of options on the left side #}
{% set optionList = [] %}
{% for r in loop %} 
    {% if r.venue.name %}
        {% set optionList = optionList | merge(  {(r.venue.name | trim) : 1 }) %}
    {% endif %}
{% endfor %}
{# optionList: {{optionList | json_encode}} #}
{# no functional changed needed below this line #}
<table border=1>
    <tr><td valign="top">
        <form class="retform">
        <b>Text-Search:</b><br>
        <input type="text" name="stxt" value="" placeholder="Insert Text for search here">
        <hr>
        <b>Options:</b><br>
        {% for k,v in optionList %}
            <input type="checkbox" class="ret" id="{{k|md5}}" value=""><span>{{k}}</span><br>
        {% endfor %}
        </form>
    </td><td valign=top>
        <div id="resultarea">select settings on the left side</div>
    </td></tr>
</table>
<script type="text/javascript">
var $j = jQuery.noConflict();
// URL to load results
var zrt = '{{urltoresults}}';
doaj(); 
// update display on events
$j('.retform').change(function(){  doaj();  });
$j('.retform').keyup(function(){  doaj();  });
// do updates by loading a HTML snippet
function doaj() {
    let postpayload = {};  
    let chk = "";
    $j('.ret:checked').each(function(){
        chk = chk  + $j(this).attr('id') + "-";
    });
    postpayload["ch"] = chk ;
    postpayload["stxt"] = $j('input[name=stxt]').val();
    $j.ajax({
        url: zrt, type: "POST",
        data: postpayload, dataType: "text",
        success: function(result){ 
        $j("#resultarea").html(result);},
            error: function(result){ var resulterror ="Request failed. Try again later, please"; $j("#resultarea").html(resulterror); }
    });
}
<\/script>

Leave the other settings, like cache, twig-parser, etc., as they are (default settings). Create a WordPress-Page with this Shortcode:

Additional remark:
The faceted search uses the jQuery-JavaScript-Libraries. Depending on the used WordPress-Template those libraries are already available. If not, you can load them via the JCI-options Tab “Extra”.
Check what your template is offering here (like a css-grid or JS-libs).
In case of need load

  • jQuery: Basic jquery-Lib
  • jQuery-UI, jQuery-UI CSS: Libs for using a slider, etc.
  • jQuery-UI Touch Punch: for using sliders on mobile devices
  • jQuery mobile JS, jQuery mobile CSS: for use on mobile devices

Extra:
Also, at JCI-options Tab “Extra,” you can activate “Load foundation-float.min.css for CSS-grids.”
With that, you can replace the above <table> in the twig-Template for “facetedform” by <div> like that:

<div class="row">
  <div class="columns small-5 large-5">
        <form class="retform">
        <b>Text-Search:</b><br>
        <label><input type="text" name="stxt" value="" placeholder="Insert Text for search here"></label>
        <hr>
        <b>Options:</b><br>
                {% for k,v in optionList %}
                    <input type="checkbox" class="ret" id="{{k|md5}}" value=""><label>{{k}}</label><br>
                {% endfor %}
        </form>
  </div>
  <div class="columns small-7 large-7">
        <div id="resultarea">select settings on the left side</div>
  </div>
</div>

Well – that’s it. For other JSON you have to alter the twig-code to sum up the facet-options.