Best way to show & hide multiple items?

Hi everyone! I’m a long time user of Wix for different websites, but fairly new to the coding side.

I have something which is currently working, but i feel i have not gone the best or easiest way about it. I was looking on some suggestions on how you would tackle the following…

You have a map on a website, and information about each district/building. Depending on where you click on the map, you want the corresponding box of information to appear.

This is how i have done it…

The map on my website in a PNG image.
I have overlaid vector shapes onto the map for the areas i want to be clicked, and labelled those as ‘building1, building 2, building 3…’ etc - and added an onClick to each of them.

Upon clicking, the relevant container box will show, with information about that building.
The container box is semi-transparent, contains text, an image, and a button. Each of the container boxes are overlapped ontop of eachother so they will always show in the same spot - and are hidden on load.

That works fine - and it’s something like this:

export function building1_click(event) {
$w('#buildinginfo1').show("fade");
$w('#buildinginfo2').hide("fade");

(‘building1’ refers to the vector shape, and ‘buildinginfo1’ refers to the container box of information)

However, i have 100 different areas on that map…
The way i’ve currently tackled that is to have 100 functions, and each of those functions shows the relevant ‘building info’ and hides ALL the others.
That has resulted in 100 separate functions, each with 1 ‘show’ and 99 'hide’s

When i need to update 1 or 2 of those container boxes (or all of them…?!) i need to basically drag those boxes all over my screen to edit them individually (which is time consuming, and the editor gets quite slow with that many elements) and then align them all again afterwards.

IS that the same way you would tackle this particular instance, or could you recommend an easier way, or a way with less than 5000 lines of code…? :slight_smile:

You can do everything using 1 function.
Put everything in a box.
Then:

$w.onReady(() => {
let boxChildren = $w("#box1").children;
let infoTexts = boxChildren.filter(e => e.type === "$w.Text");
let boxVectorBottons = boxChildren.filter(e => e.type === "$w.VectorImage");
boxVectorBottons.forEach(e => {
    e.onClick(event => {
        infoTexts.forEach(i => i.hide());
        $w("#buildinginfo" + event.target.id.match(/\d+/)[0]).show();
    })
    })
})

Ah! I knew i was over-doing it with all those separate functions…

Thank-you for replying so quickly, if i can get this working it will save me so much time for when i need to create the next map! I can also see a use for this on my other sites too, as i learn more.

I am a complete code noob so i’ll be honest, the above snippet of code boggles my mind… but I really want to understand it.
Is this essentially saying something like ‘when a vector image on the map is clicked, check the last digits of the vector image reference, and show the corresponding info with the same last digits?’ I.E if you click building X > show info X

When you say to put everything into a box - do you mean put ALL of the information options into 1 container box, instead of having them in 100 separate ones?

I can see 4 objects here that are referred to (box1, Text, VectorImage, buildinginfo), but in my code i only have 2 things referred to (building1 and buildinginfo1-100).
I’m so sorry if i am just being stupid…

Not sure if it’s helpful or relevant, but each container box (buildinginfo1, buildinginfo2, buildinginfo3…) will show:

  • Building name and description (Text, unique every time)
  • Image (this will be one of 7 uploaded to my site media - so will not be unique every time)
  • Button (linking to a unique URL every time)

There’re many different ways to do it. I only demonstrated the concept.
In my code you have 1 box and inside the single box you have all the text elements and vector buttons.
So first you create an array of the box children (the elements in the box);
Then you filter them based on element type into 2 different arrays (texts and vectors).
Once you click any of the vector buttons it first hides all the texts, then it takes the last character of clicked vector image id, and show the corresponding text.

You can modify it to other elements and other element types as well.

J.D - Thank-you for taking the time to describe that to me :slight_smile: I always like to understand what i’m doing instead of guessing! That concept sounds like exactly what i need, so I will take the above snippet of code and try to implement that on a duplicated page of my site (no doubt i’ll break it for a while first…!)

You’re welcome. And yes. You should always try to understand the code you’re using, Otherwise you’ll never be able to use it right.

On second thought, since you have many elements, you cannot use the last charterer as an identifier, because some items will end with 2-digit or 3-digit Id. So instead of:

$w("#buildinginfo" + event.target.id[event.target.id.length - 1]).show();

You should use:

$w("#buildinginfo" + event.target.id.match(/\d+/)[0]).show();
//extracts only numbers from the id of the button