Can't get the selected item of a dataset and export to a lightbox [SOLVED]

Hey, guys!
I’m with an issue that I can’t send the values of a selected item from a dataset to a lightbox that should show more info about the item selected.

In the dynamic page I get a random photo of a dataset and show it.
When the user clicks on the photo it should open a lightbox with more information about the clicked item.

Here is the dynamic page code:

import wixWindow from 'wix-window';
import wixData from 'wix-data';

$w.onReady(async function () {

  if (wixWindow.rendering.env === 'browser' || wixWindow.viewMode === 'Preview') {
    let res = await wixData.query("HomepageImages").find();
    let items = res.items;
    let count = items.length; 
    let rnd = Math.floor(Math.random() * count);
    $w('#image3').src = items[rnd].image; 
    $w('#image3').show();
    let selected = items[rnd]._id;

    console.log(selected);
    
    $w('#image3').onClick(lightbox_click);

  }
});

export function lightbox_click(event) {
 let itemId = $w('#dataset1').getCurrentItem()._id;
    wixWindow.openLightbox('GaleriaCovil', {id: itemId});
    console.log(itemId)
}

When the console shows the result of “itemId” it is always the first item of the dataset and it’s not the selected item.
Could you help me, please?

Thank you so much!
RM

You can do this:

import wixWindow from "wix-window"
import wixData from "wix-data"

let selected //Here you get a scope to use it latter

$w.onReady(async function () {
    if (
        wixWindow.rendering.env === "browser" ||
        wixWindow.viewMode === "Preview"
    ) {
        let res = await wixData.query("HomepageImages").find()
        let items = res.items
        let count = items.length
        let rnd = Math.floor(Math.random() * count)
        $w("#image3").src = items[rnd].image
        $w("#image3").show()
        selected = items[rnd]._id

        console.log(selected)

        $w("#image3").onClick(lightbox_click)
    }
})

export function lightbox_click(event) {
    let itemId = selected //Just this change will do.
    wixWindow.openLightbox("GaleriaCovil", { id: itemId })
    console.log(itemId)
}

But I would refactor some of the code to better readability.

Hi, Bruno!
Thanks for helping!

I tried your suggestion and the console returned “undefined” in the itemId.

Do you know what could be wrong?
I’m not a dev so I’m sorry for the basic questions.

Thank you!

Well my first suggestion would be → perhaps you first try to solve it by your own? Your question now surely will be… → How should i do it? I am a newby!

Pay attention onto all the integrated CONSOLE-LOGS!
When using google-chrome → press F12 and navigate to → CONSOLE.
Take a look onto all the given LOGS! Check every single step!

import wixWindow from "wix-window"
import wixData from "wix-data"
//not neede here
//let selected;

$w.onReady(async function() {console.log("My page is ready now!")
  if (wixWindow.rendering.env==="browser" || wixWindow.viewMode==="Preview") {
  console.log("If-statement-1 is running now...")
  let myRESULTS = await wixData.query("HomepageImages").find();
  let items = myRESULTS.items; console.log("RESULTS: ", myRESULTS);
  let count = items.length; console.log("Total-Number of my found items = ", count);
  let rnd=Math.floor(Math.random()*count); console.log("My random-number is = ", rnd);
  $w("#image3").src=items[rnd].image; console.log("Do i have a datafield called ---> Image in my database, with the ID--> image?")
  $w("#image3").show(); 
  let selected = items[rnd]._id; console.log("selected random item = ", selected);

        //this part is a little bit confusing! 
        // What wanted Bruno to do here? --> Using the function from here, or using an export function?
        //$w("#image3").onClick(lightbox_click)

        //However ---> try this one instead....

   $w("#image3").onClick(()=>{
      wixWindow.openLightbox("GaleriaCovil", { id: selected })
   });
  }
  else{console.log("Else-part running....")}
})

Not tested!

@russian-dima

Thank you so much for helping!
This first step worked!

With this code I could get the ID of the selected image.

