{"revision":"c10276e953456835cdbb1f3a60d58ae1980be353","document":{"id":31732,"path":"it-service-management/change-management/change-model-attribute-apis.md","title":"Change model attribute API methods","bundle":null,"doc_type":null,"release":"australia","body":"\n# Change model attribute API methods\n\nUse these server-side and client-side methods to check which change model attributes are present for a change request in its current state.\n\n## Server-side methods\n\nThe ChangeRequest API provides these methods for use in business rules, UI actions, and other server-side scripts.\n\n|Method|Description|\n|------|-----------|\n|hasStateAttribute|Returns `true` if the attribute with the specified name is assigned to the current state of the change request.|\n|modelContainsAttribute\\(name\\)|Returns true if the attribute with the specified name is contained anywhere in the model. Useful when introducing an attribute and you want to preserve existing behavior for models without the attribute.|\n\n## Server-side example\n\nThe following example loads a change request and checks its state attributes.\n\n```javascript\nvar changeGr = new GlideRecord(\"change_request\");\nchangeGr.get(\"<sys_id>\");\n\nvar changeRequest = new ChangeRequest(changeGr);\ngs.info(changeRequest.getStateAttributes());\ngs.info(changeRequest.hasStateAttribute(\"allow_ci_modification\"));\n```\n\nFor a change request in a state that has both attributes, the output includes both attribute names and `true` for each attribute.\n\n## Client-side methods\n\nA client-side Change Model object is available on the Change Request form for client scripts.\n\n|Method|Description|\n|------|-----------|\n|hasStateAttribute\\(name\\)|Returns true if the attribute with the specified name is assigned to the current state of the change request.|\n|containsAttribute\\(name\\)|Returns true if the attribute with the specified name is contained anywhere in the model. Useful when introducing an attribute and you want to preserve existing behavior for models without the attribute.|\n\nThe functions can be found in the change\\_model object on the scratchpad.\n\n## Example: Enforce the Allow CI Modification attribute\n\nThe base system enforces the Allow CI Modification attribute with a client script and a business rule that use these methods. Together, they keep the original CI modification behavior for models that don't use the attribute and apply the attribute for models that do. You can follow the same pattern to add support for a custom attribute.\n\n**Client script: Change model: Read only CI**\n\nThis client script makes the **Configuration item** field read-only unless the current state has the Allow CI Modification attribute. If no state in the model has the attribute, the field stays editable in the initial state only. The script runs when the value of the **State** field changes, so the form always matches the change model.\n\n```javascript\nfunction onChange(control, oldValue, newValue, isLoading, isTemplate) {\n    var ALLOW_CI_MODIFICATION = \"allow_ci_modification\";\n\n    // Retrieve the Change Model API and data from the scratchpad\n    if (!g_scratchpad.change_model)\n        return;\n\n    var model = g_scratchpad.change_model;\n\n    // Check if the field should be read only based on if the model contains the state and if the \"allow_ci_modification\" attribute has been added to the state\n    var isReadOnly = model.containsAttribute(ALLOW_CI_MODIFICATION) ?\n            !model.hasStateAttribute(ALLOW_CI_MODIFICATION) : g_form.getValue(model.field) + \"\" !== model.initial_state;\n\n    g_form.setReadOnly(\"cmdb_ci\", isReadOnly);\n}\n```\n\n**Business rule: Change Model: Read only CI**\n\nThis business rule prevents changes to the configuration item on a change request unless the current or previous state has the Allow CI Modification attribute. If no state in the model has the attribute, the configuration item can still change in the initial state. The business rule runs when the configuration item changes on a change request that has a change model.\n\n```javascript\n(function executeRule(current, previous /*null when async*/) {\n    var ALLOW_CI_MODIFICATION = \"allow_ci_modification\";\n\n    var changeRequest = new ChangeRequest(current);\n    var preChangeRequest = new ChangeRequest(previous);\n    var modelContainsAttribute = changeRequest.modelContainsAttribute(ALLOW_CI_MODIFICATION);\n\n    // If the attribute isn't enabled preserve original 'initial state' CI changes\n    if (!modelContainsAttribute && (changeRequest.isInitialState() || prevChangeRequest.isInitialState()))\n        return;\n\n    // If the current state has the attribute allow the CI to be modified\n    if (changeRequest.hasStateAttribute(ALLOW_CI_MODIFICATION))\n        return;\n\n    // If the previous state has the attribute also allow the CI to be modified\n    if (new ChangeRequest(previous).hasStateAttribute(ALLOW_CI_MODIFICATION))\n        return;\n\n    // Otherwise, if it's a new record (no previous record) use the model to lookup the attribute on the intial state\n    var changeModel = new ChangeModel(new ChangeRequest(current).getModel());\n    if (current.isNewRecord() && changeModel.hasStateAttribute(changeRequest.getInitialState(), ALLOW_CI_MODIFICATION))\n        return;\n\n    // Abort the modification\n    gs.addErrorMessage(gs.getMessage(\"Configuration item cannot change for Change Requests in this state\"));\n    current.setAbortAction(true);\n})(current, previous);\n```\n\n**Parent Topic:**[Change model attributes](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/it-service-management/change-management/change-model-attributes.md)\n\n"}}