Skip to content

Commit

Permalink
Merge pull request #2294 from somiaj/remove-action-scope
Browse files Browse the repository at this point in the history
Remove action scope and add action form validation.
  • Loading branch information
pstaabp authored Feb 14, 2024
2 parents 9628fe0 + fda7619 commit 4a78f81
Show file tree
Hide file tree
Showing 35 changed files with 679 additions and 269 deletions.
152 changes: 152 additions & 0 deletions htdocs/js/AchievementList/achievementlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
(() => {
// Action form validation.
const is_achievement_selected = () => {
for (const achievement of document.getElementsByName('selected_achievements')) {
if (achievement.checked) return true;
}
document.getElementById('select_achievement_err_msg')?.classList.remove('d-none');
document.getElementById('achievement-table')?.addEventListener(
'change',
() => {
document.getElementById('select_achievement_err_msg')?.classList.add('d-none');
for (const id of ['edit_select', 'assign_select', 'export_select', 'score_select']) {
document.getElementById(id)?.classList.remove('is-invalid');
}
},
{ once: true }
);
return false;
};

document.getElementById('achievement-list')?.addEventListener('submit', (e) => {
const action = document.getElementById('current_action')?.value || '';
if (action === 'edit') {
const edit_select = document.getElementById('edit_select');
if (edit_select.value === 'selected' && !is_achievement_selected()) {
e.preventDefault();
e.stopPropagation();
edit_select.classList.add('is-invalid');
edit_select.addEventListener(
'change',
() => {
document.getElementById('select_achievement_err_msg')?.classList.add('d-none');
document.getElementById('edit_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'assign') {
const assign_select = document.getElementById('assign_select');
if (assign_select.value === 'selected' && !is_achievement_selected()) {
e.preventDefault();
e.stopPropagation();
assign_select.classList.add('is-invalid');
assign_select.addEventListener(
'change',
() => {
document.getElementById('select_achievement_err_msg')?.classList.add('d-none');
document.getElementById('assign_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'import') {
const import_file = document.getElementById('import_file_select');
if (!import_file.value.endsWith('.axp')) {
e.preventDefault();
e.stopPropagation();
document.getElementById('import_file_err_msg')?.classList.remove('d-none');
import_file.classList.add('is-invalid');
import_file.addEventListener(
'change',
() => {
document.getElementById('import_file_err_msg')?.classList.add('d-none');
document.getElementById('import_file_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'export') {
const export_select = document.getElementById('export_select');
if (export_select.value === 'selected' && !is_achievement_selected()) {
e.preventDefault();
e.stopPropagation();
export_select.classList.add('is-invalid');
export_select.addEventListener(
'change',
() => {
document.getElementById('select_achievement_err_msg')?.classList.add('d-none');
document.getElementById('export_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'score') {
const score_select = document.getElementById('score_select');
if (export_select.value === 'selected' && !is_achievement_selected()) {
e.preventDefault();
e.stopPropagation();
score_select.classList.add('is-invalid');
score_select.addEventListener(
'change',
() => {
document.getElementById('select_achievement_err_msg')?.classList.add('d-none');
document.getElementById('score_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'create') {
const create_text = document.getElementById('create_text');
if (create_text.value === '') {
e.preventDefault();
e.stopPropagation();
document.getElementById('create_file_err_msg')?.classList.remove('d-none');
create_text.classList.add('is-invalid');
create_text.addEventListener(
'change',
() => {
document.getElementById('create_file_err_msg')?.classList.add('d-none');
document.getElementById('create_text')?.classList.remove('is-invalid');
},
{ once: true }
);
} else if (document.getElementById('create_select')?.selectedIndex == 1 && !is_achievement_selected()) {
e.preventDefault();
e.stopPropagation();
}
} else if (action === 'delete') {
const delete_confirm = document.getElementById('delete_select');
if (!is_achievement_selected()) {
e.preventDefault();
e.stopPropagation();
} else if (delete_confirm.value != 'yes') {
e.preventDefault();
e.stopPropagation();
document.getElementById('delete_confirm_err_msg')?.classList.remove('d-none');
delete_confirm.classList.add('is-invalid');
delete_confirm.addEventListener(
'change',
() => {
document.getElementById('delete_select')?.classList.remove('is-invalid');
document.getElementById('delete_confirm_err_msg')?.classList.add('d-none');
},
{ once: true }
);
}
}
});

// Remove all error messages when changing tabs.
for (const tab of document.querySelectorAll('a[data-bs-toggle="tab"]')) {
tab.addEventListener('shown.bs.tab', () => {
const actionForm = document.getElementById('achievement-list');
for (const err_msg of actionForm.querySelectorAll('div[id$=_err_msg]')) {
err_msg.classList.add('d-none');
}
for (const invalid of actionForm.querySelectorAll('.is-invalid')) {
invalid.classList.remove('is-invalid');
}
});
}
})();
207 changes: 189 additions & 18 deletions htdocs/js/ProblemSetList/problemsetlist.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,198 @@
(() => {
// Show the filter error message if the 'Filter' button is clicked when matching set IDs without having entered
// a text to filter on.
document.getElementById('take_action')?.addEventListener('click',
(e) => {
const filter_err_msg = document.getElementById('filter_err_msg');
// Action form validation.
const is_set_selected = () => {
for (const set of document.getElementsByName('selected_sets')) {
if (set.checked) return true;
}
document.getElementById('select_set_err_msg')?.classList.remove('d-none');
document.getElementById('set_table_id')?.addEventListener(
'change',
() => {
document.getElementById('select_set_err_msg')?.classList.add('d-none');
for (const id of [
'filter_select',
'edit_select',
'publish_filter_select',
'export_select',
'score_select'
]) {
document.getElementById(id)?.classList.remove('is-invalid');
}
},
{ once: true }
);
return false;
};

if (filter_err_msg &&
document.getElementById('current_action')?.value === 'filter' &&
document.getElementById('filter_select')?.selectedIndex === 3 &&
document.getElementById('filter_text')?.value === '') {
filter_err_msg.classList.remove('d-none');
document.getElementById('problemsetlist')?.addEventListener('submit', (e) => {
const action = document.getElementById('current_action')?.value || '';
if (action === 'filter') {
const filter = document.getElementById('filter_select')?.selectedIndex || 0;
const filter_text = document.getElementById('filter_text');
if (filter === 1 && !is_set_selected()) {
e.preventDefault();
e.stopPropagation();
document.getElementById('filter_select')?.addEventListener(
'change',
() => {
document.getElementById('select_set_err_msg')?.classList.add('d-none');
},
{ once: true }
);
} else if (filter === 2 && filter_text.value === '') {
e.preventDefault();
e.stopPropagation();
document.getElementById('filter_err_msg')?.classList.remove('d-none');
filter_text.classList.add('is-invalid');
filter_text.addEventListener(
'change',
() => {
document.getElementById('filter_err_msg')?.classList.add('d-none');
document.getElementById('filter_text')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'edit') {
const edit_select = document.getElementById('edit_select');
if (edit_select.value === 'selected' && !is_set_selected()) {
e.preventDefault();
e.stopPropagation();
edit_select.classList.add('is-invalid');
edit_select.addEventListener(
'change',
() => {
document.getElementById('select_set_err_msg')?.classList.add('d-none');
document.getElementById('edit_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'publish') {
const publish_select = document.getElementById('publish_filter_select');
if (publish_select.value === 'selected' && !is_set_selected()) {
e.preventDefault();
e.stopPropagation();
publish_select.classList.add('is-invalid');
publish_select.addEventListener(
'change',
() => {
document.getElementById('select_set_err_msg')?.classList.add('d-none');
document.getElementById('publish_filter_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'export') {
const export_select = document.getElementById('export_select');
if (export_select.value === 'selected' && !is_set_selected()) {
e.preventDefault();
e.stopPropagation();
export_select.classList.add('is-invalid');
export_select.addEventListener(
'change',
() => {
document.getElementById('select_set_err_msg')?.classList.add('d-none');
document.getElementById('export_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'save_export') {
if (!is_set_selected()) {
e.preventDefault();
e.stopPropagation();
}
} else if (action === 'score') {
const score_select = document.getElementById('score_select');
if (score_select.value === 'selected' && !is_set_selected()) {
e.preventDefault();
e.stopPropagation();
score_select.classList.add('is-invalid');
score_select.addEventListener(
'change',
() => {
document.getElementById('select_set_err_msg')?.classList.add('d-none');
document.getElementById('score_select')?.classList.remove('is-invalid');
},
{ once: true }
);
}
} else if (action === 'import') {
const import_select = document.getElementById('import_source_select');
if (!import_select.value.endsWith('.def')) {
e.preventDefault();
e.stopPropagation();
document.getElementById('import_file_err_msg')?.classList.remove('d-none');
import_select.classList.add('is-invalid');
import_select.addEventListener(
'change',
() => {
document.getElementById('import_source_select')?.classList.remove('is-invalid');
document.getElementById('import_file_err_msg')?.classList.add('d-none');
},
{ once: true }
);
}
} else if (action === 'create') {
const create_text = document.getElementById('create_text');
if (create_text.value === '') {
e.preventDefault();
e.stopPropagation();
document.getElementById('create_file_err_msg')?.classList.remove('d-none');
create_text.classList.add('is-invalid');
create_text.addEventListener(
'change',
() => {
document.getElementById('create_file_err_msg')?.classList.add('d-none');
document.getElementById('create_text')?.classList.remove('is-invalid');
},
{ once: true }
);
} else if (document.getElementById('create_select')?.selectedIndex == 1 && !is_set_selected()) {
e.preventDefault();
e.stopPropagation();
}
} else if (action === 'delete') {
const delete_confirm = document.getElementById('delete_select');
if (!is_set_selected()) {
e.preventDefault();
e.stopPropagation();
} else if (delete_confirm.value != 'yes') {
e.preventDefault();
e.stopPropagation();
document.getElementById('delete_confirm_err_msg')?.classList.remove('d-none');
delete_confirm.classList.add('is-invalid');
delete_confirm.addEventListener(
'change',
() => {
document.getElementById('delete_select')?.classList.remove('is-invalid');
document.getElementById('delete_confirm_err_msg')?.classList.add('d-none');
},
{ once: true }
);
}
}
);
});

// Remove all error messages when changing tabs.
for (const tab of document.querySelectorAll('a[data-bs-toggle="tab"]')) {
tab.addEventListener('shown.bs.tab', () => {
const actionForm = document.getElementById('problemsetlist');
for (const err_msg of actionForm.querySelectorAll('div[id$=_err_msg]')) {
err_msg.classList.add('d-none');
}
for (const invalid of actionForm.querySelectorAll('.is-invalid')) {
invalid.classList.remove('is-invalid');
}
});
}

// Toggle the display of the filter elements as the filter select changes.
const filter_select = document.getElementById('filter_select');
const filter_elements = document.getElementById('filter_elements');
const filterElementToggle = () => {
if (filter_select?.selectedIndex == 3) filter_elements.style.display = 'flex';
if (filter_select?.selectedIndex == 2) filter_elements.style.display = 'flex';
else filter_elements.style.display = 'none';
};

Expand Down Expand Up @@ -65,17 +237,16 @@
// Initialize the date/time picker for the import form.
const importDateShift = document.getElementById('import_date_shift');
if (importDateShift) {

luxon.Settings.defaultLocale = importDateShift.dataset.locale ?? 'en';

// Compute the time difference between the current browser timezone and the course timezone.
// flatpickr gives the time in the browser's timezone, and this is used to adjust to the course timezone.
// Note that this is in seconds.
const timezoneAdjustment = (
(new Date((new Date).toLocaleString('en-US'))).getTime() -
(new Date((new Date).toLocaleString('en-US',
{ timeZone: importDateShift.dataset.timezone ?? 'America/New_York' }))).getTime()
);
const timezoneAdjustment =
new Date(new Date().toLocaleString('en-US')).getTime() -
new Date(
new Date().toLocaleString('en-US', { timeZone: importDateShift.dataset.timezone ?? 'America/New_York' })
).getTime();

const fp = flatpickr(importDateShift.parentNode, {
allowInput: true,
Expand Down
Loading

0 comments on commit 4a78f81

Please sign in to comment.