The second part is to find the selected ID in the dataset and populate the lightbox.
For this in the lightbox, I’m using the following code:

import wixData from 'wix-data';
import wixWindow from 'wix-window';

$w.onReady(function () {
 let selected = wixWindow.lightbox.getContext();
    console.log("selected item =",selected)
    wixData.query("HomepageImages").eq("_id", selected).find().then(results => {
    
   if(results.items.length > 0) {
      let firstItem = results.items[0]; 

      console.log("ITEM = ",firstItem);
      $w("#image6").src = firstItem.image;
      $w("#text1").text = firstItem.title;
   }
    });

});

But the query returns “0” finding the ID selected in the dataset.

The ID of the selected image is right, but seems like the query don’t find any result.

Any idea with this?

Thank you!

@minarirafael

Please make first clear the following questions…

  1. What is a —> DATASET ?
  2. What is a DATABASE ?
  3. When do i use a DATASET ?
  4. When do i use wixData?
  5. Do i mix wixData and datasets?
  6. If i am working with datasets → do i really need to search for IDs?

What i want to say, the way you are going is not good and perhaps even totaly wrong! Why?

  1. Never mix DATASET-coding with wixData-coding (just useful in some rare cases) but will cause in most cases confusion. Either you go the one or the orther way (wix-Data-way or dataset-way).

  2. Also make clear → that the dataset is just some kind of wire/glue/connector to your DB (the important element here is your DB).

Which advantage do you have now → when you got the right id?
Perhaps now you will ask yourself —> why did i want to find the ID ? And you probably will also recognize → damn!!! wouldn’t it be better to find just the right index of the random item?

Your items in your DB all have an index → example: from 0 to 99, right?
Since you are working with a dataset, you could easely use the following…

https://www.wix.com/velo/reference/wix-dataset/dynamicdataset/getitems

You have found your random-index ? Yes you have → so use it :wink:

Let us say your index is: —> 25 → (item-25 inside your database)

Now you are able to get all DATA for item-25, right? Why? → Because your dataset is already connected to your DB ?

You will surely have a repeater or a table on your Lighbox, which will show the random element from your DB provided through your DATASET.

@russian-dima

I tried to understand what you mean, but I’m not a dev and I have serious difficulties in understanding some concepts.

I don’t know if what I did is right (probably not because it’s not working hehe)

$w.onReady( () => {
    
 let selected = wixWindow.lightbox.getContext(); console.log("selected item =",selected);
   $w("#dataset1").onReady( () => {
 
     $w("#dataset1").getItems(selected, selected)
       .then( (result) => {
         let items = result.items;
         let totalCount = result.totalCount;
         let offset = result.offset;

         let firstItem = result.items[0];

 console.log("selected item =",firstItem);
 $w("#image6").src = firstItem.image;

       } )
       .catch( (err) => {
         let errMsg = err.message;
         let errCode = err.code;
       } );

   } );

 } );

The debug shows me this message:

Thanks a lot for the patience to explain me and make me think the right way to make it work.

@minarirafael
Aas i can see → it is also not wrong → because NO ERRORS are in your CONSOLE.

Now what to do? → open the 3-dots → this will give you an insight into the presented OBJECT with all it’s given RESULTS.


What was your plan, one more time?

Can’t get the selected item of a dataset and export to a lightbox

In the dynamic page I get a random photo of a dataset and show it.

When the user clicks on the photo it should open a lightbox with more information about the clicked item.

Ok first make clear thoughts about your SETUP and what you want to achieve.

Your SETUP:

-You have a DYNAMIC-PAGE connected trough a DATASET.
-On your DYNAMIC-PAGE you have different elements and one of these elements is a clickable-pic, where you want to set a triggered-function which will open a light box.
-When Lightbox is opened → you want to show all DATA which belongs to the selected pic, right?

