Commit ac05c76f authored by Romain Courteaud's avatar Romain Courteaud

erp5_web_renderjs_ui: html5 textarea/select follow the html5 input latest changes

parent dfcca04f
...@@ -39,69 +39,82 @@ ...@@ -39,69 +39,82 @@
option, option,
fragment; fragment;
select.id = this.state.id || this.state.name; if (modification_dict.hasOwnProperty('value') ||
select.setAttribute('name', this.state.name); modification_dict.hasOwnProperty('item_list') ||
modification_dict.hasOwnProperty('editable') ||
if (modification_dict.error_text && modification_dict.hasOwnProperty('required') ||
!select.classList.contains("is-invalid")) { modification_dict.hasOwnProperty('id') ||
select.classList.add("is-invalid"); modification_dict.hasOwnProperty('name') ||
} else if (select.classList.contains("is-invalid")) { modification_dict.hasOwnProperty('title')
select.classList.remove("is-invalid"); ) {
} select.id = this.state.id || this.state.name;
select.setAttribute('name', this.state.name);
if (this.state.title) {
select.setAttribute('title', this.state.title);
}
if (this.state.title) { if (this.state.required) {
select.setAttribute('title', this.state.title); select.required = true;
} } else {
select.required = false;
}
if (this.state.required) { if (this.state.editable) {
select.required = true; select.readonly = true;
} else { } else {
select.required = false; select.readonly = false;
} }
if (this.state.editable) { if (modification_dict.hasOwnProperty('value') ||
select.readonly = true; modification_dict.hasOwnProperty('item_list')) {
} else { fragment = document.createDocumentFragment();
select.readonly = false;
} for (i = 0; i < item_list.length; i += 1) {
option = document.createElement('option');
option.textContent = item_list[i][0];
if (item_list[i][1] === null) {
option.setAttribute('disabled', 'disabled');
} else {
option.setAttribute('value', item_list[i][1]);
if (item_list[i][1] === this.state.value) {
option.setAttribute('selected', 'selected');
found = true;
}
}
fragment.appendChild(option);
}
if (this.state.hidden) { if (!found && !isEmpty(this.state.value)) {
select.hidden = true; option = document.createElement('option');
} else { option.textContent = '??? (' + this.state.value + ')';
select.hidden = false; option.setAttribute('value', this.state.value);
} option.setAttribute('selected', 'selected');
fragment.appendChild(option);
}
if (modification_dict.hasOwnProperty('value') || while (select.firstChild) {
modification_dict.hasOwnProperty('item_list')) { select.removeChild(select.firstChild);
fragment = document.createDocumentFragment();
for (i = 0; i < item_list.length; i += 1) {
option = document.createElement('option');
option.textContent = item_list[i][0];
if (item_list[i][1] === null) {
option.setAttribute('disabled', 'disabled');
} else {
option.setAttribute('value', item_list[i][1]);
if (item_list[i][1] === this.state.value) {
option.setAttribute('selected', 'selected');
found = true;
}
} }
fragment.appendChild(option); select.appendChild(fragment);
} }
}
if (!found && !isEmpty(this.state.value)) { if (modification_dict.hasOwnProperty('error_text') ||
option = document.createElement('option'); modification_dict.hasOwnProperty('hidden')) {
option.textContent = '??? (' + this.state.value + ')'; if (this.state.hidden && !this.state.error_text) {
option.setAttribute('value', this.state.value); select.hidden = true;
option.setAttribute('selected', 'selected'); } else {
fragment.appendChild(option); select.hidden = false;
} }
while (select.firstChild) { if (this.state.error_text &&
select.removeChild(select.firstChild); !select.classList.contains("is-invalid")) {
select.classList.add("is-invalid");
} else if (!this.state.error_text &&
select.classList.contains("is-invalid")) {
select.classList.remove("is-invalid");
} }
select.appendChild(fragment);
} }
}) })
...@@ -122,32 +135,45 @@ ...@@ -122,32 +135,45 @@
} }
} }
return result; return result;
}) }, {mutex: 'changestate'})
.declareAcquiredMethod("notifyValid", "notifyValid") .declareAcquiredMethod("notifyValid", "notifyValid")
.declareMethod('checkValidity', function checkValidity() { .declareMethod('checkValidity', function checkValidity() {
var select = this.element.querySelector('select'), var select = this.element.querySelector('select'),
result = select.checkValidity() || this.state.error_text === ""; result = select.checkValidity();
if (result) { if (result) {
return this.notifyValid() return this.notifyValid()
.push(function () { .push(function () {
return result; return result;
}); });
} }
if (this.state.error_text) {
return this.notifyInvalid(this.state.error_text)
.push(function () {
return result;
});
}
return result; return result;
}, {mutex: 'changestate'})
.declareJob('deferErrorText', function deferErrorText(error_text) {
return this.changeState({
error_text: error_text
});
}) })
.declareAcquiredMethod("notifyChange", "notifyChange") .declareAcquiredMethod("notifyChange", "notifyChange")
.onEvent('change', function change() { .onEvent('change', function change() {
return RSVP.all([ return RSVP.all([
this.checkValidity(), this.checkValidity(),
this.notifyChange() this.notifyChange("change")
]); ]);
}, false, false) }, false, false)
.onEvent('input', function input() { .onEvent('input', function input() {
return RSVP.all([ return RSVP.all([
this.checkValidity(), this.checkValidity(),
this.notifyChange() this.notifyChange("input")
]); ]);
}, false, false) }, false, false)
...@@ -164,7 +190,10 @@ ...@@ -164,7 +190,10 @@
.declareAcquiredMethod("notifyInvalid", "notifyInvalid") .declareAcquiredMethod("notifyInvalid", "notifyInvalid")
.onEvent('invalid', function invalid(evt) { .onEvent('invalid', function invalid(evt) {
// invalid event does not bubble // invalid event does not bubble
return this.notifyInvalid(evt.target.validationMessage); return RSVP.all([
this.deferErrorText(evt.target.validationMessage),
this.notifyInvalid(evt.target.validationMessage)
]);
}, true, false); }, true, false);
}(document, window, rJS, RSVP, getFirstNonEmpty, isEmpty)); }(document, window, rJS, RSVP, getFirstNonEmpty, isEmpty));
\ No newline at end of file
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>986.42836.14245.5444</string> </value> <value> <string>990.28313.43301.324</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1600275334.01</float> <float>1614700512.05</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -3,14 +3,6 @@ ...@@ -3,14 +3,6 @@
(function (window, rJS, RSVP, navigator) { (function (window, rJS, RSVP, navigator) {
"use strict"; "use strict";
function checkChange() {
var gadget = this;
return RSVP.all([
gadget.checkValidity(),
gadget.notifyChange()
]);
}
rJS(window) rJS(window)
.setState({ .setState({
editable: false, editable: false,
...@@ -18,49 +10,71 @@ ...@@ -18,49 +10,71 @@
}) })
.declareMethod('render', function render(options) { .declareMethod('render', function render(options) {
return this.changeState(options); return this.changeState({
value: options.value,
editable: options.editable,
required: options.required,
id: options.id,
name: options.name,
title: options.title,
error_text: options.error_text || "",
hidden: options.hidden
});
}) })
.onStateChange(function onStateChange(modification_dict) { .onStateChange(function onStateChange(modification_dict) {
var textarea = this.element.querySelector('textarea'); var textarea = this.element.querySelector('textarea');
if (this.state.error_text && if (modification_dict.hasOwnProperty('value') ||
!textarea.classList.contains("is-invalid")) { modification_dict.hasOwnProperty('editable') ||
textarea.classList.add("is-invalid"); modification_dict.hasOwnProperty('required') ||
} else if (!this.state.error_text && modification_dict.hasOwnProperty('id') ||
textarea.classList.contains("is-invalid")) { modification_dict.hasOwnProperty('name') ||
textarea.classList.remove("is-invalid"); modification_dict.hasOwnProperty('title')
} ) {
if (modification_dict.hasOwnProperty("value")) { if (modification_dict.hasOwnProperty("value")) {
textarea.value = modification_dict.value; textarea.value = modification_dict.value;
} }
if (modification_dict.hasOwnProperty("name")) { if (modification_dict.hasOwnProperty("name")) {
textarea.setAttribute('name', modification_dict.name); textarea.setAttribute('name', modification_dict.name);
textarea.setAttribute('id', modification_dict.name); textarea.setAttribute('id', modification_dict.name);
} }
if (modification_dict.hasOwnProperty("title")) { if (modification_dict.hasOwnProperty("title")) {
textarea.setAttribute('title', modification_dict.title); textarea.setAttribute('title', modification_dict.title);
} }
if (this.state.required) { if (this.state.required) {
textarea.setAttribute('required', 'required'); textarea.required = true;
} else { } else {
textarea.removeAttribute('required'); textarea.required = false;
} }
if (this.state.editable) {
textarea.removeAttribute('readonly');
} else {
textarea.setAttribute('readonly', 'readonly');
}
if (this.state.editable) {
textarea.removeAttribute('readonly');
} else {
textarea.setAttribute('readonly', 'readonly');
} }
if (this.state.hidden) { if (modification_dict.hasOwnProperty('error_text') ||
textarea.hidden = true; modification_dict.hasOwnProperty('hidden')) {
} else { if (this.state.hidden && !this.state.error_text) {
textarea.hidden = false; textarea.hidden = true;
} else {
textarea.hidden = false;
}
if (this.state.error_text &&
!textarea.classList.contains("is-invalid")) {
textarea.classList.add("is-invalid");
} else if (!this.state.error_text &&
textarea.classList.contains("is-invalid")) {
textarea.classList.remove("is-invalid");
}
} }
}) })
...@@ -90,18 +104,35 @@ ...@@ -90,18 +104,35 @@
return result; return result;
}); });
} }
if (this.state.error_text) {
return this.notifyInvalid(this.state.error_text)
.push(function () {
return result;
});
}
return result; return result;
}) })
.declareAcquiredMethod("notifyChange", "notifyChange") .declareJob('deferErrorText', function deferErrorText(error_text) {
.onEvent('change', checkChange, false, true) return this.changeState({
.onEvent('input', checkChange, false, true) error_text: error_text
});
}, {mutex: 'changestate'})
.declareAcquiredMethod("notifyInvalid", "notifyInvalid") .declareAcquiredMethod("notifyChange", "notifyChange")
.onEvent('invalid', function invalid(evt) { .onEvent('change', function change() {
// invalid event does not bubble return RSVP.all([
return this.notifyInvalid(evt.target.validationMessage); this.checkValidity(),
}, true, false) this.notifyChange("change")
]);
}, false, false)
.onEvent('input', function input() {
return RSVP.all([
this.checkValidity(),
this.notifyChange("input")
]);
}, false, false)
.declareAcquiredMethod("notifyFocus", "notifyFocus") .declareAcquiredMethod("notifyFocus", "notifyFocus")
.onEvent('focus', function focus() { .onEvent('focus', function focus() {
...@@ -113,6 +144,16 @@ ...@@ -113,6 +144,16 @@
return this.notifyBlur(); return this.notifyBlur();
}, true, false) }, true, false)
.declareAcquiredMethod("notifyInvalid", "notifyInvalid")
.onEvent('invalid', function invalid(evt) {
// invalid event does not bubble
return RSVP.all([
this.deferErrorText(evt.target.validationMessage),
this.notifyInvalid(evt.target.validationMessage)
]);
}, true, false)
.declareAcquiredMethod("notifySubmit", "notifySubmit") .declareAcquiredMethod("notifySubmit", "notifySubmit")
.onEvent('keydown', function keydown(evt) { .onEvent('keydown', function keydown(evt) {
var textarea = this.element.querySelector('textarea'); var textarea = this.element.querySelector('textarea');
......
...@@ -226,7 +226,7 @@ ...@@ -226,7 +226,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>ERP5TypeTestCase</string> </value> <value> <string>zope</string> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>987.741.47228.29815</string> </value> <value> <string>990.28225.23941.23466</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1601596591.47</float> <float>1614695136.35</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -335,7 +335,7 @@ ...@@ -335,7 +335,7 @@
</tr> </tr>
<tr> <tr>
<td>assertElementPresent</td> <td>assertElementPresent</td>
<td>//div[@data-gadget-url="${renderjs_url}/gadget_erp5_label_field.html"][5]/div/span[contains(text(), "Input is required but no input given.")]</td> <td>//div[@data-gadget-url="${renderjs_url}/gadget_erp5_label_field.html"][5]/div/span[contains(text(), "The input failed the external validator.")]</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
...@@ -350,7 +350,7 @@ ...@@ -350,7 +350,7 @@
</tr> </tr>
<tr> <tr>
<td>assertElementNotPresent</td> <td>assertElementNotPresent</td>
<td>//div[@data-gadget-url="${renderjs_url}/gadget_erp5_label_field.html"][5]/div/span[contains(text(), "Input is required but no input given.")]</td> <td>//div[@data-gadget-url="${renderjs_url}/gadget_erp5_label_field.html"][5]/div/span[contains(text(), "The input failed the external validator.")]</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment