Hide form block based on parameters from listed record

Thank you guys for your prompt help.

I tried both approaches Arthur’s and Julien’s they both work perfect.

Right now I need to fetch fields from the record that shouldn’t be visible to public , so I can not rely on the rendered divs and html, but rather in the fields from record.

Also as Julien suggested I am concatenating all emails that should access the form into one field named ‘validEmails’ and making use of the includes() method I will validate a wider access to the form.

This script, opens several possibilities inside my softr app; lets say an admin user can manage up to 5 businesses, now admin can securely add collaborators to help him manage any of his businesses.
AMAZING!

I can’t wait to showcase this app, but for now is work in progress. (77% ready).

1 Like

Hey @Julien_Berawen (and @artur) - I have a follow up on this if you guys wouldn’t mind weighing in.

I’m in the middle of putting a portal together and I used this method earlier in the week on a different page to hide a few sections based on whether or not the user belonged to a particular program (a profile type page but viewed not as the logged in user) and it’s working great.

I’m now putting together another list details page that has several elements that I’d like to show or hide based on a set of rules that involve attributes from the record. I started with an identical scenario to the one that I already have working (hide if value is “-” - reads a checkbox field from airtable) using both the solution here form Julien and the alternate from Artur and neither one are working out.

This is what I have:

<script>
   document.addEventListener("DOMContentLoaded", function() {    
        var waitForData = setInterval(function () {
            if (typeof $ != 'undefined') {
                if (document.querySelectorAll('div[data-mappedto="Allow Reschedule"][data-value = "-" i]').length > 0) {

                    var schSession = document.getElementById('schedule-session');
                    var reschSession = document.getElementById('reschedule-session');

                    schSession.style.display = 'none';
                    reschSession.style.display = 'none';

                    clearInterval(waitForData);
                }
            }
        }, 100);
    });
</script>

Similarly, this also did not work -

<script>    
    document.addEventListener("DOMContentLoaded", function() {    
        var waitForData = setInterval(function () {
            if (typeof $ != 'undefined') {
                const recordId = getUrlParam('recordId');
                if (window.records && window.records[recordId] && window.records[recordId].record.fields['Allow Reschedule'] === '-') {
                    
			    	var scheduleButton = document.getElementById('schedule-session');
				    var rescheduleButton = document.getElementById('reschedule-session');
                    scheduleButton.style.display = 'none';
                    rescheduleButton.style.display = 'none';

                    
                    clearInterval(waitForData);
                }
            }
        }, 100);

        function getUrlParam(name) {
            const url = new URL(window.location.href);
            let param;
            for(var key of url.searchParams.keys()) {
                if(key.toLowerCase() === name.toLowerCase()) {
                param = url.searchParams.get(name);
                break;
                }
            }
        
            if(!param && name.toLowerCase() === 'recordid') {
                param = getRecordIdFromPath();
            }
            return param;
        }
        
        function getRecordIdFromPath() {
            let pathName = window.location.pathname;
            if (pathName.indexOf('/r/rec') !== -1) {
                pathName = pathName.substr(pathName.indexOf('/r/rec') + 3);
                if (pathName.indexOf("/") !== -1) {
                pathName = pathName(0, pathName.indexOf('/'))
                }
                return pathName;
            }
            return undefined;
        }
    });
</script>

While I’m testing, I have the values it needs to read (this one and a few others I’ll use when I figure out what is wrong here hah) in details block at the bottom of the page fully visible:

Definitely stumped here :sweat_smile: the ability to do this is kind of central to the brief :smiley: When I tested it on that other page and it worked fine I got excited.

Any ideas? I’m going to keep tinkering but any insight would be most helpful <3

Hi @bryan.stafford, I can’t speak for @artur 's snippet, I let him answer himself, but as for mine, I think the issue probably lies with the fact that Softr’s recent updates to blocks have impacted the DOM’s structure for the sites, and the objects no longer bear the “mapped to” data attribute, hence rendering that version of the selector obsolete.

If you can provide a screenshot of the source code of your page at the point where your condition sits, I could try to give you an updated version for the selector. But Artur’s solution might still be more resistant to such changes in the future.

