Skip to content

Commit 82a943d

Browse files
authored
Add data help option (#4611)
* add data-help option to modify help text based on a select option * fix data-help tests for all widgets, ensuring that we can override default values and control the text if there is no default * add resistance to malformed directives, and tests that successfully ignore them
1 parent 38abb5a commit 82a943d

File tree

2 files changed

+322
-2
lines changed

2 files changed

+322
-2
lines changed

apps/dashboard/app/javascript/dynamic_forms.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ const setHandlerCache = [];
2020
// hide handler cache is a map in the form '{ from: [hideThing1, hideThing2] }'
2121
const hideHandlerCache = {};
2222
const labelHandlerCache = {};
23-
23+
const helpHandlerCache = {};
2424
// Lookup tables for setting min & max values
2525
// for different directives.
2626
const minMaxLookup = {};
2727
const setValueLookup = {};
2828
const hideLookup = {};
2929
const labelLookup = {};
30+
const helpLookup = {};
3031

3132
// the regular expression for mountain casing
3233
const mcRex = /[-_]([a-z])|([_-][0-9])|([\/])/g;
@@ -148,6 +149,8 @@ function makeChangeHandlers(prefix){
148149
addHideHandler(element['id'], opt.value, key, data[key]);
149150
} else if(key.startsWith('label')) {
150151
addLabelHandler(element['id'], opt.value, key, data[key]);
152+
} else if(key.startsWith('help')) {
153+
addHelpHandler(element['id'], opt.value, key, data[key]);
151154
}
152155
});
153156
}
@@ -225,6 +228,46 @@ function addLabelHandler(optionId, option, key, configValue) {
225228
updateLabel(changeId, changeElement, key);
226229
};
227230

