unbxd / js-sdk

jQuery plugin for Unbxd Search & Navigation
7 stars 27 forks source link

Unbxd JavaScript Search library

Build Status

unbxdSearch.js library can be used to integrated UNBXD search and category page on client side. It supports History API, so users can share the URI.

Note : This library makes use of jQuery selectors and Handlebars templates.

Please find an example of implementation in demo folder.

Usage

Just include unbxdSearch.js in HTML and include the configuration.

configuration

Consider a normal search page with basic layout as shown in the figure below and respective configuration below the image.

Basic search layout

    window.searchobj = new Unbxd.setSearch({
        siteName : 'demo-u1393483043451'
        ,APIKey : 'ae30782589df23780a9d98502388555f'
        ,type : 'search'
        ,getCategoryId : ''
        ,inputSelector : '#search_input'
        ,searchButtonSelector : '#search_button'
        ,spellCheck : '#did_you_mean'
        ,spellCheckTemp : 'Did you mean : {{suggestion}} ?'
        ,searchQueryDisplay : '#search_title'
        ,searchQueryDisplayTemp : 'Showing results for {{query}} - {{start}}-{{end}} of {{numberOfProducts}} Results'
        ,pageSize : 12
        ,searchResultSetTemp : ['{{#products}}<li><a href="https://github.com/unbxd/js-sdk/blob/master/product.html?pid={{uniqueId}}" id="pdt-{{uniqueId}}" class="result-item" unbxdParam_sku="{{uniqueId}}" unbxdParam_pRank="{{unbxdprank}}" unbxdAttr="product">'
                ,'<div class="result-image-container">'
                    ,'<span class="result-image-horizontal-holder">'
                        ,'<img src="https://github.com/unbxd/js-sdk/raw/master/{{{image_url}}}" alt="{{{title}}}">'
                    ,'</span>'
                ,'</div>'
                ,'<div class="result-brand">{{{brand}}}</div>'
                ,'<div class="result-title">{{{title}}}</div>'
                ,'<div class="result-price">'
                    ,'${{price}}'
                ,'</div>'
            ,'</a></li>{{/products}}'].join('')
        ,searchResultContainer : '#results_container'
        ,isClickNScroll: false
        ,clickNScrollSelector : ''
        ,isAutoScroll : true
        ,facetTemp : ['{{#facets}}<div class="facet-block">'
                ,'<h3>{{name}}</h3>'
                ,'<div class="facet-values">'
                    ,'<ul>'
                        ,'{{#selected}}'
                        ,'<li unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}">'
                            ,'<label for="{{../facet_name}}_{{value}}">'
                                ,'<input type="checkbox" checked class="filter-checkbox" unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}" id="{{../facet_name}}_{{value}}"> {{prepareFacetValue value}} ({{count}})'
                            ,'</label>'
                        ,'</li>'
                        ,'{{/selected}}'
                        ,'{{#unselected}}'
                        ,'<li unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}">'
                            ,'<label for="{{../facet_name}}_{{value}}">'
                                ,'<input type="checkbox" class="filter-checkbox" unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}" id="{{../facet_name}}_{{value}}"> {{prepareFacetValue value}} ({{count}})'
                            ,'</label>'
                        ,'</li>'
                        ,'{{/unselected}}'
                    ,'</ul>'
                ,'</div>'
            ,'</div>{{/facets}}'
            ,'{{#rangefacets}}<div class="facet-block"'
            ,'<h3>{{name}}</h3>'
                ,'<div class="facet-values">'
                    ,'<ul>'
                        ,'{{#selected}}'
                        ,'<li unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}">'
                            ,'<label for="{{../facet_name}}_{{value}}">'
                                ,'<input type="checkbox" checked class="filter-checkbox" unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}" id="{{../facet_name}}_{{value}}"> {{prepareFacetValue begin}} - {{prepareFacetValue end}} ({{count}})'
                            ,'</label>'
                        ,'</li>'
                        ,'{{/selected}}'
                        ,'{{#unselected}}'
                        ,'<li unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}">'
                            ,'<label for="{{../facet_name}}_{{value}}">'
                                ,'<input type="checkbox" class="filter-checkbox" unbxdParam_facetName="{{../facet_name}}" unbxdParam_facetValue="{{value}}" id="{{../facet_name}}_{{value}}"> {{prepareFacetValue begin}} - {{prepareFacetValue end}} ({{count}})'
                            ,'</label>'
                        ,'</li>'
                        ,'{{/unselected}}'
                    ,'</ul>'
                ,'</div>'
            ,'</div>{{/rangefacets}}'].join('')
        ,facetContainerSelector : "#facets_container"
        ,facetCheckBoxSelector : "input[type='checkbox']"
        ,facetElementSelector : "label"
        ,facetOnSelect : function(el){
            //jQuery(el).addClass('selected');
        }
        ,facetOnDeselect : function(el){
            //jQuery(el).removeClass('selected');
        }
        ,facetMultiSelect : true
        ,selectedFacetTemp : ['{{#each filters}}'
            ,'{{#each this}}'
                ,'<div class="selected-facet clearfix">'
                    ,'<div class="selected-facet-name lt">{{{prepareFacetValue @key}}}</div>'
                    ,'<div class="selected-facet-delete rt" unbxdParam_facetName="{{this}}" unbxdParam_facetValue="{{@key}}">&times;</div>'
                ,'</div>'
            ,'{{/each}}'
        ,'{{/each}}'
        '{{#each ranges}}'
            ,'{{#each this}}'
                ,'<div class="selected-facet clearfix">'
                    ,'<div class="selected-facet-name lt">{{{prepareFacetValue @key}}}</div>'
                    ,'<div class="selected-facet-delete rt" unbxdParam_facetName="{{this}}" unbxdParam_facetValue="{{@key}}">&times;</div>'
                ,'</div>'
            ,'{{/each}}'
        ,'{{/each}}'].join('')
        ,selectedFacetContainerSelector : "#selected_facets"
        ,clearSelectedFacetsSelector : "#clear_all_selected_facets"
        ,removeSelectedFacetSelector : ".selected-facet-delete"
        ,selectedFacetHolderSelector : ""
        ,loaderSelector : ""//".result-loader"
        ,onFacetLoad : function(obj){}
        ,sanitizeQueryString : function(q){ return q;}
        ,getFacetStats : ""
        ,processFacetStats : function(obj){}
        ,setDefaultFilters : function(){}
        ,onIntialResultLoad : function(obj){}
        ,onPageLoad : function(obj){}
        ,onNoResult : function(obj){}
        ,facetMultilevel: true
        ,facetMultilevelName: 'CATEGORY'
        ,mappedFields: {
            'price': price,
            'title': name,
            'imageUrl': imageurl,
            'description': desc,
            'variantFields': {
                'v_imageUrl':v_imageUrl,
                'v_productUrl':v_productUrl,
                'v_price':v_price,
                'v_title':v_title
            }
        }
        ,variants: false,
        ,bannerSelector: ".banner"
        ,bannerTemp: "<a href='{{landingUrl}}'><img src='{{imageUrl}}'/></a>"
        ,fields : ['image_url','title','brand','price','uniqueId']
        ,searchQueryParam:"q"
        ,retainbaseParam: false
        ,baseParams:[]
    });