@Julien_Berawen Thank you so much! That’s such a kind offer and I appreciate it greatly and appreciate the quick response.

I did end up getting @artur’s method to work. What’s strange is that the issue was actually that the field itself was not loading as part of the record object. I dropped a console.log in there so that I could monitor it and all of my fields except the one I was targeting were loading. I tried all sorts of weird things to try and get it to show up, but finally just deleted the field and remade it and just like that everything works :sweat_smile: Luckily since this is still a developmental build, I have a little flexibility with base changes without a deletion propagating through layers of automation etc.

To your point, though, I think I am going to swap the other implementation to the record method so that it’s not reliant on the DOM. I have a modest amount of css changes on some of my pages that I’m worried won’t stick if I’m updating blocks and such :joy:

Anyway, I digress - Thanks again for responding to the tag I really do appreciate it :face_holding_back_tears::purple_heart:

2 Likes

this works perfectly today for us :pray:

1 Like

Hi @artur tks v much for this (which I was pointed to by @Julien_Berawen) - we’ll definitely give it a bash. Is there a style.display value that would change a block from ‘not visible’ to ‘visible.’ - ie the opposite of what you have here? We would like to hide or display header blocks (with specific user logos in them) based on record data, not user data…

Sure you can use

myElement.style.display = 'none'; // to hide

myElement.style.display = 'block'; // to unhide

You need to identify the myElement as in other examples.

Please keep in mind this is not a security measure if the data needs to be not shown at all user visibility rules or conditional filters.

V many thanks @artur (apols, previously replied in different thread)! This is already proving very useful.

Would it be straightforward to store the name of a block - or possibly a block ID - in our Airtable record and then display/hide the block of that name/id? IE instead of:
var form1 = document.getElementById(‘submissionseries’);
form1.style.display = ‘none’;
…something like this logic - excuse syntax as I’m not a programmer!
var formname = window.records[recordId].record.fields[‘formname’]
var form1 = document.getElementById(formname);
form1.style.display = ‘none’;
That would be a huge bonus for us!

Thanks for the solution @artur , it is great!

I’m trying to figure out how to take it a bit further and struggle getting my case to work:

I’m currently working on a step-by-step user journey. For that, I want to check if the User has already submitted a Category (Step 1) , an Image (Step 2) and a Date (Step 3) for a certain record and hide/show/ render elements on the page accordingly. The progress is indicated by Airtable fields that are either true or false.

Basically:

  • If Category is submitted, hide the Button for the Form and change the Text to “Category submitted!”
  • If Image is submitted, hide the Button for the Form and change the Text to “Image submitted!”
  • If Date is submitted, hide the Button for the Form and change the Text to “Date submitted!”

I have 1 If- statement for each of the conditions that will render the matching parts of the page. Each one of them works fine, but when I try to combine them and have them all running, it will always only run 1 or two of them.

So if all 3 conditions are true, it will for example either show only the renderings for Category and Image Items or only for the Date Items. That changes randomly when I refresh the page.

It may be because it is a bit of a crappy solution as I’m not very versed in coding and just tried to make it work :sweat_smile:

This is what I have right now:

