Display an image when hover over an item in a Radio Button Group

Each item in a radio button group has an associated image in the data source database. The user should hover over (not click) an item to temporarily display the image. If he clicks the item, the image should display permanently.

I have done this with checkboxes, but radio buttons require less coding for other things on my custom page. Can anyone tell me if this is possible with Radio Buttons, and if so, please give me some tips or snippets on direction or how to build it in code? Thanks.

Pay attention on the fact, that radiobuttons have a little bit a different functionality.

As i know → you can choose just one option simutaniously when working with radio-button-group. Checkboxes offers a multi-checking.

Your SETUP:

  1. 1x Database
  2. 1x Radiobutton-Group with several options
  3. Action fired on MouseIn() and onClick().

Let us say you store your IMAGE-DATA in a DATAFIELD called “pics” and your database is called “myDB”.

First of all you will have to query your DB, but not just do a simple db-query!
You wanto query by the filtering for the right selected index of your READIOBUTTON-GROUP!

https://www.wix.com/velo/reference/$w/radiobuttongroup/selectedindex

$w.onReady(()=>{
	$w("#myRBGroup").onChange(()=>{
		console.log($w("#myRBGroup").selectedIndex);
	});
});

And here you already will face the first problem!
A radio-button-group do not provide → onMouseIn( ) !!!
So i think your wished functionality won’t be able to work, the way you want.
You will have to search for an alternative way.

Well, the documentation indicates onMouseIn() is available for RadioButtonGroup, but I have not tried it and just assumed I could use it. Not being an expert, it misled me, so thank you.

Since I can’t use RadioButtonGroup then my only alternative seems to be to build my own version using checkboxes aligned like a radioButtonGroup with controls to ensure only one item can be selected. Its just that it is SO TEDIOUS having to change the #names for each item on the checkbox line. I wish there was a better way to change them other than manually.

multi-checkboxes would work for me, but maybe a repeater would be a possibility. have to look into that further

You are right, MouseIn() is available for Radio-Buttons, i must mixed-up something. However even if the neccessary command exists, i still belive, that the usage of a radio-button-group for your purpose is useless.
You can test it by your own.
Generate an onMouseIn/Out event-triggering and console-log the event-output.
Move your mouse over all radiobutton, options and take a look if you get an output for every single radio-button-option, or if you get an output for just the whole radiobutton-group.

console.log(event.target) → inspect the results.

The only way i see to get your functionality working is by using a repeater in combination with either buttons or single checkboxes, because your data is loaded from database.

The way you could easily do this is using a transparent box on top of each radio option and using the .onMouseIn() and .onMouseOut() methods of each box. Less coding and hassle than a repeater.

To recap, the radio buttons are filled from a database and can be any length. I am trying to imagine what your suggestion would look like. If you are suggesting a box on top of the whole radiobuttonGroup element I don’t see how I can display images from each element. If you are suggesting a box somehow on top of each individual option, wouldn’t I need to know how many options there will be ahead of time? Please give me more details of your idea.

For that, you should use a repeater and put a single radio button in each repeater element. The do something like:

$w.onReady(() => {
$w('#repeater1').onItemReady(($i, iData) => {
    $i('#radioGroup1').options = [{value: iData._id, label: iData.title}];
})
$w('#radioGroup1').onMouseIn(event => {
    const iData = $w('#repeater1').data.find(e => e._id === event.context.itemId);
    $w('#imageToDisplay').src = iData.image;
})
})

@jimyaccino Ok, I missed the “filled from database”, that would make it impossible to be done the way I suggested. Sorry. The repeater would be your best bet.

Yes, a SINGLE-Radio-Button also works. (i was to fixed on a RADIO-BUTTON-GROUP).

@russian-dima I meant radio-button-group with a single option each. (I don’t think there’s a single radio button element. Am I wrong?)

@jonatandor35 Yes it makes sense! Again i am mixing it up with Check-Boxes → DAMN! :sweat_smile:
It was the checkbox, which was available at SINGLE-MODE.

Ok, seems your solution will be the perfect one, because a Radio-Button compared with a check-box can’t be unchecked again (altough → disabling a checkbox after first checking would generating the same functionality, wouldn’t it) ???

Once you check → checkbox disables and can’t be unchecked anymore.
Or is there still difference compared to the RadioButton-Group?

@russian-dima it can’t be unchecked via code.
Actually in the code Break80 will have to reset it like that:

