Change display of result's template with Javascript

Hi,
I want to change currency of the results when I click on a radio button. When I try to change the display with JS, nothing happened.

searchDemo.addWidget(
    instantsearch.widgets.infiniteHits({
        container: '#infinitehits-container-d',
        showMoreLabel: "Plus de résultats",
        templates: {
            item: function (item) {
                return '<a class="link-item" href="/demo/' + item.cars_getroute + '">' +
                    '<div class="img__container">' +
                    '<img class="infinitehits__img" src="' + item.img_url + '">' +
                    '</div>' +
                    '<div class="left-hit__content">' +
                    '<div class="hit__marque">' + item.marque + '</div>' +
                    '</div>' +
                    '<div class="right-hit__content">' +
                    '<div class="cote_actual_eu" id="cote-actual-eu">' + item.cote_actual.cote_actual_eu.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR', minimumFractionDigits: 0, maximumFractionDigits: 0 }) + '</div>' +
                    '<div class="cote_actual_usd" id="cote-actual-usd" style="display:none">' + item.cote_actual.cote_actual_usd.toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }) + '</div>' +
                    '</div>' +
                    '</a>';
            },
            return item;
        },
    }),
);

My HTML with the radio buttons:

<div class="currency__dropdown--body">
<div class="currency__euro">
    <img src="/assets/images/icons/euro.png" alt="Euro sign">
    <label for="euro">Euro
        <input type="radio" name="currency" value="euro" id="euro-radio" class="euro_radio" checked="checked">
    </label>
</div>
<div class="currency__dollar">
    <img src="/assets/images/icons/dollar.png" alt="Dollar sign">
    <label for="dollar">Dollar
        <input type="radio" name="currency" id="dollar-radio" class="dollar_radio" name="dollar">
    </label>
</div>

And the JS code to change the display:
// Radio button currency
let radioButtonEu = document.querySelector(".euro_radio");
let radioButtonUsd = document.querySelector(".dollar_radio");
//Search cote actual
let coteActualSearchEu = document.querySelectorAll(".cote_actual_eu")
let coteActualSearchUsd = document.querySelectorAll(".cote_actual_usd")

if (radioButtonEu || radioButtonUsd) {
    radioButtonEu.addEventListener("click", currencyEu);
    radioButtonUsd.addEventListener("click", currencyUsd);
    if (radioButtonUsd.checked = true) {
        function currencyUsd() {
        if (coteActualSearchUsd) {
            coteActualSearchEu.forEach(y => y.style.display = "none");
            coteActualSearchUsd.forEach(y => y.style.display = "block");
        }}};

It doesn’t work when I do that, is it possible to change the display like this in InstantSearch ?

Hi @qbolgi
It’s not clear to be how you have linked your radio buttons to your Hit dom. Could you reproduce your code in this boilerplate? https://codesandbox.io/s/github/algolia/doc-code-samples/tree/master/InstantSearch.js/getting-started

Can’t wait to help!

I have difficulties to translate this in Codebox. But I’ll try to be more clear. Is it possible to change the style (display in this case) like I did it in my example ? Or have I to modify it in a Helper ?

Hi there,

Sorry, we are still not able to fully understand what you are trying to do. It would be a lot clearer for us if you could make a reproducible example pointing at what element you would like to change, in a codeSandbox. Thanks in advance!

I tried to edit the codebox, I’d like to be able to check the dollar currency. In this case, the price will be in dollar and the price in euro will be hidden (with a display none).
But it doesn’t work.

Hey @qbolgi - fellow Algolia user here. I recently built something along the same lines, so let’s see if I can’t get you steered in the right direction.

The fundamental issue is you’re defining your price targets upon page load (e.g. coteActualSearchEu). The hits list does not yet exist in the DOM.

Luckily, Algolia provides a render event for us.

// Basic example

search.on('render', () => {
  let coteActualSearchEu = document.querySelectorAll('.hit-price-euro');
  console.log(coteActualSearchEu); // NodeList is now populated
});

Hopefully this sets you on the right path.

2 Likes

I’m a little late but thank you very much, I just tried it and it worked ! Thank you Chad !

1 Like

I have another question. It works well when I type something in the search box. But i’s not the case when the user just arrives on the page, maybe because the search is not rendered… Is there another parameter than “render” to use ?

Hi there,
Sorry if I misunderstand your question.
When you arrive at the page, do you have InstantSearch on the page or not?
If you have, search.on('render', () => {}) should work fine.

If you look at this https://codesandbox.io/s/ais-ecommerce-demo-app-q47s1
as soon as you arrive at the page and InstantSearch loads, the callback will be executed without typing any search query.

Let me know if you meant something else.

Thank you, the problem I have is that I added a ShowMore button and if I click on it without any search in the searchBox the currency doesn’t change which is the case if I search something.

I change the “result” parameter by the “render” one on the but it doesn’t change anything

Okay, I assume you’re using infiniteHits.

If you’re trying it based on your previous implementation which is Change display of result's template with Javascript

then, the problem is with

let coteActualSearchEu = document.querySelectorAll('.hit-price-euro');
let coteActualSearchUsd = document.querySelectorAll('.hit-price-dollar');

That is evaluated once at the page load.

Actually it’s not a good practice to update styles of many elements like that.

I’ve made this example for you which just toggles a class name on #hits element.
Take a look at 64-74 lines.

Even after clicking “show more” button, it works.

Let me know if this solves your problem.

Thank you very much but it’s difficult for me to solve the problem. The problem is that I added a “.toLocaleString” to each value. Without it it works but not without…

Hi @qbolgi,

Can you create a new sandbox from the codesandbox that @eunjae.lee created to demonstrate the issue you are having?