Files
edx-platform/lms/static/js/student_account/tos_modal.js
Uman Shahzad cb034d4f2f Implement client-side registration form validation.
Input forms that need validation will have AJAX requests
performed to get validation decisions live.

All but a few important and common form fields perform
generic validation; these will need a back-end handler
in the future in order to have them validated through AJAX requests.

Information is conveyed on focus and blur for both
errors and successes.
2017-08-03 00:22:25 +05:00

180 lines
7.0 KiB
JavaScript

/**
* Modal for displaying the Terms of Service in the Register page.
*/
(function($, gettext) {
'use strict';
var focusableElementsSelector = [
'a[href], area[href], input:not([disabled]), select:not([disabled]),',
'textarea:not([disabled]), button:not([disabled]), iframe, object, embed,',
'*[tabindex], *[contenteditable]'
].join(' ');
var disableTabIndexingOn = function(containerSelector) {
var $container = $(containerSelector),
$focusableItems = $container.find('*').filter(focusableElementsSelector).filter(':visible');
$container.attr('aria-hidden', 'true');
$focusableItems.attr('tabindex', '-1');
};
var enableTabIndexingOn = function(containerSelector) {
var $container = $(containerSelector),
$focusableItems = $container.find('*').filter(focusableElementsSelector).filter(':visible');
$container.attr('aria-hidden', 'false');
$focusableItems.attr('tabindex', '0');
};
var showModal = function(modalSelector) {
$(modalSelector).attr('aria-hidden', 'false');
$(modalSelector).show();
disableTabIndexingOn('.window-wrap');
// Prevent scrolling of the background
$('body').addClass('open-modal');
};
var hideModal = function(modalSelector, tosLinkSelector) {
$(modalSelector).attr('aria-hidden', 'true');
$(modalSelector).hide();
enableTabIndexingOn('.window-wrap');
$('body').removeClass('open-modal');
$(modalSelector).find('iframe').remove();
$(tosLinkSelector).focus();
};
var buildModal = function(modalClass, contentClass, closeButtonClass) {
// Create the modal container
var modalTitle = gettext('Terms of Service and Honor Code'),
closeLabel = gettext('Close'),
titleId = 'modal-header-text',
$modal = $('<div>', {
class: modalClass,
'aria-hidden': 'true'
}),
$content = $('<div>', {
class: contentClass,
role: 'dialog',
'aria-modal': 'true',
'aria-labelledby': titleId
}),
$header = $('<div>', {
class: 'header'
}),
$closeButton = $('<button>', {
'aria-label': closeLabel,
class: closeButtonClass
}),
$title = $('<h1>', {
id: titleId
});
$closeButton.text(closeLabel);
$title.text(modalTitle);
$header.append($title);
$header.append($closeButton);
$content.append($header);
$modal.append($content);
return $modal;
};
var buildIframe = function(link, modalSelector, contentSelector, tosLinkSelector) {
// Create an iframe with contents from the link and set its height to match the content area
return $('<iframe>', {
title: 'Terms of Service and Honor Code',
src: link.href,
load: function() {
var $iframeHead = $(this).contents().find('head'),
$iframeBody = $(this).contents().find('body');
// Overwrite styles in child page to hide top navigation and footer
var $style = $('<style>', {type: 'text/css'}),
styleContent = [
'/* Default honor.html template */',
'.nav-skip, header#global-navigation, .wrapper-footer {',
' display: none;',
'}',
'.container.about {',
' min-width: auto;',
'}',
'/* https://www.edx.org/edx-terms-service */',
'.edx-header, #skip-link, footer {',
' display: none;',
'}',
'.region-banner, #breadcrumb + .region-column-wrapper, .edx-header + .region-column-wrapper {',
' margin-top: 0;',
' padding-top: 10px;',
'}',
'body.node-type-page h1.field-page-tagline {',
' font-size: 16px;',
'}',
'/* edx-themes */',
'.page-heading, .footer-main {',
' display: none;',
'}'
].join('\n');
$style.text(styleContent);
$iframeHead.append($style);
// Set the iframe's height to fill the available space
$(this).css({
height: $(contentSelector).height()
});
// Hide the modal when ESC is pressed and the iframe is focused
$iframeBody.keydown(function(event) {
if ($(modalSelector).is(':visible') && event.keyCode === 27) {
event.preventDefault();
hideModal(modalSelector, tosLinkSelector);
}
});
}
});
};
$(document).ready(function() {
var tosLinkSelector = '.checkbox-honor_code .supplemental-link a',
closeButtonClass = 'modal-close-button',
closeButtonSelector = '.' + closeButtonClass,
contentClass = 'modal-content',
contentSelector = '.' + contentClass,
modalClass = 'tos-modal',
modalSelector = '.' + modalClass;
$('body').on('click', tosLinkSelector, function(event) {
var link = event.target,
$modal,
$iframe;
event.preventDefault();
// Ignore disabled TOS
if (link.href.endsWith('#')) {
return;
}
// Add the modal if it doesn't exist yet
if ($(modalSelector).length < 1) {
$modal = buildModal(modalClass, contentClass, closeButtonClass);
$('body').append($modal);
}
// Add a new iframe to the content area
$iframe = buildIframe(link, modalSelector, contentSelector, tosLinkSelector);
$(contentSelector).append($iframe);
showModal(modalSelector);
$(closeButtonSelector).focus();
});
$('body').on('click', closeButtonSelector, function() {
hideModal(modalSelector, tosLinkSelector);
});
// Hide the modal when clicking outside its content
$('body').on('click', modalSelector, function(event) {
if ($(event.target).hasClass(modalClass)) {
hideModal(modalSelector, tosLinkSelector);
}
});
// Hide the modal when ESC is pressed and the modal is focused
$(document).keydown(function(event) {
if ($(modalSelector).is(':visible') && event.keyCode === 27) {
event.preventDefault();
hideModal(modalSelector, tosLinkSelector);
}
});
});
}(jQuery, gettext));