In this case, we need to also mention the different view types under 'viewTypes':

,viewTypes: ['grid', 'list']
,viewTypeContainerSelector: '.view_type_select'
,viewTypeContainerTemp:
    '{{#options}}'
    +'<li class="nxt-{{#if selected}}current{{/if}}">'
        +'<a title="{{value}} View" class="nxt-{{value}}view-button" {{#unless selected}}unbxdviewtype="{{value}}"{{/unless}}>'
            +'<span class="icon-{{value}}view">'
            +'</span>'
        +'</a>'
    +'</li>'
    +'{{/options}}'

JSON used for this template:

{
    options: [{
        "selected": true,
        "value": "grid"
    },
    {
        "selected": false,
        "value": "list"
    }]
}

Note: The HTML served by the server to client should have the minimum requred structure. Check the below image.

Basic search layout

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>UNBXD - Search</title>
    <link rel="stylesheet" type="text/css" href="https://github.com/unbxd/js-sdk/blob/master/css/style.css">
    <script type="text/javascript" src="https://github.com/unbxd/js-sdk/raw/master/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="https://github.com/unbxd/js-sdk/raw/master/handlebars.js"></script>
    <script type="text/javascript" src="https://github.com/unbxd/js-sdk/raw/master/unbxdSearch.js"></script>
</head>
<body>
    <div class="header-container clearfix">
        <div class="header row clearfix">
            <div class="header-search">
                <div class="search-input-button-holder clearfix">
                    <form method="GET" action="search.html">
                        <input type="text" class="search-input lt" id="search_input" value="" unbxdattr="sq" name="q" autocomplete="off"/>
                        <button type="submit" class="search-button lt" id="search_button" unbxdattr="sq_bt"></button>
                    </form>
                </div>
            </div>
        </div>
    </div>
    <div class="search-container">
        <div class="row clearfix">
            <div class="lt search-facet-column" id="facets_container">
            </div>
            <div class="rt search-result-column">
                <h2 class="result-spell-check" id="did_you_mean">
                </h2>
                <h3 class="result-title-count" id="search_title">
                </h3>
                <div class="result-selected-facets clearfix" id="selected_facets">
                </div>
                <ul class="search-result-list clearfix" id="results_container">
                </ul>
                <div class="result-loader" id="ajax_loader">
                <a href="#"><img src="https://github.com/unbxd/js-sdk/raw/master/images/loader.gif">Loading more...</a>
            </div>
            </div>
        </div>
    </div>
    <div class="footer">
        Copyright &copy; 2014 Unbxd
    </div>
    <script type="text/javascript">
    jQuery(function(){
        //search configuration here
    });
    </script>
</body>
</html>