So what are your steps?

  1. Get the current selected ITEM on your dynamic page (you surely know, that on dynamic pages always just ONE-ITEM can be shown at once.

  2. Generating an OBJECT with all the needed DATA, what you want to send to your LIGHTBOX when opening it (using the contect of the LIGHTBOX).

  3. Showing RESULTS inside your LIGHTBOX, either using a REPEATER or by placed elements (like dropdowns, inputs, textfields and so on…) on your LIGHTBOX.

So → let’s GO!

STEP-1: Getting the neccessayry data for the LIGHTBOX (using getCurrentItem)
https://www.wix.com/velo/reference/wix-dataset/dataset/getcurrentitem
https://www.wix.com/velo/reference/wix-dataset/dataset/gettotalcount
Now you have your TOTAL-ITEMS-COUNT and the first basic part of your code → you have the DATA of the current selected ITEM. Do not forget → on DYNAMIC-PAGES you will always get just one ITEM-DATA, to be more precise → always the current selected one (getCurrentItem)!

Your CODE after STEP-1:

var DATASET = "#dataset1"

$w.onReady( () => {
  $w(DATASET).onReady( () => {
    let myItem = $w(DATASET).getCurrentItem(); console.log("ITEM: ", myItem);
    let count = $w("#myDataset").getTotalCount();

   });
 });

But hey —> What the hell! → You wanted a RANDOM PIC → RANDOM selected ITEM! So let’s generate a RANDOM one! We will use your already generated codes.

 let rnd=Math.floor(Math.random()*count); console.log("My random-number is = ", rnd);

STEP-2: Random-ITEM
What happened in the code now? YES! → Now the order is different and we do not use → getCurrentItem anymore, because we want to get a random item!
Why the ORDER of COMMANDS changed? → Because you first have to know the TOTAL-COUNT of your ITEMS to generate your RANDOM-DIGIT.
After you have generated your random DIGIT → you can search for that ITEM in your DATASET/DATABASE of the gotten RANDOM DIGIT-RESULT.

This time we use → getItems()… WHY? → because we need a RANDOM one!

var DATASET = "#dataset1"

$w.onReady( () => {
  $w(DATASET).onReady( () => {
    let count = $w("#myDataset").getTotalCount(); console.log("Total-Items: ", count);
    let rnd = Math.floor(Math.random()*count); console.log("RANDOM-NUMBER: ", rnd);
    let myItem = $w(DATASET).getItems(rnd,1); console.log("ITEM: ", myItem);

   });
 });

HURAYYYYY! Second STEP done! → You have your RANDOM-selected item.

Now try to figure out the same logical way → how to get that found RANDOM-ITEM-DATA → into your LIGHTBOX.

As you can see → your very first approach to generate a random pic, could not work → because you have had any connection between PIC and random gotten DATA. → Never mix DATASETS with wix-DATA → this will just cause you a lot of headaches!!!
Go either the wix-data-way, or use the dataset-one, but try not to mix them.

STEP-3: Preparing DATA to be send to LIGHTBOX (generating an OBJECT)




STEP-4: Open Lightbox with with generated DATA…

import wixWindow from 'wix-window';
6
7export function openButton_click(event) {
8  wixWindow.openLightbox("MyLightBox", {
9    "pageSend1": $w('#pageSend1').value,
10    "pageSend2": $w('#pageSend2').value
11  })
12  .then( (data) => {
13    $w('#pageReceive1').text = data.lightBoxSend1;
14    $w('#pageReceive2').text = data.lightBoxSend2;
15  } );
16}

https://www.wix.com/velo/reference/wix-window/lightbox-obj/getcontext

…and so on…

And do not forget to use —> CONSOLE-LOGS!

CONSOLE → is your BEST-FRIEND !

EDIT: By the way → perhaps you can even skip → STEP-3, because you have already an RESULT-OBJECT. Just send the whole OBJECT to your LIGHTBOX.
You can then decide directly on your LIGHTBOX, which data you want to use out of the whole OBJECT!

Hey, @russian-dima
I think I’m understanding how it works. I think you understood all the process and what I want to do as well.
Let me explain step by step what I’m doing, so you can say if it’s right or not.

First I used the following code in the dynamic page:

var DATASET = "#dataset1"

$w.onReady( () => {
  $w(DATASET).onReady( () => {
    let count = $w(DATASET).getTotalCount(); console.log("Total-Items: ", count);
    let rnd = Math.floor(Math.random()*count); console.log("RANDOM-NUMBER: ", rnd);
    let myItem = $w(DATASET).getItems(rnd,1); console.log("ITEM: ", myItem);

   });
 });

The console returned this:

Looking the reference you gave me about the getItem function I did this with the following code and results:

$w.onReady(() => {
    $w(DATASET).onReady(() => {
        let count = $w(DATASET).getTotalCount();
        console.log("Total-Items: ", count);
        let rnd = Math.floor(Math.random() * count);
        console.log("RANDOM-NUMBER: ", rnd);

        let myItem = $w(DATASET).getItems(rnd, 1)
            .then((result) => {
                let items = result.items;
               
                console.log("Selected Item =", items);
            })
            .catch((err) => {
                let errMsg = err.message;
                let errCode = err.code;
            });

        console.log("Show myItem = ", myItem);

    });

});

Console results:

Looks like it’s getting the right random selected item in the DB.
But I’m still in trouble to apply the theory hehe

What’s the meaning of the return result “Promise<>” in variable “myItem”?

When I try to show the image in the screen it does not work. Seems like the variable “myItem” is null or undefined, therefore the image is not loaded.
I don’t know if it there is syntax or order error in my code.

I’m trying to do this:

var DATASET = "#dataset1"

$w.onReady(() => {
    $w(DATASET).onReady(() => {
        let count = $w(DATASET).getTotalCount();
        console.log("Total-Items: ", count);
        let rnd = Math.floor(Math.random() * count);
        console.log("RANDOM-NUMBER: ", rnd);

        let myItem = $w(DATASET).getItems(rnd, 1)
            .then((result) => {
                let items = result.items;
               
                console.log("Selected Item =", items);  
                $w('#image3').src = items.image;  // get a random image
                $w('#image3').show(); // image on page is hidden, we now show it
            })
            .catch((err) => {
                let errMsg = err.message;
                let errCode = err.code;
            });

        console.log("Show myItem = ", myItem);
  
    });

});

The console result:

So to pass the selected random image to the lightbox should I call a function using a onClick event to the export function?

I did it like this (but I don’t know if it’s correct):

var DATASET = "#dataset1"

$w.onReady(() => {
    $w(DATASET).onReady(() => {
        let count = $w(DATASET).getTotalCount();
        console.log("Total-Items: ", count);
        let rnd = Math.floor(Math.random() * count);
        console.log("RANDOM-NUMBER: ", rnd);

        let myItem = $w(DATASET).getItems(rnd, 1)
            .then((result) => {
                let items = result.items;
               
                console.log("Seleceted Item =", items);  
                $w('#image3').src = items.image;  // get a random image
                $w('#image3').show(); // image on page is hidden, we now show it
                $w('#image3').onClick(callLightbox);
            })
            .catch((err) => {
                let errMsg = err.message;
                let errCode = err.code;
            });

        console.log("Show myItem = ", myItem);
  
    });

});

 export function callLightbox(event) {
    wixWindow.openLightbox("GaleriaCovil", {
            "pageSend1": $w('#image3').src,
        })
        .then((data) => {
            $w('#image3').src = data.lightBoxSend1;
           
        });
}

and in the lightbox it should be like this?

import wixWindow from 'wix-window';

$w.onReady( function () {
  let received = wixWindow.lightbox.getContext();
  $w('#image6').src = received.pageSend1;

} );

Making all these attempts the console returned this:

And the image is not loaded in the lightbox too.

Am I at least near to make this work properly? hehe
I hope you understand what I did.

Thank you so much for helping and teaching me.

@minarirafael

The problem with —>myItem occures because i forgot the async await, but doesn’t matter, you did it already the right way → using the then()-command.

Almost the same as ASYNC-AWAIT.

What you can see on the CONSOLE is an unresolved promise, but at the end you got your result in CONSOLE.

What’s the meaning of the return result “Promise<>” in variable “myItem”?

Here the important part…(you got the right random item-OBJECT.

...
.then((result)=>{
  let items=result.items;console.log("Selected Item =",items);
  $w('#image3').src=items.image;// get a random image
  $w('#image3').show();// image on page is hidden, we now show it
}) 
...

Well but the call for opening the lightbox looks not the best.
And you SURELY want to send the WHOLE → DATA-OBJECT to the lightbox!
NOT JUST THE source of the pic!

exportfunction callLightbox(event){
wixWindow.openLightbox(“GaleriaCovil”,{“pageSend1”:$w(‘#image3’).src,})
.then((data)=>{$w(‘#image3’).src=data.lightBoxSend1;});}

Look at this one…(your basic)…

var DATASET="#dataset1";

$w.onReady(()=>{ 
  $w(DATASET).onReady(()=>{
    $w('#yourButtonIDhere').onClick(()=>{
    
    
    });
  });
);

EXPANDED… (i did in a hurry → not tested!)…

import wixWindow from 'wix-window';

var DATASET="#dataset1";

$w.onReady(()=>{
    $w(DATASET).onReady(()=>{
        let ITEM
        $w('#yourButtonIDhere').onClick(()=>{
            let count = $w(DATASET).getTotalCount();
            console.log("Total-ITEM: ", count);
            let rnd = Math.floor(Math.random() * count);
            console.log("RANDOM-NUMBER: ", rnd);

            $w(DATASET).getITEM(rnd, 1)
            .then((result) => {ITEM = result.ITEM;
                console.log("Seleceted Item =", ITEM);  
                $w('#image3').src = ITEM.image;
                $w('#image3').show(); 
            }).catch((err) => {let errMsg = err.message; let errCode = err.code;});  
        });
        //--------------------------------------------------------------------
        $w('#image3').onClick(()=>{
            console.log("Sending ITEM to LIGHTBOX --> running..")
            wixWindow.openLightbox("GaleriaCovil", {"ITEM": ITEM})
            .then((data) => {
                console.log("Recieved back-data from LIGHTBOX: ", data);        
            });
        });
        //--------------------------------------------------------------------
    });
});

Hi Rafael :raised_hand_with_fingers_splayed:

It’s always the first item because you’re using the global selector, use the repeater scooped selector instead and it should work.

This code assumes you have a clickable element with an ID of " lightbox " inside a repeater.

$w('#lightbox').onClick((event) => {
    const item = $w.at(event.context);
    const currentItem = $item('#dataset1').getCurrentItem();
    wixWindow.openLightbox('GaleriaCovil', { id: currentItem._id });
})

Note #1: I used the dynamic event handler in my example, you can use the static event handler as well, although I recommend the dynamic handler.

Note #2: If you decided to use the dynamic event handler, don’t forget to include it inside the page’s $w.onReady( ) function.


Hope this helps~!
Ahmad

@russian-dima
I think we are almost there! haha

I think the first part is working!!

I coded this in the dynamic page:

var DATASET = "#dataset1"

$w.onReady(() => {
    $w(DATASET).onReady(() => {
        let count = $w(DATASET).getTotalCount();
        console.log("Total-Items: ", count);
        let rnd = Math.floor(Math.random() * count);
        console.log("RANDOM-NUMBER: ", rnd);

        let myItem = $w(DATASET).getItems(rnd, 1)
            .then((result) => {
                let items = result.items;
               
                console.log("Selected Item =", items);  
                $w('#image3').src = items[0].image; // get a random image
                $w('#image3').show(); // image on page is hidden, we now show it
            $w('#image3').onClick(()=>{
            console.log("Sending ITEM to LIGHTBOX --> running..")
            wixWindow.openLightbox("GaleriaCovil", {"ITEM": items
              
              })

            .then((data) => {
                console.log("Received back-data from LIGHTBOX: ", data);        
            });
        });   
            })
            .catch((err) => {
                let errMsg = err.message;
                let errCode = err.code;
            });

        console.log("Show myItem = ", myItem);
  
    });

});

The result:

And when I click in the image it should call the lightbox, but the image is not showed in lightbox.

The error is: TypeError: Cannot read properties of undefined (reading ‘image’)

The results after click:

The lightbox code:


 $w.onReady( function () {
  let received = wixWindow.lightbox.getContext();
let imagem =  $w('#image6').src = received[0].image;
$w('#image6').src = received[0].image;
$w('#image6').show();


console.log("all data received = ",received);
console.log("image url = ",imagem);

} );

Looks like I have all data I need, but I’m not able to show it in the screen.

@minarirafael

Ok your last part / step to fortune.
You forgot to use your best friend → console again.

If your code on your dynamic-page is ready and working well, deactivate all console-logs → reduce unneccessary informations and result on screen.

Now work on your Lightbox-page part.

  1. What do you have?
    You got already your random data-package (item).
  2. You also could send it to lightbox (opening lightbox itself).
  3. Now inspect every single line and put a logical CONSOLE-LOG in every line of the lightbox-code-part.

When your code starts with…
$w.onReady(()=>{ }); —> then also paste a console-log to that line saying, that → lightbox is ready to do some action. Do the same for every single line in your lightbox and inspect what you get as results, for every single line. You are very close.
Not sure if you can use Ahmad’s suggested code, because it’s functionality seems to be a little bit diffrent.

I will take a closer look onto all that when i am back home :+1::v:

@russian-dima

IT WORKS! :tada::tada::tada:

Thank you so much @russian-dima !

I learned so much with your tips and teachings.
Thanks for the patience with a beginner hehehe
I wish you a brilliant and wonderful life!

I will post all the solution below for those who are with similar problems and questions.

Hey, guys!

Thanks to @russian-dima it is working perfectly!
Thank you to @ahmadnasriya and @Bruno Prado for the tips as well.

The solution we found here:

In the dynamic page:

var DATASET = "#dataset1"

$w.onReady(() => {
    $w(DATASET).onReady(() => {
        let count = $w(DATASET).getTotalCount();
        console.log("Total-Items: ", count);
        let rnd = Math.floor(Math.random() * count);
        console.log("RANDOM-NUMBER: ", rnd);

        let myItem = $w(DATASET).getItems(rnd, 1)
            .then((result) => {
                let items = result.items;
               
                console.log("Selected Item =", items);  
                $w('#image3').src = items[0].image; // get a random image
                $w('#image3').show(); // image on page is hidden, we now show it
            $w('#image3').onClick(()=>{
            console.log("Sending ITEM to LIGHTBOX --> running..")
            wixWindow.openLightbox("GaleriaCovil", {"ITEM": items
              })

            .then((data) => {
                console.log("Received back-data from LIGHTBOX: ", data);        
            });
        });   
            })
            .catch((err) => {
                let errMsg = err.message;
                let errCode = err.code;
            });

        console.log("Show myItem = ", myItem);
  
    });

});

And in the lightbox:

$w.onReady( function () {
console.log("lightbox is ready to do some action");

let received = wixWindow.lightbox.getContext(); 
let imagem =  $w('#image6').src = received.ITEM[0].image; 

$w('#image6').src = received.ITEM[0].image;
$w('#image6').show();

$w('#text1').text = received.ITEM[0].title;
$w('#text2').text = received.ITEM[0].autor;
$w('#text3').text = received.ITEM[0].sobre;

} );

SOLVED :slight_smile:

@minarirafael
Well, done.
As you can see–> console-log is your best friend :wink:
:man_shrugging: ET-voila–> you can do it on your own (almost).
A little bit more practise and you don’t need anybody , working with datasets next time.