<script>    
    document.addEventListener("DOMContentLoaded", function() {    
        var waitForData = setInterval(function () {
    if (typeof $ != 'undefined') {
           const recordId = getUrlParam('recordId');
        if (window.records && window.records[recordId] && window.records[recordId].record.fields['category_submitted'] === 'true') {
                    
            var buttonCategory = document.querySelector("#form-category > section > div > div > div.sw-js-single-item-elements.MuiBox-root.css-i9gxme > div > div > div.css-j7qwjs > div > button");
            var headingCategory = document.querySelector("#form-category > section > div > div > div.container.list-heading.css-1fhroz6");
            buttonCategory.style.display = 'none';
            headingCategory.innerText = 'Kategorie und Tags hinzugefügt!';
        
        clearInterval(waitForData);
            
        }
    }
}, 100);

    var waitForData = setInterval(function () {
    if (typeof $ != 'undefined') {
           const recordId = getUrlParam('recordId'); 
        if (window.records && window.records[recordId] && window.records[recordId].record.fields['image_submitted'] === 'true') {
                    
            var buttonImage = document.querySelector("#form-image > section > div > div > div.sw-js-single-item-elements.MuiBox-root.css-i9gxme > div > div > div.css-j7qwjs > div > button");
            var headingImage = document.querySelector("#form-image > section > div > div > div.container.list-heading.css-1fhroz6");
            buttonImage.style.display = 'none';
            headingImage.innerText = 'Bild hinzugefügt!';
            
        clearInterval(waitForData);
            
        }
    }
}, 100);

    var waitForData = setInterval(function () {
    if (typeof $ != 'undefined') {
           const recordId = getUrlParam('recordId'); 
        
        if (window.records && window.records[recordId] && window.records[recordId].record.fields['date_submitted'] === 'true') {
                    
            var buttonDate = document.querySelector("#form-date > section > div > div > div.sw-js-single-item-elements.MuiBox-root.css-i9gxme > div > div > div.css-j7qwjs > div > button");
            var headingDate = document.querySelector("#form-date > section > div > div > div.container.list-heading.css-1fhroz6");
            buttonDate.style.display = 'none';
            headingDate.innerText = 'Datum hinzugefügt!';
        
        clearInterval(waitForData);
            
        }
    }
}, 100);        

        function getUrlParam(name) {
            const url = new URL(window.location.href);
            let param;
            for(var key of url.searchParams.keys()) {
                if(key.toLowerCase() === name.toLowerCase()) {
                param = url.searchParams.get(name);
                break;
                }
            }
        
            if(!param && name.toLowerCase() === 'recordid') {
                param = getRecordIdFromPath();
            }
            return param;
        }
        
        function getRecordIdFromPath() {
            let pathName = window.location.pathname;
            if (pathName.indexOf('/r/rec') !== -1) {
                pathName = pathName.substr(pathName.indexOf('/r/rec') + 3);
                if (pathName.indexOf("/") !== -1) {
                pathName = pathName(0, pathName.indexOf('/'))
                }
                return pathName;
            }
            return undefined;
        }
    });
</script>

It would be great if someone who is more skilled could provide me with feedback or a solution! :pray:

@artur , in your post of the code from Oct 22, where would I stick the Form ID or the Block ID of the block that I need to conditionally hide? Thanks!

I am trying to hide the detail block based on the value of the field in a record retrieved by the block on the record detail page.

@artur does this solution still work? I’ve tried adapting it for my use case, as per below, but it doesn’t seem to have any effect. And, following the thread, I’ve tried it both with and without the trigger field (FeedbackIDs) visible to the user.

<script>    
    document.addEventListener("DOMContentLoaded", function() {    
        var waitForData = setInterval(function () {
            if (typeof $ != 'undefined') {
                const recordId = getUrlParam('recordId');
                if (window.records && window.records[recordId] && window.records[recordId].record.fields['FeedbackIDs'] === '{LOGGED_IN_USER:ID}') {
                    
                    var form1 = document.getElementById('cta3');
                    form1.style.display = 'none';

                    clearInterval(waitForData);
                }
            }
        }, 100);

        function getUrlParam(name) {
            const url = new URL(window.location.href);
            let param;
            for(var key of url.searchParams.keys()) {
                if(key.toLowerCase() === name.toLowerCase()) {
                param = url.searchParams.get(name);
                break;
                }
            }
        
            if(!param && name.toLowerCase() === 'recordid') {
                param = getRecordIdFromPath();
            }
            return param;
        }
        
        function getRecordIdFromPath() {
            let pathName = window.location.pathname;
            if (pathName.indexOf('/r/rec') !== -1) {
                pathName = pathName.substr(pathName.indexOf('/r/rec') + 3);
                if (pathName.indexOf("/") !== -1) {
                pathName = pathName(0, pathName.indexOf('/'))
                }
                return pathName;
            }
            return undefined;
        }
    });
</script>