(Free Rock Available) Hide field values in datatable based on boolean field

(This may sound weird and I hope this is allowed on this forum. But I work for a non-profit geological society and this is for our website we are re-launching. Anyone that is able to fix this issue, I will happily send a nice rock, mineral, or fossil specimen via mail as a token of our appreciation :slight_smile: :slight_smile: #geologistscantcode #butwedohaveotherskills)

I currently have a searchable database on my site that has member information. However, I have given members the ability to ā€œhideā€ certain fields like email, etc. with a boolean check on their submission form. I want to be able to display all the data fields unless the field ā€œhide_emailā€ is checked as true, at which point I would like for the email to either not display or display something such as ā€œnot availableā€. I’ve found ways to filter the entire row based on these boolean checks using code below but I’d like instead to only filter certain fields in a row, (i.e. ā€˜email’ using ā€˜hide_email’ boolean field) and not the entire row.

( $w ( ā€œ#dataset1ā€ ). setFilter ( wixData . filter (). eq ( ā€˜hide_in_search’ , Boolean ( false ))
);

Thanks!!

I think perhaps a visual of what is happening now vs. what you are trying to achieve could help community members here assist you. I’m having trouble figuring out what you want from the description…

Are you trying to hide a form field or a column in a table or something else?

Hi Amanda, Thanks for your response. I will try to explain better. The screenshot below shows an example of the table that I have searchable on the website. When members fill out this information, there is a boolean check that essentially says (hide_address), (hide_in_search_entirely) and (hide_email). This allows users to determine what sort of information they want available to the rest of our members. So for example, if the person in the first row of the table below, had checked yes to the boolean (hide_email) but not (hide_in_search_entirely), then I’d like for all of the rest of their fields to display except for email which I’d like to display as something generic such as ā€œnot availableā€ or ā€œnullā€ or even best just " ".
The boolean checks for these scenarios are saved in the table as Boolean(true) or Boolean(false). The code I have below shows an example for how I currently have the database filtered which essentially filters out any row that has any of the three Booleans checked. This works for the ā€œhide_in_search_entirelyā€ but is not correct for the other two, but is just what I’m having to do in the mean time to keep their email or address private.


import wixData from ā€˜wix-data’ ;
//datasetfilters need to be repeated under on ready search function in order to stay evergreen
$w . onReady ( function () {
$w ( ā€œ#dataset1ā€ ). onReady (() => {
$w ( ā€œ#dataset1ā€ ). setFilter ( wixData . filter (). eq ( ā€˜hide_in_search’ , false )
. and ( wixData . filter (). eq ( ā€˜hide_email’ , Boolean ( false )))
. and ( wixData . filter (). eq ( ā€˜hide_address’ , Boolean ( false ))))

$w . onReady ( function () {

//SEARCH BUTTON TRIGGER⚔ 
$w ( "#searchButton" ). onClick ( function  () { 
    search (); 
}); 

//ENTER KEY TRIGGER⚔ 
$w ( "#searchBar" ). onKeyPress ( function  ( event ) { 
    if  ( event . key  ===  "Enter" ) { 
        search (); 
    } 
}); 
$w ( "#searchBar2" ). onKeyPress ( function  ( event ) { 
    if  ( event . key  ===  "Enter" ) { 
        search (); 
    } 
}); 
//dropdown click trigger 
$w ( "#dropdown1" ). onClick ( function  () { 
    search (); 
}); 

//SEARCH FUNCTIONšŸš€ 
function  search () { 
    ////datafilters above need to be repeated here in order to stay evergreen 
    $w ( "#dataset1" ). onReady ( function  () { 
        $w ( "#dataset1" ). setFilter ( wixData . filter (). contains ( 'membership' ,  String ( $w ( '#dropdown1' ). value )) 
                . and ( wixData . filter (). contains ( "title" ,  String ( $w ( '#searchBar' ). value ))) 
                . and ( wixData . filter (). contains ( "lastName" ,  String ( $w ( '#searchBar2' ). value ))) 
                . and ( wixData . filter (). eq ( 'hide_in_search' ,  Boolean ( **false** ))) 
                . and ( wixData . filter (). eq ( 'hide_email' ,  Boolean ( **false** ))) 
                . and ( wixData . filter (). eq ( 'hide_address' ,  Boolean ( **false** )))) 
        $w ( "#clearFilter" ). show (); 
    }) 
} 


//CLEAR FILTER šŸš€ 
$w ( "#clearFilter" ). onClick ( function  () { 

    $w ( "#dropdown1" ). value  =  **undefined** ; 
    $w ( "#searchBar" ). value  =  **undefined** ; 
    $w ( "#searchBar2" ). value  =  **undefined** ; 
    $w ( "#clearFilter" ). hide (); 
    
    search () 

});}) 

})})

Ah, I see. You can definitely accomplish this but I’m not sure if you can in setFilter. I will test a few things later and get back to you as I have an idea but want to. make sure I am correct first.

In addition, to increase the security if users do not want their data shown at all I would recommend doing this logic in a backend (.jsw) file and only returning to the front end what site visitors should be allowed to see based on the booleans.

If you want to take a look at some docs in the meantime, I am thinking you will need to query the data in the collection on the backend, return to the front end and then build the table in code.

https://www.wix.com/velo/reference/wix-data/query

@amandam thank you! I’ll read up on these backend queries to see if I can get an understanding of how to do this.

@justin-anderson-12-0 Okay, here is some sample code that you can start with to work on your new table

If you are currently using a dataset in the editor ui to connect the collection, you will want to remove that.

backend .jsw file

const options = {
   "suppressAuth":true
}
export async function getRocksData(){
   try {
   let results = await wixData.query("BooleanTest").find(options);
        if(results.totalCount > 0){
           const filteredResults = results.items.map(item => {
               if(!item.showData){
                   console.log(item.sensitiveData)
                    item.sensitiveData = "Don't show me!"
                    return item
               }else{
                   return item
               }
           })

           return filteredResults
       }
   } catch(err) {
       console.log(err)
   }
   
 
}

and then in the page code…

import { getRocksData } from 'backend/callData'

$w.onReady(async function () {

    $w("#table1").columns = [
        {
 "id": "col1",
 "dataPath": "title", // matches field key from collection
 "label": "Rock",
 "width": 100,
 "visible": true,
 "type": "string",
        },
        {
 "id": "col2",
 "dataPath": "sensitiveData", // matches field key from collection
 "label": "Sensitive Data",
 "width": 100,
 "visible": true,
 "type": "string",
        }
    ];

    let data = await getRocksData();
 
    $w('#table1').rows = data
});

let me know if you have any questions about what is going on in this code.

Thank you! I won’t have time to try this until later this evening and might need some help implementing. I’ll reply here with questions.

Hi @amandam , trying to implement this now, can you tell me where/how the collection should be implemented into the code above? Would the collection ID be inserted for the ā€œBooleanTestā€?

Hello! Yes, in my case the collection ID was BooleanTest. Apologies for not linking the docs in my previous post which can help explain how to use Query and what the different options are

https://www.wix.com/velo/reference/wix-data/query

I think I have the backend code working now but can’t actually get the columns to display. All that is displayed is the sample data that comes with the table after it’s added to the page. The two columns I’m trying to display have field keys as ā€œtitleā€ and "email. Below is the entirety of the page code I currently have.

import { getRocksData } from ā€˜backend/callData’

$w . onReady ( async function () {

$w ( "#table1" ). columns  = [{ 
        "id" :  "col1" , 
        "dataPath" :  "title" ,  // matches field key from collection 
        "label" :  "Name" , 
        "width" :  100 , 
        "visible" :  **true** , 
        "type" :  "string" , 
    }, 
    { 
        "id" :  "col2" , 
        "dataPath" :  "email" ,  // matches field key from collection 
        "label" :  "Sensitive Data" , 
        "width" :  100 , 
        "visible" :  **true** , 
        "type" :  "string" , 
    } 
]; 

**let**  data  =  **await**  getRocksData (); 

$w ( '#table1' ). rows  =  data 

});

The backend data is saved in callData.js and looks like this:

import wixData from ā€˜wix-data’ ;

const options = {
ā€œsuppressAuthā€ : true
}
export async function getRocksData ( ) {
try {
let results = await wixData . query ( ā€œregistrationā€ ). find ( options );
if ( results . totalCount > 0 ) {
const filteredResults = results . items . map ( item => {
if (! item . showData ) {
console . log ( item . sensitiveData )
item . sensitiveData = ā€œDon’t show me!ā€
return item
} else {
return item
}
})

        **return**  filteredResults 
    } 
}  **catch**  ( err ) { 
    console . log ( err ) 
} 

}

Two things I would check…

console.log(data) and see if you are getting anything in the front end.

NExt I would check that your element id’s are correct, any column names ids are correct and so on. If you are still having trouble debugging, drop your link and I can look.

ok fixed that part, I had the code saved as a .js and not a .jsw. now I’m just having issues actually understanding the backend code and what/how data is actually being filtered. can you help me understand the portion of the backend code below?

let results = await wixData . query ( ā€œregistrationā€ ). find ( options );
if ( results . totalCount > 0 ) {
const filteredResults = results . items . map ( item => {
if (! item . showData ) {
console . log ( item . sensitiveData )
item . sensitiveData = ā€œDon’t show me!ā€
return item
} else {
return item

Sure!

So your first line is querying your ā€œregistrationā€ collection and passing in the options of suppressAuth = true (suppressAuth can be used in the backend on collections where you have set the permissions to Admin so that no one malicious can access anything from the FE, but you can still query and override as needed in the BE)

Next - you are checking that your query actually returned results
then, you are checking your boolean field to see if it is false (! is the not operator in js)
if ā€œshowDataā€ is NOT checked, you are then changing your ā€œsensitiveDataā€ field to show some dummy text instead of the sensitive data you do not want to reveal
then you are returning the updated item in the array with the modification

in your case showData should be the id of your boolean field
and sensitiveData is likely called Email or whatever it is you don’t want to show to users on the FE dependent on the boolean

Does this help?

This is so helpful and I think it works now :slight_smile: :slight_smile: Let me double check and get back to you. Thank you so much

Yes this works. Since it’s safer to do this filter on the back end, is it possible for me to filter an entire row using a similar Boolean check for those that want to be left out of the directory entirely?

@AmandaM Since it’s safer to do this filter on the back end, is it possible for me to filter an entire row using a similar Boolean check for those that want to be left out of the directory entirely? p.s. I was totally serious about delivering a rock/mineral/fossil so if you have a safe place for me to send one let me know where :slight_smile:

I’m also having trouble get my search functions to work now on the front end that I don’t have the dataset there. Any suggestions there would be helpful:

here is my webpage link: https://www.dgs.org/membership-directory-coded

here is my current front end code:

import { getRocksData } from ā€˜backend/callData’ ;

$w . onReady ( async function () {

$w ( "#table1" ). columns  = [{ 
        "id" :  "col1" , 
        "dataPath" :  "title" ,  // matches field key from collection 
        "label" :  "Name" , 
        "width" :  100 , 
        "visible" :  **true** , 
        "type" :  "Text" , 
    }, 
     { 
        "id" :  "col2" , 
        "dataPath" :  "lastName" ,  // matches field key from collection 
        "label" :  "Last Name" , 
        "width" :  100 , 
        "visible" :  **true** , 
        "type" :  "Text" , 
    },  
    { 
        "id" :  "col3" , 
        "dataPath" :  "email" ,  // matches field key from collection 
        "label" :  "Email" , 
        "width" :  100 , 
        "visible" :  **true** , 
        "type" :  "Text" , 
    }, 
    { 
        "id" :  "col4" , 
        "dataPath" :  "address" ,  // matches field key from collection 
        "label" :  "Address" , 
        "width" :  100 , 
        "visible" :  **true** , 
        "type" :  "Text" , 
    } 
]; 

//SEARCH BUTTON TRIGGER
$w ( ā€œ#searchButtonā€ ). onClick ( function () {
search ();
});

//ENTER KEY TRIGGER 
$w ( "#searchBar" ). onKeyPress ( function  ( event ) { 
    if  ( event . key  ===  "Enter" ) { 
        search (); 
    } 
}); 
$w ( "#searchBar2" ). onKeyPress ( function  ( event ) { 
    if  ( event . key  ===  "Enter" ) { 
        search (); 
    } 
}); 
//dropdown click trigger 
$w ( "#dropdown1" ). onClick ( function  () { 
    search (); 
}); 

//SEARCH FUNCTION 
function  search () { 
    $w ( data ). onReady ( function  () { 
        $w ( data ). setFilter ( data . filter (). contains ( 'membership' ,  String ( $w ( '#dropdown1' ). value )) 
                . and ( data . filter (). contains ( "title" ,  String ( $w ( '#searchBar' ). value ))) 
                . and ( data . filter (). contains ( "lastName" ,  String ( $w ( '#searchBar2' ). value ))) 
                . and ( data . filter (). eq ( 'hide_in_search' ,  Boolean ( **false** )))) 
        $w ( "#clearFilter" ). show (); 
    }) 
} 


//CLEAR FILTER  
$w ( "#clearFilter" ). onClick ( function  () { 

    $w ( "#dropdown1" ). value  =  **undefined** ; 
    $w ( "#searchBar" ). value  =  **undefined** ; 
    $w ( "#searchBar2" ). value  =  **undefined** ; 
    $w ( "#clearFilter" ). hide (); 
    
    search () 

}); 

let  data  =  **await**  getRocksData  () 

$w ( '#table1' ). rows  =  data 

})