powerpagestoolkit 2.7.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -142,76 +142,113 @@ node.on("click", function (e) {
142
142
  ...
143
143
  ```
144
144
 
145
- ##### Visibility Control
145
+ ##### Business Rule Application
146
146
 
147
- ```typescript
148
- // Basic visibility
149
- node.hide();
150
- node.show();
151
- ```
147
+ This utility provides a flexible way to dynamically control field visibility, requirement status, values, and enabled states based on dependencies within PowerPages forms.
152
148
 
153
- **_Advanced conditional rendering_**
149
+ _Method Signature:_
154
150
 
155
- Out of the box, Microsoft does not provide PowerPages developers the ability to hide or show fields or form elements based on the value of another field. This method allows such configurations
151
+ ```typescript
152
+ applyBusinessRule(
153
+ rule: IBusinessRule,
154
+ dependencies: DOMNodeReference[]
155
+ ): DOMNodeReference; /* Instance of this is returned for optional
156
+ method chaining */
157
+ ```
156
158
 
157
- _Method signature:_
159
+ **BusinessRule Definition**
158
160
 
159
161
  ```typescript
160
- configureConditionalRendering(
161
- condition: () => boolean,
162
- dependencies?: DOMNodeReference[],
163
- clearValuesOnHide: boolean = true
164
- ): DOMNodeReference /* Instance of this returned
165
- for optional method chaining */
162
+ interface IBusinessRule {
163
+ setVisibility?: [
164
+ condition: () => boolean,
165
+ clearValuesOnHide?: boolean = true
166
+ ];
167
+ setRequired?: [
168
+ isRequired: () => boolean,
169
+ isValid: () => boolean
170
+ ];
171
+ setValue?: [
172
+ condition: () => boolean,
173
+ value: () => any | any
174
+ ];
175
+ setDisabled?: () => boolean;
176
+ }
166
177
  ```
167
178
 
168
- _Example implementation:_
179
+ ##### Visibility Control
169
180
 
170
181
  ```typescript
171
- node.configureConditionalRendering(
172
- function () // Function to evaluate wether this node should be visible or not
182
+ // Show the 'taxIdField' only when
183
+ // 'businessTypeField' is set to 'Corporation' or 'LLC'
184
+ taxIdField.applyBusinessRule(
173
185
  {
174
- return otherNode.value === "some value";
186
+ setVisibility: [
187
+ () =>
188
+ businessTypeField.value === "Corporation" ||
189
+ businessTypeField.value === "LLC",
190
+ ],
175
191
  },
176
- [otherNode] /* Dependency array | if the values or visibility of these
177
- change, the function is re-evaluated */,
192
+ [businessTypeField] // Re-evaluate when businessTypeField changes
193
+ );
178
194
 
179
- true /* should the values in the targeted elements (this.element)
180
- be cleared if this node is hidden? Default = true */
195
+ // Optionally disable 'clearValuesOnHide:
196
+ taxIdField.applyBusinessRule(
197
+ {
198
+ setVisibility: [
199
+ () =>
200
+ businessTypeField.value === "Corporation" ||
201
+ businessTypeField.value === "LLC",
202
+ false, // defaults to true. False will prevent the fields from losing it's value if it is hidden
203
+ ],
204
+ },
205
+ [businessTypeField] // Re-evaluate when businessTypeField changes
181
206
  );
182
207
  ```
183
208
 
184
209
  ##### Validation and Requirements
185
210
 
186
- This utility enhances PowerPages forms by adding dynamic field validation and conditional requirements based on other field values.
187
-
188
- _Method signature:_
189
-
190
211
  ```typescript
191
- configureValidationAndRequirements(
192
- isRequired: () => boolean,
193
- isValid: () => boolean,
194
- fieldDisplayName: string,
195
- dependencies: DOMNodeReference[]
196
- ): DOMNodeReference; /* instance of this is returned for optional
197
- method chaining */
212
+ // Require 'taxIdField' when 'businessTypeField' is 'Corporation' or 'LLC'
213
+ taxIdField.applyBusinessRule(
214
+ {
215
+ setRequired: [
216
+ function () {
217
+ return (
218
+ businessTypeField.value === "Corporation" ||
219
+ businessTypeField.value === "LLC"
220
+ );
221
+ },
222
+ function () {
223
+ return this.value != null && this.value !== "";
224
+ },
225
+ ],
226
+ },
227
+ [businessTypeField] // Revalidate when businessTypeField changes
228
+ );
198
229
  ```
199
230
 
200
- _Example implementation:_
231
+ ##### Setting Field Values Conditionally
201
232
 
202
233
  ```typescript
203
- node.configureValidationAndRequirements(
204
- // Make field required only when "Yes" is checked
205
- () => dependentNode.yesRadio?.checked ?? false,
206
-
207
- // Basic validation: ensure field isn't empty
208
- function () {
209
- return this.value != null && this.value !== "";
234
+ // Set default industry value when 'businessTypeField' is 'Corporation'
235
+ industryField.applyBusinessRule(
236
+ {
237
+ setValue: [() => businessTypeField.value === "Corporation", "Corporate"],
210
238
  },
239
+ [businessTypeField] // Apply value when businessTypeField changes
240
+ );
241
+ ```
211
242
 
212
- "Contact Phone", // Shows in error message: "Contact Phone is required"
243
+ ##### Enabling and Disabling Fields
213
244
 
214
- [dependentNode] // Revalidate when dependentNode changes
245
+ ```typescript
246
+ // Disable 'taxIdField' when 'businessTypeField' is 'Individual'
247
+ taxIdField.applyBusinessRule(
248
+ {
249
+ setDisabled: [() => businessTypeField.value === "Individual"],
250
+ },
251
+ [businessTypeField] // Enable/disable when businessTypeField changes
215
252
  );
216
253
  ```
217
254
 
@@ -261,7 +298,6 @@ _Enabling/Disabling inputs_
261
298
  ```typescript
262
299
  node.disable();
263
300
  node.enable();
264
-
265
301
  ```
266
302
 
267
303
  ##### Label and Tooltip Management
@@ -295,6 +331,89 @@ title.addTooltip("This is an Example of a tooltip!", { color: "red" });
295
331
 
296
332
  ![Example](./assets//infoIconExample.gif)
297
333
 
334
+ Here's an improved markdown documentation with more comprehensive details:
335
+
336
+ ### BindForm Method
337
+
338
+ The `bindForm` method simplifies form element management in DataVerse by providing a semantic and efficient way to access form controls, sections, and tabs.
339
+
340
+ ##### Key Features
341
+
342
+ - Retrieves form definition directly from DataVerse
343
+ - Automatically generates references for:
344
+ - Controls
345
+ - Sections
346
+ - Tabs
347
+
348
+ ##### Element Types
349
+
350
+ | Element Type | Description | Accessibility |
351
+ | ------------ | ------------------------------------------- | ------------------------- |
352
+ | `control` | Includes all form fields and sub-grids | Accessed via logical name |
353
+ | `section` | Standard PowerApps form sections | Accessed via logical name |
354
+ | `tab` | Form tabs corresponding to PowerApps layout | Accessed via logical name |
355
+
356
+ ##### Usage Example
357
+
358
+ ```javascript
359
+ import { bindForm } from "powerpagestoolkit";
360
+
361
+ // Basic form binding
362
+ bindForm("form-guid").then((form) => {
363
+ // Access elements by their logical name
364
+ const nameField = form["name"];
365
+
366
+ // execute custom methods
367
+ nameField.applyBusinessRule(
368
+ {
369
+ setVisibility: [() => someNode.value === "desired value"],
370
+ },
371
+ [someNode]
372
+ );
373
+
374
+ // Or executes methods immediately upon accessing
375
+ form["phonenumber"].addTooltip("Example tooltip text");
376
+ });
377
+ ```
378
+
379
+ ##### Method Signature
380
+
381
+ ```typescript
382
+ /**
383
+ * Binds a form by its GUID and returns a collection of form elements
384
+ * @param formGuid Unique identifier for the form
385
+ * @returns Promise resolving to form element references
386
+ */
387
+ function bindForm(formGuid: string): Promise<DOMNodeReferenceArray & Record<string: DOMNodeReference>>;
388
+ ```
389
+
390
+ ##### Benefits
391
+
392
+ - Reduces code complexity
393
+ - Improves readability
394
+ - Provides type-safe access to form elements
395
+ - Supports flexible form interactions
396
+
397
+ ##### Best Practices
398
+
399
+ - Use logical names consistently
400
+ - Handle async nature of form binding
401
+ - Leverage TypeScript for enhanced type checking
402
+
403
+ ##### Error Handling
404
+
405
+ Ensure proper error handling for form binding:
406
+
407
+ ```javascript
408
+ bindForm("form-guid")
409
+ .then((form) => {
410
+ // Form processing
411
+ })
412
+ .catch((error) => {
413
+ console.error("Form binding failed", error);
414
+ });
415
+ ```
416
+
298
417
  ### DataVerse API
299
418
 
300
419
  Perform secure API calls to DataVerse from your PowerPages site. This method implements the shell deferred token to send requests with `__RequestVerificationToken`
@@ -9,24 +9,21 @@ interface IBusinessRule {
9
9
  setVisibility?: [condition: () => boolean, clearValuesOnHide?: boolean];
10
10
  /**
11
11
  * @param isRequired Function determining if field is required
12
- * @param isValid Function validating field input. allows access to the invoked expression passed by {@link isRequired}
12
+ * @param isValid Function validating field input.
13
13
  */
14
- setRequired?: [
15
- isRequired: () => boolean,
16
- isValid: (isRequired: () => boolean) => boolean
17
- ];
14
+ setRequired?: [isRequired: () => boolean, isValid: () => boolean];
18
15
  /**
19
16
  * @param condition A function to determine if the value provided should be applied to this field
20
17
  * @param value The value to set for the HTML element.
21
18
  * for parents of boolean radios, pass true or false as value, or
22
19
  * an expression returning a boolean
23
20
  */
24
- setValue?: [condition: () => boolean, value: any];
21
+ setValue?: [condition: () => boolean, value: () => any | any];
25
22
  /**
26
23
  * @param condition A function to determine if this field
27
24
  * should be enabled in a form, or disabled. True || 1 = disabled. False || 0 = enabled
28
25
  */
29
- setDisabled?: [condition: () => boolean];
26
+ setDisabled?: () => boolean;
30
27
  }
31
28
  export declare const _init: unique symbol;
32
29
  declare const _destroy: unique symbol;
package/dist/bundle.js CHANGED
@@ -916,7 +916,7 @@ var DOMNodeReference = class _DOMNodeReference {
916
916
  evaluationfunction: () => {
917
917
  const isFieldRequired = isRequired.bind(this)();
918
918
  const isFieldVisible = window.getComputedStyle(this.visibilityController).display !== "none";
919
- return !isFieldRequired || !isFieldVisible || isValid.bind(this)(isRequired.bind(this));
919
+ return !isFieldRequired || !isFieldVisible || isValid.bind(this)();
920
920
  }
921
921
  });
922
922
  Page_Validators.push(newValidator);
@@ -928,7 +928,8 @@ var DOMNodeReference = class _DOMNodeReference {
928
928
  );
929
929
  }
930
930
  if (rule.setValue) {
931
- const [condition, value] = rule.setValue;
931
+ let [condition, value] = rule.setValue;
932
+ if (value instanceof Function) value = value();
932
933
  if (condition.bind(this)()) {
933
934
  this.setValue.bind(this)(value);
934
935
  }
@@ -945,7 +946,7 @@ var DOMNodeReference = class _DOMNodeReference {
945
946
  }
946
947
  }
947
948
  if (rule.setDisabled) {
948
- const [condition] = rule.setDisabled;
949
+ const condition = rule.setDisabled;
949
950
  condition.bind(this)() ? this.disable() : this.enable();
950
951
  if (dependencies.length) {
951
952
  this._configDependencyTracking(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "powerpagestoolkit",
3
- "version": "2.7.0",
3
+ "version": "2.7.001",
4
4
  "description": "Reference, manipulate, and engage with Power Pages sites through the nodes in the DOM; use a variety of custom methods that allow customizing your power pages site quicker and easier. ",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",