231+
function getNewHelp(changeElement, key) {
232+
const selectedOptionHelpIndex = changeElement[0].selectedIndex;
233+
const selectedOptionHelp = changeElement[0].options[selectedOptionHelpIndex];
234+
return selectedOptionHelp.dataset[key];
235+
}
236+
237+
function updateHelp(changeId, changeElement, key) {
238+
const helpContent = getNewHelp(changeElement, key);
239+
if (helpContent === undefined || changeId === undefined) return;
240+
const wrapper_id = `#${changeId}_wrapper`;
241+
var helpElement = $(`${wrapper_id} small p`);
242+
if (helpElement.length == 0) {
243+
const small = document.createElement('small');
244+
small.classList.add('form-text', 'text-muted');
245+
helpElement = document.createElement('p');
246+
$(helpElement).appendTo($(small).appendTo($(wrapper_id).children()[0]));
247+
}
248+
$(helpElement).text(helpContent);
249+
ariaStream(`Changed help text on ${getWidgetInfo(changeId)} to ${helpContent}`);
250+
}
251+
252+
function addHelpHandler(optionId, option, key, configValue) {
253+
const changeId = idFromToken(key.replace(/^help/, ''));
254+
const changeElement = $(`#${optionId}`);
255+
256+
if(helpLookup[optionId] === undefined) helpLookup[optionId] = new Table(changeId, undefined);
257+
const table = helpLookup[optionId];
258+
table.put(changeId, option, configValue);
259+
260+
if(helpHandlerCache[optionId] === undefined) helpHandlerCache[optionId] = [];
261+
262+
if(!helpHandlerCache[optionId].includes(changeId)) {
263+
helpHandlerCache[optionId].push(changeId);
264+
changeElement.on('change', (event) => {
265+
updateHelp(changeId, changeElement, key);
266+
});
267+
};
268+
269+
updateHelp(changeId, changeElement, key);
270+
};
228271
/**
229272
*
230273
* @param {*} subjectId batch_connect_session_context_node_type

apps/dashboard/test/system/batch_connect_test.rb

Lines changed: 278 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,284 @@ def check_visibility(hidden_id, expect_hidden)
881881

882882
data_hide_checkbox_test(form, 'checkbox_test', 'gpus', true)
883883
end
884-
884+
885+
def data_help_basic_test(form)
886+
Dir.mktmpdir do |dir|
887+
make_bc_app(dir, form)
888+
visit new_batch_connect_session_context_url('sys/app')
889+
890+
widget_selector = '#batch_connect_session_context_hard_choice'
891+
assert_selector(widget_selector)
892+
widget = find(widget_selector)
893+
parent = widget.all(:xpath, 'ancestor::div[contains(@class,"mb-3")]').first
894+
895+
help = parent.find(':scope > small')
896+
897+
help.assert_text('Choose yes')
898+
899+
select 'Second', from: 'batch_connect_session_context_group'
900+
help.assert_text('Choose no')
901+
902+
select 'Third', from: 'batch_connect_session_context_group'
903+
help.assert_text('Choose whatever')
904+
905+
select 'First', from: 'batch_connect_session_context_group'
906+
help.assert_text('Choose yes')
907+
end
908+
end
909+
910+
test 'data-help sets number field help field when unset' do
911+
form = <<~HEREDOC
912+
---
913+
cluster:
914+
- owens
915+
form:
916+
- group
917+
- hard_choice
918+
attributes:
919+
group:
920+
widget: 'select'
921+
label: Membership group
922+
help: 'you can find your group in your personal page'
923+
options:
924+
- ['First', data-help-hard-choice: 'Choose yes']
925+
- ['Second', data-help-hard-choice: 'Choose no']
926+
- ['Third', data-help-hard-choice: 'Choose whatever']
927+
hard_choice:
928+
widget: 'number_field'
929+
HEREDOC
930+
data_help_basic_test(form)
931+
end
932+
933+
test 'data-help sets text area help field when unset' do
934+
form = <<~HEREDOC
935+
---
936+
cluster:
937+
- owens
938+
form:
939+
- group
940+
- hard_choice
941+
attributes:
942+
group:
943+
widget: 'select'
944+
label: Membership group
945+
help: 'you can find your group in your personal page'
946+
options:
947+
- ['First', data-help-hard-choice: 'Choose yes']
948+
- ['Second', data-help-hard-choice: 'Choose no']
949+
- ['Third', data-help-hard-choice: 'Choose whatever']
950+
hard_choice:
951+
widget: 'text_area'
952+
HEREDOC
953+
data_help_basic_test(form)
954+
end
955+
956+
test 'data-help sets select help field when unset' do
957+
form = <<~HEREDOC
958+
---
959+
cluster:
960+
- owens
961+
form:
962+
- group
963+
- hard_choice
964+
attributes:
965+
group:
966+
widget: 'select'
967+
label: Membership group
968+
help: 'you can find your group in your personal page'
969+
options:
970+
- ['First', data-help-hard-choice: 'Choose yes']
971+
- ['Second', data-help-hard-choice: 'Choose no']
972+
- ['Third', data-help-hard-choice: 'Choose whatever']
973+
hard_choice:
974+
widget: 'select'
975+
options:
976+
- ["Yes"]
977+
- ["No"]
978+
- ["Maybe"]
979+
HEREDOC
980+
data_help_basic_test(form)
981+
end
982+
983+
test 'data-help sets check-box area help field when unset' do
984+
form = <<~HEREDOC
985+
---
986+
cluster:
987+
- owens
988+
form:
989+
- group
990+
- hard_choice
991+
attributes:
992+
group:
993+
widget: 'select'
994+
label: Membership group
995+
help: 'you can find your group in your personal page'
996+
options:
997+
- ['First', data-help-hard-choice: 'Choose yes']
998+
- ['Second', data-help-hard-choice: 'Choose no']
999+
- ['Third', data-help-hard-choice: 'Choose whatever']
1000+
hard_choice:
1001+
widget: 'check_box'
1002+
HEREDOC
1003+
data_help_basic_test(form)
1004+
end
1005+
1006+
test 'data-help sets radio button help field when unset' do
1007+
form = <<~HEREDOC
1008+
---
1009+
cluster:
1010+
- owens
1011+
form:
1012+
- group
1013+
- hard_choice
1014+
attributes:
1015+
group:
1016+
widget: 'select'
1017+
label: Membership group
1018+
help: 'you can find your group in your personal page'
1019+
options:
1020+
- ['First', data-help-hard-choice: 'Choose yes']
1021+
- ['Second', data-help-hard-choice: 'Choose no']
1022+
- ['Third', data-help-hard-choice: 'Choose whatever']
1023+
hard_choice:
1024+
widget: 'radio_button'
1025+
options:
1026+
- ["Yes", "1"]
1027+
- ["No", "0"]
1028+
- ["Maybe", "i"]
1029+
HEREDOC
1030+
data_help_basic_test(form)
1031+
end
1032+
1033+
test 'data-help sets path selector help field when unset' do
1034+
form = <<~HEREDOC
1035+
---
1036+
cluster:
1037+
- owens
1038+
form:
1039+
- group
1040+
- hard_choice
1041+
attributes:
1042+
group:
1043+
widget: 'select'
1044+
label: Membership group
1045+
help: 'you can find your group in your personal page'
1046+
options:
1047+
- ['First', data-help-hard-choice: 'Choose yes']
1048+
- ['Second', data-help-hard-choice: 'Choose no']
1049+
- ['Third', data-help-hard-choice: 'Choose whatever']
1050+
hard_choice:
1051+
widget: 'path_selector'
1052+
HEREDOC
1053+
data_help_basic_test(form)
1054+
end
1055+
1056+
# We may want to change this behavior later, but this records current state
1057+
test 'data-help overrides initial setting for all options' do
1058+
form = <<~HEREDOC
1059+
---
1060+
cluster:
1061+
- owens
1062+
form:
1063+
- group
1064+
- hard_choice
1065+
attributes:
1066+
group:
1067+
widget: 'select'
1068+
label: Membership group
1069+
help: 'you can find your group in your personal page'
1070+
options:
1071+
- ['First']
1072+
- ['Second', data-help-hard-choice: 'Choose no']
1073+
- ['Third', data-help-hard-choice: 'Choose yes']
1074+
hard_choice:
1075+
widget: 'radio_button'
1076+
label: 'Make your choice'
1077+
help: 'Choose anything'
1078+
options:
1079+
- ["Yes", "1"]
1080+
- ["No", "0"]
1081+
- ["Maybe", "i"]
1082+
HEREDOC
1083+
Dir.mktmpdir do |dir|
1084+
make_bc_app(dir, form)
1085+
visit new_batch_connect_session_context_url('sys/app')
1086+
1087+
widget_selector = '#batch_connect_session_context_hard_choice'
1088+
assert_selector(widget_selector)
1089+
widget = find(widget_selector)
1090+
parent = widget.find(:xpath, '..')
1091+
1092+
help = parent.find(':scope > small')
1093+
help.assert_text('Choose anything')
1094+
1095+
select 'Third', from: 'batch_connect_session_context_group'
1096+
help.assert_text('Choose yes')
1097+
1098+
select 'First', from: 'batch_connect_session_context_group'
1099+
help.assert_text('Choose yes')
1100+
1101+
select 'Second', from: 'batch_connect_session_context_group'
1102+
help.assert_text('Choose no')
1103+
1104+
select 'First', from: 'batch_connect_session_context_group'
1105+
help.assert_text('Choose no')
1106+
end
1107+
end
1108+
1109+
test 'data-help skips over malformed options' do
1110+
form = <<~HEREDOC
1111+
---
1112+
cluster:
1113+
- owens
1114+
form:
1115+
- group
1116+
- hard_choice
1117+
attributes:
1118+
group:
1119+
widget: 'select'
1120+
label: Membership group
1121+
help: 'you can find your group in your personal page'
1122+
options:
1123+
- ['First']
1124+
- ['Second', data-help-hard-choice: 'Choose no']
1125+
- ['Broken', data-help-bad-widget: 'oops']
1126+
- ['Third', data-help-hard-choice: 'Choose yes']
1127+
hard_choice:
1128+
widget: 'radio_button'
1129+
label: 'Make your choice'
1130+
help: 'Choose anything'
1131+
options:
1132+
- ["Yes", "1"]
1133+
- ["No", "0"]
1134+
- ["Maybe", "i"]
1135+
HEREDOC
1136+
Dir.mktmpdir do |dir|
1137+
make_bc_app(dir, form)
1138+
visit new_batch_connect_session_context_url('sys/app')
1139+
1140+
widget_selector = '#batch_connect_session_context_hard_choice'
1141+
assert_selector(widget_selector)
1142+
widget = find(widget_selector)
1143+
parent = widget.find(:xpath, '..')
1144+
1145+
help = parent.find(':scope > small')
1146+
help.assert_text('Choose anything')
1147+
1148+
select 'Third', from: 'batch_connect_session_context_group'
1149+
help.assert_text('Choose yes')
1150+
1151+
select 'Broken', from: 'batch_connect_session_context_group'
1152+
help.assert_text('Choose yes')
1153+
1154+
select 'Second', from: 'batch_connect_session_context_group'
1155+
help.assert_text('Choose no')
1156+
1157+
select 'Broken', from: 'batch_connect_session_context_group'
1158+
help.assert_text('Choose no')
1159+
end
1160+
end
1161+
8851162
test 'options with hyphens set min & max' do
8861163
visit new_batch_connect_session_context_url('sys/bc_jupyter')
8871164

0 commit comments

Comments
 (0)