Skip to content

Commit 70e82ed

Browse files
authored
CLDR-16819 Improve front-end handling of submissions with errors (#5086)
1 parent 2cac2a5 commit 70e82ed

File tree

2 files changed

+53
-133
lines changed

2 files changed

+53
-133
lines changed

tools/cldr-apps/js/src/esm/cldrTable.mjs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -893,16 +893,6 @@ function updateRowOthersCell(tr, theRow, cell, protoButton) {
893893
if (!hadOtherItems /*!onIE*/) {
894894
listen(null, tr, cell);
895895
}
896-
if (
897-
tr.myProposal &&
898-
tr.myProposal.value &&
899-
!cldrSurvey.findItemByValue(theRow.items, tr.myProposal.value)
900-
) {
901-
// add back my proposal
902-
cell.appendChild(tr.myProposal);
903-
} else {
904-
tr.myProposal = null; // not needed
905-
}
906896
}
907897

908898
/**

tools/cldr-apps/js/src/esm/cldrVote.mjs

Lines changed: 53 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,7 @@ function wireUpButton(button, tr, theRow, vHash) {
5252
return false;
5353
});
5454

55-
// proposal issues
56-
if (tr.myProposal) {
57-
if (button == tr.myProposal.button) {
58-
button.className = "ichoice-x";
59-
button.checked = true;
60-
tr.lastOn = button;
61-
} else {
62-
button.className = "ichoice-o";
63-
button.checked = false;
64-
}
65-
} else if (
55+
if (
6656
theRow.voteVhash === vHash ||
6757
(theRow.voteVhash === undefined && vHash === null)
6858
) {
@@ -110,13 +100,6 @@ async function handleWiredClick(tr, theRow, vHash, newValue, button) {
110100
// and scroll
111101
cldrLoad.showCurrentId();
112102

113-
if (tr.myProposal) {
114-
const otherCell = tr.querySelector(".othercell");
115-
if (otherCell) {
116-
otherCell.removeChild(tr.myProposal);
117-
}
118-
tr.myProposal = null; // mark any pending proposal as invalid.
119-
}
120103
tr.wait = true;
121104
cldrTable.resetLastShown();
122105
theRow.proposedResults = null;
@@ -208,8 +191,12 @@ function handleVoteSubmitted(json, tr, theRow, button, valToShow) {
208191
button.checked = false;
209192
cldrSurvey.hideLoader();
210193
if (json.testResults && (json.testWarnings || json.testErrors)) {
211-
// tried to submit, have errs or warnings.
212-
showProposedItem(tr.inputTd, tr, theRow, valToShow, json.testResults);
194+
// Tried to submit, have errs or warnings.
195+
// Caution: even though json is defined, it is NOT used here as the 5th argument
196+
// for showProposedItem, which apparently depends on the 5th argument being
197+
// undefined when called from here (handleVoteSubmitted), and only defined
198+
// when called from handleVoteNotSubmitted.
199+
showProposedItem(tr, theRow, valToShow, json.testResults);
213200
}
214201
if (CLDR_VOTE_DEBUG) {
215202
console.log(
@@ -232,7 +219,7 @@ function handleVoteNotSubmitted(json, tr, theRow, button, valToShow) {
232219
(json.statusAction && json.statusAction != "ALLOW") ||
233220
(json.testResults && (json.testWarnings || json.testErrors))
234221
) {
235-
showProposedItem(tr.inputTd, tr, theRow, valToShow, json.testResults, json);
222+
showProposedItem(tr, theRow, valToShow, json.testResults, json);
236223
}
237224
button.className = "ichoice-o";
238225
button.checked = false;
@@ -285,61 +272,18 @@ function getSubmitUrl(xpstrid) {
285272

286273
/**
287274
* Show an item that's not in the saved data, but has been proposed newly by the user.
288-
* Called only by loadHandler in handleWiredClick.
289275
* Used for "+" button in table.
276+
*
277+
* Caution: if called from handleVoteSubmitted, the fifth argument (json) is undefined
278+
* (even though there is json from the server response), and that appears to be necessary
279+
* for this function to work right, as it stands. The fifth argument (json) is only defined
280+
* when called from handleVoteNotSubmitted. This function cries out to be thoroughly refactored,
281+
* but that may only be feasible in conjunction with a thorough analysis or refactoring of the
282+
* back end.
290283
*/
291-
function showProposedItem(inTd, tr, theRow, value, tests, json) {
292-
// Find where our value went.
293-
var ourItem = cldrSurvey.findItemByValue(theRow.items, value);
294-
var testKind = getTestKind(tests);
295-
var ourDiv = null;
296-
var wrap;
297-
if (!ourItem) {
298-
/*
299-
* This may happen if, for example, the user types a space (" ") in
300-
* the input pop-up window and presses Enter. The value has been rejected
301-
* by the server. Then we show an additional pop-up window with the error message
302-
* from the server like "Input Processor Error: DAIP returned a 0 length string"
303-
*/
304-
ourDiv = document.createElement("div");
305-
var newButton = cldrSurvey.cloneAnon(
306-
document.getElementById("proto-button")
307-
);
308-
const otherCell = tr.querySelector(".othercell");
309-
if (otherCell && tr.myProposal) {
310-
otherCell.removeChild(tr.myProposal);
311-
}
312-
tr.myProposal = ourDiv;
313-
tr.myProposal.value = value;
314-
tr.myProposal.button = newButton;
315-
if (newButton) {
316-
if (value === "") {
317-
newButton.value = cldrTable.EMPTY_ELEMENT_VALUE; // Special case for ''
318-
} else {
319-
newButton.value = value;
320-
}
321-
if (tr.lastOn) {
322-
tr.lastOn.checked = false;
323-
tr.lastOn.className = "ichoice-o";
324-
}
325-
wireUpButton(newButton, tr, theRow, "[retry]", {
326-
value: value,
327-
});
328-
wrap = wrapRadio(newButton);
329-
ourDiv.appendChild(wrap);
330-
}
331-
var h3 = document.createElement("span");
332-
appendItem(h3, value, "value");
333-
ourDiv.appendChild(h3);
334-
if (otherCell) {
335-
otherCell.appendChild(tr.myProposal);
336-
}
337-
} else {
338-
ourDiv = ourItem.div;
339-
}
284+
function showProposedItem(tr, theRow, value, tests, json) {
285+
const ourItem = cldrSurvey.findItemByValue(theRow.items, value);
340286
if (json && !cldrSurvey.parseStatusAction(json.statusAction).vote) {
341-
ourDiv.className = "d-item-err";
342-
343287
const replaceErrors =
344288
json.statusAction === "FORBID_PERMANENT_WITHOUT_FORUM";
345289
if (replaceErrors) {
@@ -355,82 +299,68 @@ function showProposedItem(inTd, tr, theRow, value, tests, json) {
355299
];
356300
}
357301

302+
const valueMessage = value === "" ? "Abstention" : "Value: " + value;
303+
358304
// TODO: modernize to obviate cldrSurvey.testsToHtml
359305
// Reference: https://unicode-org.atlassian.net/browse/CLDR-18013
360-
const description = cldrSurvey.testsToHtml(tests);
361-
cldrNotify.openWithHtml("Response to voting", description);
306+
const testDescription = cldrSurvey.testsToHtml(tests);
362307
if (ourItem || (replaceErrors && value === "") /* Abstain */) {
363-
const message = cldrText.sub(
364-
"StatusAction_msg",
365-
[cldrText.get("StatusAction_" + json.statusAction)],
366-
"p",
367-
""
368-
);
369-
const description = cldrText.sub(
370-
"StatusAction_popupmsg",
371-
[cldrText.get("StatusAction_" + json.statusAction), theRow.code],
372-
"p",
373-
""
374-
);
375-
cldrNotify.error(message, description);
308+
const statusAction = cldrText.get("StatusAction_" + json.statusAction);
309+
const message = cldrText.sub("StatusAction_msg", [statusAction]);
310+
/*
311+
* This may happen if, for example, the user types a space (" ") in
312+
* the input pop-up window and presses Enter. The value has been rejected
313+
* by the server. Then we show an additional pop-up window with the error message
314+
* from the server like "Input Processor Error: DAIP returned a 0 length string"
315+
*/
316+
const statusMessage = cldrText.sub("StatusAction_popupmsg", [
317+
statusAction,
318+
theRow.code,
319+
]);
320+
const description =
321+
valueMessage + "<br>" + statusMessage + " " + testDescription;
322+
cldrNotify.openWithHtml(message, description);
323+
} else {
324+
const description = valueMessage + "<br>" + testDescription;
325+
cldrNotify.openWithHtml("Response to voting", description);
376326
}
377327
return;
378-
} else if (json && json.didNotSubmit) {
379-
ourDiv.className = "d-item-err";
328+
} else if (json?.didNotSubmit) {
380329
const description = "Did not submit this value: " + json.didNotSubmit;
381330
cldrNotify.error("Not submitted", description);
382331
return;
383-
} else {
384-
cldrTable.setDivClassSelected(ourDiv, testKind);
385332
}
386-
333+
// Note: it is possible to arrive here (as of 2025-09), for example, if the vote was accepted but has warnings
334+
const ourDiv = ourItem ? ourItem.div : document.createElement("div");
335+
const testKind = getTestKind(tests);
336+
cldrTable.setDivClassSelected(ourDiv, testKind);
387337
if (testKind || !ourItem) {
388-
var div3 = document.createElement("div");
389-
var newHtml = "";
390-
newHtml += cldrSurvey.testsToHtml(tests);
391-
338+
const div3 = document.createElement("div");
392339
if (!ourItem) {
393-
var h3 = document.createElement("h3");
340+
const h3 = document.createElement("h3");
394341
appendItem(h3, value, "value");
395342
h3.className = "span";
396343
div3.appendChild(h3);
397344
}
398-
var newDiv = document.createElement("div");
345+
const newDiv = document.createElement("div");
399346
div3.appendChild(newDiv);
400-
newDiv.innerHTML = newHtml;
347+
newDiv.innerHTML = cldrSurvey.testsToHtml(tests);
401348
if (json && !parseStatusAction(json.statusAction).vote) {
402-
div3.appendChild(
403-
cldrDom.createChunk(
404-
cldrText.sub(
405-
"StatusAction_msg",
406-
[cldrText.get("StatusAction_" + json.statusAction)],
407-
"p",
408-
""
409-
)
410-
)
411-
);
349+
const text = cldrText.sub("StatusAction_msg", [
350+
cldrText.get("StatusAction_" + json.statusAction),
351+
]);
352+
div3.appendChild(cldrDom.createChunk(text, "p", ""));
412353
}
413354

414355
div3.popParent = tr;
415356

416357
// will replace any existing function
417-
var ourShowFn = function (showDiv) {
418-
var retFn;
419-
if (ourItem && ourItem.showFn) {
420-
retFn = ourItem.showFn(showDiv);
421-
} else {
422-
retFn = null;
423-
}
424-
if (tr.myProposal && value == tr.myProposal.value) {
425-
// make sure it wasn't submitted twice
426-
showDiv.appendChild(div3);
427-
}
428-
return retFn;
358+
const ourShowFn = function (showDiv) {
359+
return ourItem?.showFn ? ourItem.showFn(showDiv) : null;
429360
};
430361
cldrTable.listen(null, tr, ourDiv, ourShowFn);
431362
cldrInfo.showRowObjFunc(tr, ourDiv, ourShowFn);
432363
}
433-
return false;
434364
}
435365

436366
/**

0 commit comments

Comments
 (0)