-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmtz-wizard-step-behavior.html
156 lines (152 loc) · 4.79 KB
/
mtz-wizard-step-behavior.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<link rel="import" href="../polymer/polymer.html">
<script>
window.mtz = window.mtz || {};
/**
* `mtz.WizardStepBehavior`
* Works with wizard to register and build out the steps array so stepper can accurately report on the available
* steps, also contains meta-data needed by stepper to display the steps for navigation.
*
* @polymerBehavior mtz.WizardStepBehavior
* @demo demo/mtz-wizard-step.html
*/
mtz.WizardStepBehavior = {
hostAttributes: {
'wizard-step': true
},
properties: {
/* Used to stamp the content for the first time, supports a single lazy-load/API call per wizard instance */
active: {
type: Boolean,
value: false,
reflectToAttribute: true,
notify: true,
},
/* Used to track the dirty state of the form, if there is one */
dirty: {
type: Boolean,
value: false,
readOnly: true,
reflectToAttribute: true,
notify: true
},
/* The form associated with this step, or null if one isn't found */
form: {
type: Object,
notify: true,
value: null
},
/* The query selector to base the form selection off of */
formSelector: {
type: String,
value: '[wizard-form],.wizard-form'
},
/* The validity state of the element */
invalid: {
type: Boolean,
reflectToAttribute: true,
notify: true,
value: false
},
/* TODO: Add optional flows */
/* A step that is not required in the flow */
optional: {
type: Boolean,
value: false
},
/* TODO: Add setting of completed flag */
/* Step was finished used for flow control and display */
completed: {
type: Boolean,
value: false
},
/* TODO: Add editable/non-editable functionality */
/* Determines if the step is able to be revisited for modifications */
editable: {
type: Boolean,
value: false
},
/* Used by the stepper to give a pretty name */
label: String,
/* Used to map the UI and API together for validation and data interfacing */
name: {
type: String,
reflectToAttribute: true
},
/* Whether or not the step is required */
required: {
type: Boolean,
value: false,
reflectToAttribute: true
},
/* The nodeObserver for tracking forms being added */
__nodeObserver: Object
},
/**
* Replaces methods with bound methods for ease of use in event listeners.
*/
ready() {
this.__updateDirty = this.__updateDirty.bind(this);
},
/**
* Binds the event listeners and node observers.
*/
attached() {
this.addEventListener('change', this.__updateDirty);
// For non-shadow DOM manipulations
this.__nonShadowObserver = Polymer.dom(this).observeNodes(() => {
const form = Polymer.dom(this).queryDistributedElements(this.formSelector)[0];
this.set('form', form || this.form || null);
});
// For Shadow DOM manipulations
this.__shadowObserver = Polymer.dom(this.root).observeNodes(() => {
const form = Polymer.dom(this.root).queryDistributedElements(this.formSelector)[0];
this.set('form', form || this.form || null);
});
},
/**
* Cleans up the event listeners and node observers.
*/
detached() {
this.removeEventListener('change', this.__updateDirty);
// For non-shadow child observer
if (this.__nonShadowObserver) {
Polymer.dom(this).unobserveNodes(this.__nonShadowObserver);
this.__nonShadowObserver = null;
}
// For shadow DOM child observer
if (this.__shadowObserver) {
Polymer.dom(this.root).unobserveNodes(this.__shadowObserver);
this.__shadowObserver = null;
}
},
/**
* Reverts the form back to initial state if one exists, clears validity and dirty states.
*/
reset() {
if (this.form) this.form.reset();
this.invalid = false;
this._setDirty(false);
},
/**
* Validates all the required elements (custom and native) in the form, if one exists, and checks step validity.
* NOTE: this method is a promise so validation for the step in custom implementations can rely on async validation
* via things like API services.
*
* @return {Promise} - resolves with a Boolean that says if the wizard is valid or not
*/
validate() {
const validForm = !this.form || this.form.validate();
const valid = !this.required || validForm;
this.invalid = !valid;
return Promise.resolve(valid);
},
/**
* Sets the dirty state to true.
* @listens change
* @private
*/
__updateDirty() {
this._setDirty(true);
}
};
</script>