Dynamic handler read only fields are editable again after refresh

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • onepoint0
    Member
    • Jul 2023
    • 41

    Dynamic handler read only fields are editable again after refresh

    Hi Devs,

    I have a use case where I need to let the user edit fields and then depending on some conditions, the fields are set to read only. I've set it up in a dynamic handler but I've found that if I refresh the entire page using the browser refresh button, all the fields that are supposed to be read-only revert back to being editable even though the dynamic handler code is rerunning.

    My code is much more complex than this but I've created the simplest possible example to test it using an entity with just two fields.

    My entity:

    Code:
    {
        "fields": {
            "name": {
                "type": "varchar",
                "required": true,
                "pattern": "$noBadCharacters"
            },
            "description": {
                "type": "text"
            },
            "createdAt": {
                "type": "datetime",
                "readOnly": true
            },
            "modifiedAt": {
                "type": "datetime",
                "readOnly": true
            },
            "createdBy": {
                "type": "link",
                "readOnly": true,
                "view": "views/fields/user"
            },
            "modifiedBy": {
                "type": "link",
                "readOnly": true,
                "view": "views/fields/user"
            },
            "assignedUser": {
                "type": "link",
                "required": false,
                "view": "views/fields/assigned-user"
            },
            "teams": {
                "type": "linkMultiple",
                "view": "views/fields/teams"
            },
            "readOnly": {
                "type": "varchar",
                "maxLength": 150,
                "options": [],
                "isCustom": true
            }
        },
        "links": {
            "createdBy": {
                "type": "belongsTo",
                "entity": "User"
            },
            "modifiedBy": {
                "type": "belongsTo",
                "entity": "User"
            },
            "assignedUser": {
                "type": "belongsTo",
                "entity": "User"
            },
            "teams": {
                "type": "hasMany",
                "entity": "Team",
                "relationName": "entityTeam",
                "layoutRelationshipsDisabled": true
            }
        },
        "collection": {
            "orderBy": "createdAt",
            "order": "desc"
        },
        "indexes": {
            "name": {
                "columns": [
                    "name",
                    "deleted"
                ]
            },
            "assignedUser": {
                "columns": [
                    "assignedUserId",
                    "deleted"
                ]
            },
            "createdAt": {
                "columns": [
                    "createdAt"
                ]
            },
            "createdAtId": {
                "unique": true,
                "columns": [
                    "createdAt",
                    "id"
                ]
            }
        }
    }​
    ClientDefs:

    Code:
    {
        "controller": "controllers/record",
        "boolFilterList": [
            "onlyMy"
        ],
        "dynamicHandler": "custom:dynhand"
    }​
    And a dynamic handler:

    Code:
    define('custom:dynhand', ['dynamic-handler'], function (Dep) {
        return Dep.extend({
            // called on initialization
            init: function () {
                console.log(`set read only`);
                this.recordView.setFieldReadOnly('readOnly');
                console.log(`after set read only`);
            }
        });
    });​​
    When I run a php rebuild.php this works properly and sets the readOnly field to readonly. But if I refresh the page in the browser, the dynamic handler runs (I can see the logging in the console) but the readOnly field is editable again.

    Am I doing something wrong?

    I am on version 7.5.5 of Espo.

    Cheers,
    Clare
  • yuri
    Member
    • Mar 2014
    • 8471

    #2
    I Clare,

    I checked on v8.2. There was no this problem. Maybe consider upgrading. Not sure what is the cause.
    If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

    Comment

    • yuri
      Member
      • Mar 2014
      • 8471

      #3
      If you want to make the field read-only completely, you can pass true in the second parameter.
      If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

      Comment

      • onepoint0
        Member
        • Jul 2023
        • 41

        #4
        Thanks Yuri,

        I tried on 8.2 and it's working fine, but I'm getting another problem.

        I'm calling this.getMetadata() from an action handler to conditionally show dropdown buttons.

        It's giving me an error "Uncaught (in promise) TypeError: this.getMetadata is not a function​"

        My code is like this where showProdComplete is a checkVisibilityFunction.

        Code:
            "detailActionList": [
                "__APPEND__",
                {
                    "label": "Production Complete",
                    "name": "productionComplete",
                    "acl": "edit",
                    "data": {
                        "handler": "custom:handlers/mmx-lite-production-complete"
                    },
                    "checkVisibilityFunction": "showProdComplete"
                },​
        The let "productionAtts = " line is failing:

        Code:
        define('custom:handlers/mmx-lite-production-complete', ['action-handler'], function (Dep) {
        
          return Dep.extend({
        
            actionProductionComplete: function (data, e) {​
                // some stuff to lock production
            },
        
            showProdComplete:  function() {
              console.log(`show prod complete `,this);
        
              let productionAtts =  this.getMetadata().get('entityDefs.MmxLite.mmxFieldConfigurations.stages.production.mandatory');
        
              let attsSet =  !(productionAtts.some(l => !this.view.model.get(l)));
        
              return (!this.view.model.get('productionLocked') && attsSet);
            }
          });
        });​
        It worked fine in version 7. I can't find any info in the docs to say that it has changed. Should I be using something else?

        Cheers,
        Clare
        Last edited by onepoint0; 04-11-2024, 02:05 AM.

        Comment

        • onepoint0
          Member
          • Jul 2023
          • 41

          #5
          Actually scratch that - it works using this.view:

          Code:
          this.view.getMetadata().get(' ... ');
          ​​

          Comment

          Working...