$w('#radioGroup1').onChange(event => {
	$w('#repeater1').forEachItem(($i, iData) => {
	if(iData._id !== event.context.itemId){$i('#radioGroup1').value = null;}
})
})

@jonatandor35
Oh wait J.D. now you must mix-up something :sweat_smile:
I was talking about CHECKBOXES (single-mode).
https://www.wix.com/velo/reference/$w/checkbox/checked

Just wanted to make clear that the same functionality is able to be generated by using a single-checkbox inside repeater.

-repeater loads data from DB
-each item connected to a checkbox
-hover over the correcponding checkbox (MouseIn / MouseOut) → showsTEMPORARY info
-click on the checkbox (check) will emmidiatelly disable the checked CHECKBOX and show the related item PERMANENTLY.
-an unchecking of CHECKBOX is not possible anymore → because DEACTIVATED/DISABLED.

Also a RESET of checked CHECKBOXES would be possible (by code).

So i would say, here we have two different ways of how to solve it. All just theoretical thoughts for training my brain → i have never tested it :sweat_smile::rofl:

-single checkbox
-Radiobutton-Group

The only difference i see would be of design-aspect, but functionality should be the same.

Here below in the picture is the repeater I have been considering…from left to right you will see an image, a single checkbox, and three text boxes. For now, there is just one image available in this test, 4th one down.

Three features are required in this design:
1. Hover - hovering over an image in the repeater would display a larger image. I believe this should be able to work using onMouseIn/onMouseOut. Hovering would display the selected image in a different larger image element somewhere else on the page.
2. Select - buyer needs ability to select/deselect any number of items.
3. Pre-Checked selections - the repeater need to display one or more “pre-checked” boxes that cannot be unchecked manually when the repeater is called to display itself.

For lots or reasons, I don’t think radio buttons or multi checkboxes can do all I need. However I HAVE already achieved all the above requirement using over 100 single lines each containing an image, a checkbox and 3 text boxes (similar to the above ) elements pasted individually to the page. Its a royal mess since every element alias name (e.g. #name, etc) on the page must be handled manually. Since the wix editor is not designed to do mass changes like this, the job is very tedious and way too time consuming.

I believe a “repeater” (as some of you have mentioned) containing the same information as my individual checkbox design should work. Given the above background, can a repeater with associated code be built to meet all three requirements? What are the pitfalls?

I am guessing there might be an Wix template example of something like this, but I don’t know how to find it.

All your wished functions can be done using Ccheck-Box (SINGLE-MODE).
And normaly also all your questions already have been answered in this post.

  1. Hover-Features → Yes possible! → Checkbox/or RadiobuttonGroup
  2. Any number of items → Yes, possible! → ARRAY
  3. Prechecked-Sections → Yes, also possible.
  4. uncheck-protection: Yes possible → discussed in this post.

For lots or reasons, I don’t think radio buttons or multi checkboxes can do all I need.

It’s either the RadiobuttonGroup, nor the Checkbox who is the most important element in your wished functionality! → It’s the → REPEATER !

@russian-dima I agree the repeater is my best method to use, and my tests are going in that direction as you see in my last post. Thanks for all your help, collectively.

There is just one more item that has not been touched (at least I don’t see it) by any posts. That is how open the repeater with prechecked items already displayed. That is when the repeater first displays, no boxes are checked. When I click a box, the box I click AND the precheck box show up. Any thought on what I can do to get the precheck to display when the repeater is first displayed?

@jimyaccino
All your already displayed items, which have been already checked once, you will have to save their STATUS inside your DB → for example → using a BOOLEAN-DB-FIELD.

This way you can load checkboxes, knowing which ones already have been selected once, because the booleanfiled changed from false to → true.

When you load data to your REPEATER …

booleanField will be the field where you will set FALSE/TRUE-VALUES

$w('#myRepeaterID).onItemReady(($item, itemData, index)={console.log(itemData);
   console.log(itemData.booleanField); //result --> status of every single loaded checkbox
});

I do not test what i am suggesting here, everything i do out of my mind, so you will have eventually to do some corrections.

To keep all this in an short conclusion: → You need something which works like MEMORY and knows exactly which checkbox already has been clicked once.
And your MEMORY is your DATABASE → Boolean-Field!

I just did this for you, see if it fits you and let me know:

import wixData from 'wix-data'

