Hide Button If No Content In Database (Repeater)

I tried adding to another thread, but it was closed and my problem is still not sorted out. I will try to transfer what I know.

This is the code I had:
$w . onReady ( function () {
$w ( “#repeater1” ). onItemReady ( ( $w , itemData , index ) => {
if ( itemData === undefined || itemData . email === undefined || itemData . email . length === 0 ) {
let vendorString = “” ;
if ( itemData !== undefined ) {
vendorString = itemData . vendor ;
}
$w ( “#email” ). hide ();
} else {
let vendorString = itemData . vendor ;
}

if ( itemData === undefined || itemData . socialMedia === undefined || itemData . socialMedia . length === 0 ) {
let vendorString = “” ;
if ( itemData !== undefined ) {
vendorString = itemData . socialMedia ;
}
$w ( “#social” ). hide ();
} else {
let vendorString = itemData . socialMedia ;
}
});

And it all of a sudden stopped working.

So I tried this:
$w . onReady ( function (){
$w ( " #vendorDataset " ). onReady (()=>{
if ( $w ( " #email " ). link === “” ){
$w ( " #email " ). hide ();}
if ( $w ( " #socialMedia " ). link === “” ){
$w ( " #socialMedia " ). hide ();
}
});
});

Which was definitely wrong because I forgot to mention that it was a repeater. So I returned back to the other code, but it is still not working.

Here are some images which might help…

Dataset Name:

Button Names:

Here is the reference page: www.thequeensmarketshop . com/vendors

Here is an image of the database showing blank entries.

Its a Normal Page and not a Dynamic page, at least I don’t think.

Thanks to those who have helped me so far.
@russian-dima
@volkaertskristof
@stcroppe

Try always first to clarify your project…

What we know?

  1. You are using a repeater.
  2. You are using a dataset (non-dynamic one) → at least you think that :grin:
  3. You are using buttons (which should be hidden when no data found in DB)
  4. Oh hell, yes you are also using a —> DATABASE.

But wait! How is now the relation between DB ↔ DATASET <—> and REPEATER?

You have now your DATA stored in your DB.
Your DB is connected by a DATASET to a REPEATER.
So you are able to manage DATA directly out of the repeater…

Simple example: for " email "-datafield…

const datafield = "email"

$w.onReady(function () {
    $w("#repeater1").onItemReady(($item, itemData, index) => {
        console.log($w)
        console.log(itemData)
        console.log(index)
        //----------------------------------------
        const repeatedData = itemData[datafield]

        if(repeatedData) {$item("#email").show()}
        else {$item("#email").hide()}
    });
});

If no entry in “email”-datafield, then element —> “#email” should be hidden.
Modify and expand this example for your own needs.

No luck so far. Is it my initial setting of the buttons. I tried Hidden, and it just hid the buttons.

Thanks again for help!

@thequeensmarketshop
Everything works like described in my post (tested here on this site…)
https://www.media-junkie.com/repeater-queensmarket

var datafield = "title"

$w.onReady(function () {
    $w("#repeater1").onItemReady(($item, itemData, index) => {
        console.log($w)
        console.log(itemData)
        console.log(index)
 //----------------------------------------
 const repeatedData = itemData[datafield]

 if(repeatedData) {$item("#image1").show()}
 else {$item("#image1").hide()}
 });
});

Title 3 + 6 is empty —> Repeater-Image 3 + 6 is hidden!

EDIT: After changes—> it is now the button which is hidden (instead of the image). Read the post till end to understand this changement.

BTW: Your old post here…
https://www.wix.com/velo/forum/coding-with-velo/hide-buttons-if-no-content

Okay. Maybe its the name of my columns. I am pretty sure they are named the same.

In your example, are you relating two columns being blank? In my case I am treating each button(database column) individually. And I don’t want to hide the whole vendor, just the button.

Yah, they just removed commenting even though I was carrying on from the previous posters code. I was trying to carry on from a similar topic, but that is okay. Thank you for linking, just in case others want to follow-up. :slight_smile:

@thequeensmarketshop I gave you just a simple example which should help you to understand how you can/could solve your issue.

You can generate severat buttons with following ID (ID = name of a column in your DB), for example…

$item("#email")
$item("#socialMedia")
$item("#description")

…and so on…
Now you have identical ID for BUTTON sand DATAFIELDs.

Now ATTENTION, here comes the trick…

let columnID =$w("#myElement").id;// "myElement"

In your case…

let columnID1 = $item("#email").id;
let columnID2 = $item("#socialMedia").id;
let columnID3 = $item("#description").id;
var datafield ="title"  

$w.onReady(function(){
	let columnID1 = $item("#email").id;
	let columnID2 = $item("#socialMedia").id;
	let columnID3 = $item("#description").id;
	
	$w("#repeater1").onItemReady(($item, itemData, index)=>{
		const repeatedData1 = itemData[columnID1]
		const repeatedData2 = itemData[columnID2]
		const repeatedData3 = itemData[columnID3]
		
		if(repeatedData1){$item("#email").show()}
		else{$item("#email").hide()}
		
		if(repeatedData2){$item("#socialMedia").show()}
		else{$item("#socialMedia").hide()}
		
		if(repeatedData3){$item("#description").show()}
		else{$item("#description").hide()}
	});
});

This should do the trick and solve your issue.

Good luck and happy coding.:wink:

@thequeensmarketshop I’m not sure what you are really trying to do. Having looked at your code in the link above the record format that you are dealing with is shown below. The pink colored text are the property keys for each record. There is not a property key with the name “email”.

What it seems that you are trying to do is hide the image element if the title property is empty. In your screenshot above the third row (Vladimir Putin) does not have a title value. So if you want to hide the image in this case you simply do this:

$w . onReady ( function (){

$w ( "#repeater1" ). onItemReady (( $item ,  itemData ,  index ) => { 
	// get the title property 
	const  title  =  itemData [ "title" ]; 

	if ( title)  { 
		// If title exists show the image 
		$item ( " [#i](https://www.wix.com/velo/forum/search/~num~socialMedia) mage" ). show () 
	} **else** { 
		// If the title does not exist hide the image 
		$ item ( " [#i](https://www.wix.com/velo/forum/search/~num~socialMedia) mage" ). hide () 
	} 
}); 

});

  1. anrede : “Herr”

  2. ausbildung : “abgeschlossen”

  3. berufserfahrung : “1”

  4. bundesland : Array(2)

  5. 0 : “Oberösterreich”

  6. 1 : “Niederösterreich”

  7. length : 2

  8. proto : Array(0)

  9. geburtsort : “U.S.A”

  10. name : “Trump”

  11. nationalitat : “amerikanisch”

  12. pic : “wix:image://v1/b03143_4f5e6883057a4649b9b8e997208b01b5~mv2.png/AVATAR-Trump.png#originWidth=256&originHeight=256”

  13. sprache : Array(1)

  14. 0 : “Englisch”

  15. length : 1

  16. proto : Array(0)

  17. status : “Aktiv”

  18. title : “1”

  19. verfugbarkeit : “abwesend”

  20. vip : true

  21. vorname : “Donald”

  22. _createdDate : Sat Nov 28 2020 09:51:41 GMT+0000 (Greenwich Mean Time) {}

  23. _id : “069fdd20-c146-439d-8b6c-6c021e72b039”

  24. _owner : “b031430e-f59e-4ef2-aac6-787ef04e9b2c”

  25. _updatedDate : Wed Apr 14 2021 23:23:27 GMT+0100 (British Summer Time) {}

Close… but i think he wants to show hide buttons, related to the given values in his DB. It was just an example → i used images instead of a buttons.

And yes that would be the simple one. This one is working on my example here…
https://www.media-junkie.com/repeater-queensmarket …for the images.

$w.onReady(function(){
   $w("#repeater1").onItemReady(($item, itemData, index)=>{
      // get the title property
      const title = itemData["title"];
      if (title) {
      // If title exists show the image
         $item("#image").show()
      }else{
         // If the title does not exist hide the image
         $item("#image").hide()
      }
   });
});

I changed my example —> to act with buttons instead of images…
Did not want to cause misunderstandings.


Now it works with buttons instead of images.
If there is no —> TITLE (number), then the correcponding button also will be hidden.

No ENTRY in DB: (item3 & item6)

No BUTTON in REPEATER: (item3 & item6)

In my example, the button-ID is —>“#title” and it is also the datafield-ID at once.

But the post-opener would need something like this one…

$w.onReady(function(){
    $w("#repeater1").onItemReady(($item, itemData, index)=>{
       const repeatedData1 = itemData[$item("#email").id]
       const repeatedData2 = itemData[$item("#socialMedia").id]
       const repeatedData3 = itemData[$item("#description").id]
 
       if(repeatedData1){$item("#email").show()}
       else{$item("#email").hide()}
 
       if(repeatedData2){$item("#socialMedia").show()}
       else{$item("#socialMedia").hide()}
 
       if(repeatedData3){$item("#description").show()}
       else{$item("#description").hide()}
    });
});

His setup was …

  1. Button-ID-1 —> “#email
  2. Button-ID-2 —> “#socialMedia
  3. Button-ID-3—> “#description
    and so on…

Of course the BUTTONS have to be INSIDE —> REPEATER !

More about the corresponding DATABASE-EXAMPLE you will find here …
https://www.media-junkie.com/pflegeservice

Wow guys, thanks for going back and forth and trying to solve me issue.

Unfortunately this example:

$w . onReady ( function (){
$w ( “#repeater1” ). onItemReady (( $item , itemData , index )=>{
const repeatedData1 = itemData [ $item ( “#email” ). id ]
const repeatedData2 = itemData [ $item ( “#socialMedia” ). id ]

if ( repeatedData1 ){ $item ( “#email” ). show ()}
else { $item ( “#email” ). hide ()}

if ( repeatedData2 ){ $item ( “#socialMedia” ). show ()}
else { $item ( “#socialMedia” ). hide ()}
});
});

Still did not work, and I am trying to figure out why. It totally makes sense.
-Yes, the buttons are in the repeater, or they wouldn’t work with the database, right?

Questions I ask myself:

  1. Does the button need to start off as ‘Hidden’ in the properties panel?
  2. Is something name wrong (caps or lowercase) to make this not work?
  3. Could it be my browser type? I use FF, but many still do.
  4. Do you I need to reconnect things?
  5. Could other code interfere with this? I guess it would scream at me if it did.

Here is another image with as much detail possible.

I am sorry to be a pain, and I appreciate ALL your efforts so far.

Cheers

  1. Check all your element-IDs → all button-IDs are right?
  2. Check your dataset-ID.
  3. Check if the dataset is connected to the right DB.
  4. Check if button-IDs are the same as the related datafield-IDs…


For example:
Button-ID = “#email” → related datafield-ID should be —> “email”

Normaly you should now have enough informations, to get your project to work.

If you still can’t get it to work, then create a → BLANK new site and try first to reconstruct the shown example. Then understand it and then try to complete your own issued project.

Queens Market - can you post the page link that you are having a problem with? You have only showed a small segment of the data collection which doesn’t help with addressing your problem.

My earlier post mistakenly reflected what I saw on russian-dima’s mock up (apologies I mis read the thread).

You do not need to bother with IDs for what you are trying to do.

In every data collection there are two field names one that is for humans to see. Example in your screen shot would be “Description” or “SocialMedia”. One that code wants to see (there are called field keys and are camel cased versions of your Field names. So “Description” becomes “description” and “SocialMedia” becomes “socialMedia”.

In addition if you have renamed the field name used by a human to identify the column it will retain the old field key name. So if you rename “SocialMedia” to “Social Media Links” the field key will remain the same “socialMedia”.

Now what you are trying to do is see if one of the itemData column values is null or not in your test to show or hide the email or other elements.

To determine the value of an itemData column you need to know the correct field key name and use it as an object selector.

itemData is an object and will look something like this:

{
socialMedia:”Facebook,
email:”john.smith@email.com”,
description:”This describes facebook info”
}

These are the column values from the data collection (data set).

You access each value in one of these two ways:

let email = itemData.email;

or

let email = itemData[“email”];

These are syntactically the same.

Now if itemData[“email”] is undefined or empty then email will likely be null. Null is what we call untruthy. This means it doesn’t have a value that is intelligible and is treated by JavaScript as false (e.g. not true or untruthy).

The conditional test if (xxx) {}. tests for something to be truthy. So if (email) {} is saying “if email is truthy then we can proceed into the if statement block. That is if email contains a meaningful value.

OK mini tutorial over.

What you need to do is “SEE” what data is being processed by your code and to do this you need to sprinkle a few console.log() statements in your code to see what the data is that your code is seeing.

You also need to fix your onItemReady handler argument list :-).

Since you are working with a repeater you need to be clear on the scope of the elements you are working with. $w is how we access elements in the “global scope” of the Velo IDE. When you are inside of a repeater (that is you have the same element recurring for each item being displayed) you need to be using the repeater item scope. So don’t use $w as the first handler argument you need to use $item (or something else that is NOT $w).

So to help you debug and fix you code you need to alter your onItemReady and the element access code like this

// Make sure handler uses $item as first argument NOT $w

$w(“#repeater1”).onItemReady(($item, itemData, index) => {

// Use console log to look at the itemData value being handled by the onItemReady repeater 
// because the itemData value is an object we will use stringify to see the output 
console.log(`itemData => $log {JSON.stringify(itemData)}`); 

// In order to hide the email element we need to use the $item scope 
    $item(“#email”).hide(); 

// In order to show the email element we need to use the $item scope 
    $item(“#email”).show(); 

});

Of course the code above is not a replacement for your code but intended to show you what you need to do when working inside of a repeater.

Note in the console.log statement in the above code there is a syntax error which wix forum won’t let me edit :-(.

the syntax is:

console.log(itemData => ${JSON.stringify(itemData)});

Okay @stcroppe , I gave it a shot. I left the console log visible to see if it helps with the problem solving.

This is my 5th attempt, your explanation is great, however I am getting even more confused.

Here is the URL linking to the page in question, which I thought I posted. I might have done so in my last post that got muted.
www . thequeensmarketshop . com / vendors

Also the only two I am interested is if they are missing their email or socialMedia, not description, if that helps.

Thanks, in advance

@thequeensmarketshop you have errors in the code on your page that is preventing it from loading (this could also be an on going issue that you need to pay attention to).

If the Velo IDE has any red dots or red wiggly lines under text you need to figure out where your syntax error(s) are. See the attached image from the browser developer tools.

@veloninja

Thank you, thank you! I’ve been trying to figure out this for days (I am new to Javascript coding) and your code has fixed my problem! Thank you, thank you!!

No problem! You did it on your own! Congratulation!:wink: