Conditional data rendering with reactivity and templates
Luigi's Box Front-End libraries allow for using templates to customize results appearance (see Search.js templates or example). To customize user experiance even further, you can take adventage of reactivity concept used in Vue.js.
This example presents how to make use of it and custom templates in order to conditionally render pricing data for users of different types.
Example context
In this example ecommerce is offering products for two types of clients:
- clients paying full price with tax,
- clients paying net price.
For both users store is available under the same domain - user's type can be decided e.g. by a dropdown/select box in site header.
Prerequisite: both prices have to be indexed in catalog.
Setting property in browser
Line of code below presents how to set property prices
with value jsonParsed
.
window.Luigis.Search.$app.$store.commit('setItgState', {key: 'prices', data: jsonParsed});
Changing property value
Code snippet below presents a simple case of switching prize model based on the user input - selection change in <select>
element with class price-model
.
Change of value for select triggers code below which sets priceModel
to selectedPriceModel
.
<script>
// assuming a select box with 2 options for the user - price or price_without_vat
$(".price-model").onchange(() => {
const selectedPriceModel = $(this).val();
window.Luigis.Search.$app.$store.commit('setItgState', {key: 'priceModel', data: selectedPriceModel});
})
</script>
Conditional rendering using template
Using custom HTML template you can achieve rendering results data approproiate for given user.
In the code snippet below price
for product is being presented either as a value of price_amount
or price_wo_vat_amount
. Correct price is rendered conditionally based on itgState.priceModel
, which was previously set in browser.
<script type="text/x-template" id="template-result-default">
<div class="product-price">
<span v-if="itgState.priceModel && itgState.priceModel === 'price'"> {{ attributes.price_amount | price }}</span>
<span v-else> {{ attributes.price_wo_vat_amount | price }}</span>
</div>
</script>
Real life example
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdn.luigisbox.com/search.js" async onload="LBInitSearch(); waitForLuigisApp();"></script>
<script>
function LBInitSearch() {
Luigis.Search({
TrackerId: '179075-204259',
Locale: 'en',
Theme: 'boo',
Size: 20,
Facets: ['brand', 'category', 'price_amount'],
DefaultFilters: {
type: 'product'
},
QuicksearchTypes: ['category', 'brand'],
UrlParamName: {
QUERY: 'q',
}
}, '#q', '#search-ui');
}
</script>
<script>
function waitForLuigisApp() {
if (window.Luigis.Search.$app) {
initializePriceModel();
initializeChangeHandler();
} else {
setTimeout(waitForLuigisApp, 100);
}
}
function initializePriceModel() {
window.Luigis.Search.$app.$store.commit('setItgState', { key: 'priceModel', data: 'price_a' });
}
function initializeChangeHandler() {
$(document).ready(function() {
$(".price-model").on('change', function() {
const selectedPriceModel = $(this).val();
window.Luigis.Search.$app.$store.commit('setItgState', { key: 'priceModel', data: selectedPriceModel });
});
});
}
</script>
<script type="text/x-template" id="template-result-default">
<div class="col-md-4 mb-4">
<a :href="url">
<h5>{{ attributes.title }}</h5>
</a>
<img class="img-fluid" :src="attributes.image_link"/>
<div class="product-price" style="color: #f11;">
<span v-if="itgState.priceModel && itgState.priceModel === 'price_a'">${{ attributes.price_amount.toFixed(2) }}</span>
<span v-else>${{ attributes.price_czk_amount.toFixed(2) }}</span>
</div>
</div>
</script>