//This function changes the image
const changeImg = (imgElement, src) => (imgElement.src = src)

//This is the hard coded preselected index
const preSelectedIndex = 1

$w.onReady(async () => {
    //This sets up the repeater to all the functions you want
    $w('#rptChoices').onItemReady(($item, itemData, index) => {
        //This sets up the text inside the repeater contextually
        $item('#title').text = itemData.title
        //This sets up the text inside the repeater contextually
        $item('#text1').text = itemData.text1
        //This sets up the text inside the repeater contextually
        $item('#text2').text = itemData.text2

        //This checks the box or not, depending on the preSelectedIndex
        $item('#cb').checked = index === preSelectedIndex ? true : false

        //This checks if the checkbox is selected or not, if so, disables it
        $item('#cb').checked === true && $item('#cb').disable()

        //This functions controls the mouseIn function.
        $item('#box').onMouseIn(() => {
            changeImg($w('#img'), itemData.image)
            $w('#img').show()
        })
        //This functions controls the mouseOut function.
        $item('#box').onMouseOut(() => {
            changeImg($w('#img'), itemData.image)
            $w('#img').hide()
        })
    })
    //This retrieves the data
    const data = await wixData.query('Choices').find()
    //This puts the data inside the repeater
    $w('#rptChoices').data = data.items
})

Try it here: Checkbox

I took a look onto your example Bruno.
I think what the postopener will be missing, is the following one…

If he clicks the item, the image should display permanently.
The last selected pic (single-mode-selection) do not stay permanently, after it has been chosen.

Of course this is just an example! So the post-opener will still have to do some work on it to get the right functionality. There is also a little white-gap between Image-Switch, which also has to be fixed → perhaps with a smooth fade-in/fade-out after img-src has been loaded.

@ Bruno Prado → Also pay attention on this one…

Since I can’t use RadioButtonGroup then my only alternative seems to be to build my own version using checkboxes aligned like a radioButtonGroup with controls to ensure only one item can be selected

It seems that break80 wanted to achieve a functionality where the user is able to choose ALWAYS JUST ONE PIC AT ONCE , if i understood it the right way (but perhaps i missunderstood something).
No multi-selection should be possible.
I asume, this is why break80 wanted to use → Radiabuttons.
And this is why i suggested → DISABLING immediately selected CHECKBOX after checking.

Bruno i know you can do it better :wink:.

However, it is a good start!

@russian-dima You are right, I didn’t read everything @jimyaccino wanted, just the last post so I clearly misunderstood. Would this be a solution?

import wixData from 'wix-data'

//This function changes the image
const changeImg = (imgElement, src) => {
    fixedImage ? '' :   imgElement.src = src
}

//This is the hard coded preselected index
let preSelectedIndex
let fixedImage = false

$w.onReady(async () => {
    //This sets up the repeater to all the functions you want
    $w('#rptChoices').onItemReady(($item, itemData, index) => {
        //This sets up the text inside the repeater contextually
        $item('#title').text = itemData.title
        //This sets up the text inside the repeater contextually
        $item('#text1').text = itemData.text1
        //This sets up the text inside the repeater contextually
        $item('#text2').text = itemData.text2

        //This checks the box or not, depending on the preSelectedIndex
        $item('#cb').checked = index === preSelectedIndex ? true : false

        //This checks if the checkbox is selected or not, if so, disables it
        $item('#cb').checked === true && $item('#cb').disable()

        //This functions controls the mouseIn function.
        $item('#box').onMouseIn(() => {
            changeImg($w('#img'), itemData.image)
            $w('#img').show()
        })
        //This functions controls the mouseOut function.
        $item('#box').onMouseOut(() => {
            changeImg($w('#img'), itemData.image)
            fixedImage || $w('#img').hide()
        })
        //This function does stuff when a checkbox is changed
        $item('#cb').onChange(() => {
            fixedImage = false
            changeImg($w('#img'), itemData.image)
            fixedImage = true
            //Runs through the options and change them, letting only the selected one marked
            $w('#rptChoices').forEachItem(($i, idata, i) => {
                $i('#cb').checked = i !== index ? false : true
            })
        })
        //This fixes the image after being clicked
        $item('#box').onClick(() => (fixedImage = !fixedImage))
    })
    //This retrieves the data
    const data = await wixData.query('Choices').find()
    //This puts the data inside the repeater
    $w('#rptChoices').data = data.items
})

You can use the same link to test.