diff --git a/package-lock.json b/package-lock.json index 4a9606f..45e0ede 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@gisce/ooui", - "version": "0.22.5", + "version": "0.22.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@gisce/ooui", - "version": "0.22.5", + "version": "0.22.6", "dependencies": { "html-entities": "^2.3.3", "moment": "^2.29.3" diff --git a/package.json b/package.json index 889cfcc..510b31b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gisce/ooui", - "version": "0.22.5", + "version": "0.22.6", "main": "./dist/ooui.umd.js", "module": "./dist/ooui.es.js", "types": "./dist/index.d.ts", diff --git a/src/Form.ts b/src/Form.ts index d81ddd6..f30c991 100644 --- a/src/Form.ts +++ b/src/Form.ts @@ -9,6 +9,7 @@ import { parseContext } from "./helpers/contextParser"; import { parseOnChange } from "./helpers/onChangeParser"; import * as txml from "txml"; import Field from "./Field"; +import Button from "./Button"; export type FormParseOptions = { readOnly?: boolean; @@ -177,6 +178,7 @@ class Form { tagAttributes, values, fields: this._fields, + widgetType: tagName, }); let evaluatedStateAttributes; @@ -241,8 +243,15 @@ class Form { }); } - // If the form is set to readonly, reflect it to its children - widget.readOnly = widget.readOnly || this.readOnly; + // If the widget is a button and has a readonly attribute specified + // reflect it to the widget independently of the form readonly attribute + if (widget instanceof Button && widget.readOnly !== undefined) { + // widget.readOnly = widget.readOnly; + } else { + // If the form is set to readonly, reflect it to its children + widget.readOnly = widget.readOnly || this.readOnly; + } + container.addWidget(widget); }); } diff --git a/src/Widget.ts b/src/Widget.ts index 5d11c26..53a7c13 100644 --- a/src/Widget.ts +++ b/src/Widget.ts @@ -11,13 +11,13 @@ abstract class Widget { } /** - * Determines if widget is read only (default is false) + * Determines if widget is read only (default is undefined) */ - _readOnly: boolean; - get readOnly(): boolean { + _readOnly: boolean | undefined; + get readOnly(): boolean | undefined { return this._readOnly; } - set readOnly(value: boolean) { + set readOnly(value: boolean | undefined) { this._readOnly = value; } @@ -97,20 +97,25 @@ abstract class Widget { constructor(props?: any) { this._colspan = Widget._defaultColspan; - this._readOnly = false; this._invisible = false; if (props) { if (props.colspan) { this._colspan = +props.colspan; } - if (props.readonly) { + if (props.readonly !== undefined) { if ( props.readonly === "1" || props.readonly === 1 || props.readonly === true ) { this._readOnly = true; + } else if ( + props.readonly === "0" || + props.readonly === 0 || + props.readonly === false + ) { + this._readOnly = false; } } if (props.invisible) { diff --git a/src/helpers/attributeParser.ts b/src/helpers/attributeParser.ts index d175bcb..a01b566 100644 --- a/src/helpers/attributeParser.ts +++ b/src/helpers/attributeParser.ts @@ -93,10 +93,12 @@ const parseAttributes = ({ attrs, values, fields, + widgetType, }: { attrs: string; values: any; fields: any; + widgetType?: string; }) => { const leftP = attrs.replace(/\(/g, "["); const rightP = leftP.replace(/\)/g, "]"); @@ -116,6 +118,13 @@ const parseAttributes = ({ if (attrIsTrue) { newAttributes[attrField] = true; + } else if ( + attrField === "readonly" && + !attrIsTrue && + widgetType === "button" + ) { + // Buttons with readonly false will have to override the default readonly + newAttributes[attrField] = false; } } @@ -126,16 +135,19 @@ const evaluateAttributes = ({ tagAttributes, values, fields, + widgetType, }: { tagAttributes: any; values: any; fields: any; + widgetType?: string; }) => { const newTagAttributes = tagAttributes.attrs ? parseAttributes({ attrs: tagAttributes.attrs, values, fields, + widgetType, }) : {}; diff --git a/src/spec/Form.spec.ts b/src/spec/Form.spec.ts index 49b76dc..be22b95 100644 --- a/src/spec/Form.spec.ts +++ b/src/spec/Form.spec.ts @@ -3217,4 +3217,45 @@ describe("A Form", () => { "[('tarifes_atr_compatibles', '=', tarifa), ('type', '=', 'sale')]" ); }); + it("Should be able to parse a specifically enabled button even though in the form is disabled", () => { + const arch = `
`; + const form = new Form({}); + form.parse(arch, { + readOnly: true, + values: {}, + }); + const buttonWidget = form.findById("example_button") as Button; + expect(buttonWidget.readOnly).toBeFalsy(); + }); + it("Should be able to parse a specifically enabled button even though in the form is disabled, with attrs", () => { + const arch = ``; + const form = new Form({ + state: { + selection: [ + ["esborrany", "Esborrany"], + ["actiu", "Actiu"], + ["pendent", "Pendent d'activació"], + ["baixa", "Baixa"], + ["baixa2", "Baixa per modificació"], + ["baixa3", "Baixa per renovació"], + ["baixa4", "Baixa per nova pòlissa"], + ], + string: "Estat", + type: "selection", + views: {}, + }, + }); + form.parse(arch, { + readOnly: true, + values: { + state: "actiu", + }, + }); + const buttonWidget = form.findById("example_button") as Button; + expect(buttonWidget.readOnly).toBeFalsy(); + }); }); diff --git a/src/spec/Widget.spec.ts b/src/spec/Widget.spec.ts index ce006a5..f7b9877 100644 --- a/src/spec/Widget.spec.ts +++ b/src/spec/Widget.spec.ts @@ -20,10 +20,10 @@ describe('A Widget', () => { expect(widget.colspan).toBe(3); }); - it('should be readOnly false by default', () => { + it('should be undefined by default', () => { const widget = new WidgetImpl(); - expect(widget.readOnly).toBe(false); + expect(widget.readOnly).toBeUndefined(); }); it('colspan should be of type Number', () => {