@yuneta/gobj-ui 7.6.1 → 7.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/dist/gobj-ui.cjs.js +51 -20
- package/dist/gobj-ui.es.js +51 -20
- package/package.json +1 -1
- package/src/c_yui_form.js +86 -19
- package/src/c_yui_treedb_topic_with_form.js +6 -1
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -6951,26 +6951,13 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
6951
6951
|
"",
|
|
6952
6952
|
{
|
|
6953
6953
|
"invalid": function(evt) {
|
|
6954
|
-
this
|
|
6955
|
-
let $h = this.parentNode.querySelector(".help");
|
|
6956
|
-
$h.textContent = this.validationMessage;
|
|
6957
|
-
$h.style.display = "block";
|
|
6954
|
+
mark_field_validity(this);
|
|
6958
6955
|
},
|
|
6959
6956
|
"input": function(evt) {
|
|
6960
6957
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_RECORD_CHANGED", {}, gobj);
|
|
6961
6958
|
},
|
|
6962
6959
|
"blur": function(evt) {
|
|
6963
|
-
|
|
6964
|
-
this.classList.add("is-danger");
|
|
6965
|
-
let $h = this.parentNode.querySelector(".help");
|
|
6966
|
-
$h.textContent = this.validationMessage;
|
|
6967
|
-
$h.style.display = "block";
|
|
6968
|
-
} else {
|
|
6969
|
-
this.classList.remove("is-danger");
|
|
6970
|
-
let $h = this.parentNode.querySelector(".help");
|
|
6971
|
-
$h.textContent = "";
|
|
6972
|
-
$h.style.display = "none";
|
|
6973
|
-
}
|
|
6960
|
+
mark_field_validity(this);
|
|
6974
6961
|
}
|
|
6975
6962
|
}
|
|
6976
6963
|
]);
|
|
@@ -7485,6 +7472,44 @@ function template2columns(gobj, columns, template, sub_elements) {
|
|
|
7485
7472
|
return columns;
|
|
7486
7473
|
}
|
|
7487
7474
|
/************************************************************
|
|
7475
|
+
* What is wrong with a field, in the APP's language.
|
|
7476
|
+
*
|
|
7477
|
+
* `input.validationMessage` is the BROWSER's sentence in the BROWSER's
|
|
7478
|
+
* locale: a Spanish form on an English Firefox says "Please fill out
|
|
7479
|
+
* this field." and no i18n reaches it. The one case worth owning is
|
|
7480
|
+
* the empty required field — by far the common one — and the rest
|
|
7481
|
+
* falls back to the browser, whose wording for a bad pattern or an
|
|
7482
|
+
* out-of-range number is more precise than anything generic here.
|
|
7483
|
+
************************************************************/
|
|
7484
|
+
function field_validation_message($input) {
|
|
7485
|
+
let v = $input.validity;
|
|
7486
|
+
if (v && v.valueMissing) return (0, i18next.t)("this field is required");
|
|
7487
|
+
return $input.validationMessage;
|
|
7488
|
+
}
|
|
7489
|
+
/************************************************************
|
|
7490
|
+
* Mark a field as wrong, or clear the mark. One place: the same
|
|
7491
|
+
* three lines lived in the `invalid` and `blur` handlers of every
|
|
7492
|
+
* field kind.
|
|
7493
|
+
************************************************************/
|
|
7494
|
+
function mark_field_validity($input) {
|
|
7495
|
+
let $h = $input.parentNode ? $input.parentNode.querySelector(".help") : null;
|
|
7496
|
+
let v = $input.validity;
|
|
7497
|
+
if (!v || v.valid) {
|
|
7498
|
+
$input.classList.remove("is-danger");
|
|
7499
|
+
if ($h) {
|
|
7500
|
+
$h.textContent = "";
|
|
7501
|
+
$h.style.display = "none";
|
|
7502
|
+
}
|
|
7503
|
+
return true;
|
|
7504
|
+
}
|
|
7505
|
+
$input.classList.add("is-danger");
|
|
7506
|
+
if ($h) {
|
|
7507
|
+
$h.textContent = field_validation_message($input);
|
|
7508
|
+
$h.style.display = "block";
|
|
7509
|
+
}
|
|
7510
|
+
return false;
|
|
7511
|
+
}
|
|
7512
|
+
/************************************************************
|
|
7488
7513
|
*
|
|
7489
7514
|
************************************************************/
|
|
7490
7515
|
function validate_form(gobj, $form) {
|
|
@@ -7944,7 +7969,7 @@ function form_value_2_treedb_value(gobj, field_desc, value) {
|
|
|
7944
7969
|
function ac_window_to_close(gobj, event, kw, src) {
|
|
7945
7970
|
if ((0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "changes")) {
|
|
7946
7971
|
kw.abort_close = true;
|
|
7947
|
-
kw.warning = "
|
|
7972
|
+
kw.warning = "all changes will be lost";
|
|
7948
7973
|
}
|
|
7949
7974
|
return 0;
|
|
7950
7975
|
}
|
|
@@ -7971,10 +7996,16 @@ function ac_save_record(gobj, event, kw, src) {
|
|
|
7971
7996
|
let values = get_form_values(gobj, $form);
|
|
7972
7997
|
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_SAVE_RECORD", values);
|
|
7973
7998
|
set_changed_stated(gobj, false);
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7999
|
+
return 0;
|
|
8000
|
+
}
|
|
8001
|
+
try {
|
|
8002
|
+
$form.reportValidity();
|
|
8003
|
+
} catch (e) {
|
|
8004
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot report the form's validity: ${e}`);
|
|
7977
8005
|
}
|
|
8006
|
+
$form.querySelectorAll(".yui-form-data-input").forEach(($input) => {
|
|
8007
|
+
mark_field_validity($input);
|
|
8008
|
+
});
|
|
7978
8009
|
return 0;
|
|
7979
8010
|
}
|
|
7980
8011
|
/************************************************************
|
|
@@ -17247,7 +17278,7 @@ function form_may_close(gobj) {
|
|
|
17247
17278
|
let kw = {};
|
|
17248
17279
|
(0, _yuneta_gobj_js.gobj_send_event)(priv.form, "EV_WINDOW_TO_CLOSE", kw, gobj);
|
|
17249
17280
|
if (kw.abort_close) {
|
|
17250
|
-
yui_shell_confirm_yesnocancel(yui_shell_of(gobj), "
|
|
17281
|
+
yui_shell_confirm_yesnocancel(yui_shell_of(gobj), kw.warning || "all changes will be lost", {
|
|
17251
17282
|
t: i18next.t,
|
|
17252
17283
|
yes_label: "yes",
|
|
17253
17284
|
no_label: "no",
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -6946,26 +6946,13 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
6946
6946
|
"",
|
|
6947
6947
|
{
|
|
6948
6948
|
"invalid": function(evt) {
|
|
6949
|
-
this
|
|
6950
|
-
let $h = this.parentNode.querySelector(".help");
|
|
6951
|
-
$h.textContent = this.validationMessage;
|
|
6952
|
-
$h.style.display = "block";
|
|
6949
|
+
mark_field_validity(this);
|
|
6953
6950
|
},
|
|
6954
6951
|
"input": function(evt) {
|
|
6955
6952
|
gobj_send_event(gobj, "EV_RECORD_CHANGED", {}, gobj);
|
|
6956
6953
|
},
|
|
6957
6954
|
"blur": function(evt) {
|
|
6958
|
-
|
|
6959
|
-
this.classList.add("is-danger");
|
|
6960
|
-
let $h = this.parentNode.querySelector(".help");
|
|
6961
|
-
$h.textContent = this.validationMessage;
|
|
6962
|
-
$h.style.display = "block";
|
|
6963
|
-
} else {
|
|
6964
|
-
this.classList.remove("is-danger");
|
|
6965
|
-
let $h = this.parentNode.querySelector(".help");
|
|
6966
|
-
$h.textContent = "";
|
|
6967
|
-
$h.style.display = "none";
|
|
6968
|
-
}
|
|
6955
|
+
mark_field_validity(this);
|
|
6969
6956
|
}
|
|
6970
6957
|
}
|
|
6971
6958
|
]);
|
|
@@ -7480,6 +7467,44 @@ function template2columns(gobj, columns, template, sub_elements) {
|
|
|
7480
7467
|
return columns;
|
|
7481
7468
|
}
|
|
7482
7469
|
/************************************************************
|
|
7470
|
+
* What is wrong with a field, in the APP's language.
|
|
7471
|
+
*
|
|
7472
|
+
* `input.validationMessage` is the BROWSER's sentence in the BROWSER's
|
|
7473
|
+
* locale: a Spanish form on an English Firefox says "Please fill out
|
|
7474
|
+
* this field." and no i18n reaches it. The one case worth owning is
|
|
7475
|
+
* the empty required field — by far the common one — and the rest
|
|
7476
|
+
* falls back to the browser, whose wording for a bad pattern or an
|
|
7477
|
+
* out-of-range number is more precise than anything generic here.
|
|
7478
|
+
************************************************************/
|
|
7479
|
+
function field_validation_message($input) {
|
|
7480
|
+
let v = $input.validity;
|
|
7481
|
+
if (v && v.valueMissing) return t("this field is required");
|
|
7482
|
+
return $input.validationMessage;
|
|
7483
|
+
}
|
|
7484
|
+
/************************************************************
|
|
7485
|
+
* Mark a field as wrong, or clear the mark. One place: the same
|
|
7486
|
+
* three lines lived in the `invalid` and `blur` handlers of every
|
|
7487
|
+
* field kind.
|
|
7488
|
+
************************************************************/
|
|
7489
|
+
function mark_field_validity($input) {
|
|
7490
|
+
let $h = $input.parentNode ? $input.parentNode.querySelector(".help") : null;
|
|
7491
|
+
let v = $input.validity;
|
|
7492
|
+
if (!v || v.valid) {
|
|
7493
|
+
$input.classList.remove("is-danger");
|
|
7494
|
+
if ($h) {
|
|
7495
|
+
$h.textContent = "";
|
|
7496
|
+
$h.style.display = "none";
|
|
7497
|
+
}
|
|
7498
|
+
return true;
|
|
7499
|
+
}
|
|
7500
|
+
$input.classList.add("is-danger");
|
|
7501
|
+
if ($h) {
|
|
7502
|
+
$h.textContent = field_validation_message($input);
|
|
7503
|
+
$h.style.display = "block";
|
|
7504
|
+
}
|
|
7505
|
+
return false;
|
|
7506
|
+
}
|
|
7507
|
+
/************************************************************
|
|
7483
7508
|
*
|
|
7484
7509
|
************************************************************/
|
|
7485
7510
|
function validate_form(gobj, $form) {
|
|
@@ -7939,7 +7964,7 @@ function form_value_2_treedb_value(gobj, field_desc, value) {
|
|
|
7939
7964
|
function ac_window_to_close(gobj, event, kw, src) {
|
|
7940
7965
|
if (gobj_read_bool_attr(gobj, "changes")) {
|
|
7941
7966
|
kw.abort_close = true;
|
|
7942
|
-
kw.warning = "
|
|
7967
|
+
kw.warning = "all changes will be lost";
|
|
7943
7968
|
}
|
|
7944
7969
|
return 0;
|
|
7945
7970
|
}
|
|
@@ -7966,10 +7991,16 @@ function ac_save_record(gobj, event, kw, src) {
|
|
|
7966
7991
|
let values = get_form_values(gobj, $form);
|
|
7967
7992
|
gobj_publish_event(gobj, "EV_SAVE_RECORD", values);
|
|
7968
7993
|
set_changed_stated(gobj, false);
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7994
|
+
return 0;
|
|
7995
|
+
}
|
|
7996
|
+
try {
|
|
7997
|
+
$form.reportValidity();
|
|
7998
|
+
} catch (e) {
|
|
7999
|
+
log_error(`${gobj_short_name(gobj)}: cannot report the form's validity: ${e}`);
|
|
7972
8000
|
}
|
|
8001
|
+
$form.querySelectorAll(".yui-form-data-input").forEach(($input) => {
|
|
8002
|
+
mark_field_validity($input);
|
|
8003
|
+
});
|
|
7973
8004
|
return 0;
|
|
7974
8005
|
}
|
|
7975
8006
|
/************************************************************
|
|
@@ -17242,7 +17273,7 @@ function form_may_close(gobj) {
|
|
|
17242
17273
|
let kw = {};
|
|
17243
17274
|
gobj_send_event(priv.form, "EV_WINDOW_TO_CLOSE", kw, gobj);
|
|
17244
17275
|
if (kw.abort_close) {
|
|
17245
|
-
yui_shell_confirm_yesnocancel(yui_shell_of(gobj), "
|
|
17276
|
+
yui_shell_confirm_yesnocancel(yui_shell_of(gobj), kw.warning || "all changes will be lost", {
|
|
17246
17277
|
t,
|
|
17247
17278
|
yes_label: "yes",
|
|
17248
17279
|
no_label: "no",
|
package/package.json
CHANGED
package/src/c_yui_form.js
CHANGED
|
@@ -1168,26 +1168,13 @@ function create_form_field(
|
|
|
1168
1168
|
}
|
|
1169
1169
|
let extend = ['input', attrs, '', {
|
|
1170
1170
|
'invalid': function (evt) {
|
|
1171
|
-
this
|
|
1172
|
-
let $h = this.parentNode.querySelector('.help');
|
|
1173
|
-
$h.textContent = this.validationMessage;
|
|
1174
|
-
$h.style.display = 'block';
|
|
1171
|
+
mark_field_validity(this);
|
|
1175
1172
|
},
|
|
1176
1173
|
'input': function (evt) {
|
|
1177
1174
|
gobj_send_event(gobj, "EV_RECORD_CHANGED", {}, gobj);
|
|
1178
1175
|
},
|
|
1179
1176
|
'blur': function (evt) {
|
|
1180
|
-
|
|
1181
|
-
this.classList.add('is-danger');
|
|
1182
|
-
let $h = this.parentNode.querySelector('.help');
|
|
1183
|
-
$h.textContent = this.validationMessage;
|
|
1184
|
-
$h.style.display = 'block';
|
|
1185
|
-
} else {
|
|
1186
|
-
this.classList.remove('is-danger');
|
|
1187
|
-
let $h = this.parentNode.querySelector('.help');
|
|
1188
|
-
$h.textContent = '';
|
|
1189
|
-
$h.style.display = 'none';
|
|
1190
|
-
}
|
|
1177
|
+
mark_field_validity(this);
|
|
1191
1178
|
}
|
|
1192
1179
|
}];
|
|
1193
1180
|
|
|
@@ -1976,6 +1963,61 @@ function template2columns(gobj, columns, template, sub_elements)
|
|
|
1976
1963
|
return columns;
|
|
1977
1964
|
}
|
|
1978
1965
|
|
|
1966
|
+
/************************************************************
|
|
1967
|
+
* What is wrong with a field, in the APP's language.
|
|
1968
|
+
*
|
|
1969
|
+
* `input.validationMessage` is the BROWSER's sentence in the BROWSER's
|
|
1970
|
+
* locale: a Spanish form on an English Firefox says "Please fill out
|
|
1971
|
+
* this field." and no i18n reaches it. The one case worth owning is
|
|
1972
|
+
* the empty required field — by far the common one — and the rest
|
|
1973
|
+
* falls back to the browser, whose wording for a bad pattern or an
|
|
1974
|
+
* out-of-range number is more precise than anything generic here.
|
|
1975
|
+
************************************************************/
|
|
1976
|
+
function field_validation_message($input)
|
|
1977
|
+
{
|
|
1978
|
+
let v = $input.validity;
|
|
1979
|
+
if(v && v.valueMissing) {
|
|
1980
|
+
return t("this field is required");
|
|
1981
|
+
}
|
|
1982
|
+
return $input.validationMessage;
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
/************************************************************
|
|
1986
|
+
* Mark a field as wrong, or clear the mark. One place: the same
|
|
1987
|
+
* three lines lived in the `invalid` and `blur` handlers of every
|
|
1988
|
+
* field kind.
|
|
1989
|
+
************************************************************/
|
|
1990
|
+
function mark_field_validity($input)
|
|
1991
|
+
{
|
|
1992
|
+
let $h = $input.parentNode? $input.parentNode.querySelector('.help') : null;
|
|
1993
|
+
|
|
1994
|
+
/* `validity.valid`, NEVER `checkValidity()`.
|
|
1995
|
+
*
|
|
1996
|
+
* checkValidity() FIRES the `invalid` event, and this function is what
|
|
1997
|
+
* that event's handler calls: one asks the other for ever. It cost a
|
|
1998
|
+
* page full of "too much recursion" the first time Save reported a bad
|
|
1999
|
+
* field. Reading `validity` asks the same question and fires nothing.
|
|
2000
|
+
* A control with no `validity` (a wrapper div) is not invalid. */
|
|
2001
|
+
let v = $input.validity;
|
|
2002
|
+
let ok = !v || v.valid;
|
|
2003
|
+
|
|
2004
|
+
if(ok) {
|
|
2005
|
+
$input.classList.remove('is-danger');
|
|
2006
|
+
if($h) {
|
|
2007
|
+
$h.textContent = '';
|
|
2008
|
+
$h.style.display = 'none';
|
|
2009
|
+
}
|
|
2010
|
+
return true;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
$input.classList.add('is-danger');
|
|
2014
|
+
if($h) {
|
|
2015
|
+
$h.textContent = field_validation_message($input);
|
|
2016
|
+
$h.style.display = 'block';
|
|
2017
|
+
}
|
|
2018
|
+
return false;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
1979
2021
|
/************************************************************
|
|
1980
2022
|
*
|
|
1981
2023
|
************************************************************/
|
|
@@ -2718,7 +2760,11 @@ function ac_window_to_close(gobj, event, kw, src)
|
|
|
2718
2760
|
{
|
|
2719
2761
|
if(gobj_read_bool_attr(gobj, "changes")) {
|
|
2720
2762
|
kw.abort_close = true; // Don't close the window until fields repaired
|
|
2721
|
-
|
|
2763
|
+
/* An i18n KEY, not a sentence: the dialog renders its message with
|
|
2764
|
+
* `i18n: message`. The English sentence that was here was a key
|
|
2765
|
+
* nobody had defined, so it rendered as itself in every language —
|
|
2766
|
+
* and no locale validator can see a key that travels as data. */
|
|
2767
|
+
kw.warning = "all changes will be lost";
|
|
2722
2768
|
}
|
|
2723
2769
|
return 0;
|
|
2724
2770
|
}
|
|
@@ -2754,11 +2800,32 @@ function ac_save_record(gobj, event, kw, src)
|
|
|
2754
2800
|
let values = get_form_values(gobj, $form);
|
|
2755
2801
|
gobj_publish_event(gobj, "EV_SAVE_RECORD", values);
|
|
2756
2802
|
set_changed_stated(gobj, false);
|
|
2803
|
+
return 0;
|
|
2804
|
+
}
|
|
2757
2805
|
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2806
|
+
/* Pressing Save on a form with a bad field used to do NOTHING: the
|
|
2807
|
+
* `abort_close` / `warning` this branch set were written on the click's
|
|
2808
|
+
* own kw, which nobody reads — that pair belongs to the close path, not
|
|
2809
|
+
* to this one. The button looked broken.
|
|
2810
|
+
*
|
|
2811
|
+
* reportValidity() is what the form owed the reader: it fires `invalid`
|
|
2812
|
+
* on EVERY bad field (so all of them get marked, not just the one last
|
|
2813
|
+
* touched) and puts the caret and the viewport on the first, which on a
|
|
2814
|
+
* long form is the difference between "it did nothing" and "it is that
|
|
2815
|
+
* one, up there". */
|
|
2816
|
+
try {
|
|
2817
|
+
$form.reportValidity();
|
|
2818
|
+
} catch(e) {
|
|
2819
|
+
log_error(`${gobj_short_name(gobj)}: cannot report the form's validity: ${e}`);
|
|
2761
2820
|
}
|
|
2821
|
+
|
|
2822
|
+
/* reportValidity() stops at the first field the BROWSER validates, and
|
|
2823
|
+
* the nested tables validate themselves; mark every input we own so the
|
|
2824
|
+
* count of red fields is the true one. */
|
|
2825
|
+
$form.querySelectorAll('.yui-form-data-input').forEach(($input) => {
|
|
2826
|
+
mark_field_validity($input);
|
|
2827
|
+
});
|
|
2828
|
+
|
|
2762
2829
|
return 0;
|
|
2763
2830
|
}
|
|
2764
2831
|
|
|
@@ -1527,9 +1527,14 @@ function form_may_close(gobj)
|
|
|
1527
1527
|
let kw = {};
|
|
1528
1528
|
gobj_send_event(priv.form, "EV_WINDOW_TO_CLOSE", kw, gobj);
|
|
1529
1529
|
if(kw.abort_close) {
|
|
1530
|
+
/* The message the FORM returned, not a copy of it. The dialog
|
|
1531
|
+
* takes its message as an i18n KEY, so a second literal here is
|
|
1532
|
+
* a second key to define — and the one that was here had never
|
|
1533
|
+
* been defined in any locale, which renders as the English
|
|
1534
|
+
* sentence itself, in every language, for ever. */
|
|
1530
1535
|
yui_shell_confirm_yesnocancel(
|
|
1531
1536
|
yui_shell_of(gobj),
|
|
1532
|
-
|
|
1537
|
+
kw.warning || "all changes will be lost",
|
|
1533
1538
|
{t: t, yes_label: "yes", no_label: "no", cancel_label: "cancel"}
|
|
1534
1539
|
).then(function(answer) {
|
|
1535
1540
|
if(answer === "yes" && priv.form_modal) {
|