Files
edx-platform/cms/templates/settings_advanced.html
Se Won Jang 11d260910f Implemented Validation for Course Advanced Setting
This commit adds validation for course advanced settings. Currently when course
administrators make invalid changes in the Settings/Advanced Settings tab,
they're not notified through a new modal window of the list of invalid settings
changes.

* Extending CourseMetadata
    - Previously, we only had update_from_json method in CourseMetadata.py,
      and it was only validating one field every POST request.
    - Now we have validate_and_update_from_json method that encapsulates the
      functionality of update_from_json into a validation call
    - To avoid discrepancy of validation standards between modules, validation
      uses the from_json method implemented to each field in xblock.

* Different Response in advanced settings ajax requests
    - After receiving a POST ajax request, course.py calls
      validate_and_update_from_json, and sends a json object of either:
        1) valid course metadata model
        2) error objects

* Error Messages shown in validation-error-modal
    - error objects passed through ajax are shown in a separate modal.
2014-08-26 11:24:38 -07:00

140 lines
5.5 KiB
HTML

<%inherit file="base.html" />
<%def name="online_help_token()"><% return "advanced" %></%def>
<%namespace name='static' file='static_content.html'/>
<%!
from django.utils.translation import ugettext as _
from contentstore import utils
from django.utils.html import escapejs
%>
<%block name="title">${_("Advanced Settings")}</%block>
<%block name="bodyclass">is-signedin course advanced view-settings</%block>
<%block name="jsextra">
% for template_name in ["advanced_entry", "basic-modal", "modal-button", "validation-error-modal"]:
<script type="text/template" id="${template_name}-tpl">
<%static:include path="js/${template_name}.underscore" />
</script>
% endfor
<script type="text/javascript">
require(["domReady!", "jquery", "gettext", "js/models/settings/advanced", "js/views/settings/advanced"],
function(doc, $, gettext, AdvancedSettingsModel, AdvancedSettingsView) {
$("form :input").focus(function() {
$("label[for='" + this.id + "']").addClass("is-focused");
}).blur(function() {
$("label").removeClass("is-focused");
});
// proactively populate advanced b/c it has the filtered list and doesn't really follow the model pattern
var advancedModel = new AdvancedSettingsModel(${advanced_dict | n}, {parse: true});
advancedModel.url = "${advanced_settings_url}";
var editor = new AdvancedSettingsView({
el: $('.settings-advanced'),
model: advancedModel
});
editor.render();
$("#deprecated-settings").click(function() {
var $this = $(this);
var wrapperDeprecatedSetting = $('.wrapper-deprecated-setting');
var deprecatedSettingsLabel = $('.deprecated-settings-label');
if ($this.is(':checked')) {
wrapperDeprecatedSetting.addClass('is-set');
deprecatedSettingsLabel.text('${escapejs(_('Hide Deprecated Settings'))}');
editor.render_deprecated = true;
}
else {
wrapperDeprecatedSetting.removeClass('is-set');
deprecatedSettingsLabel.text('${escapejs(_('Show Deprecated Settings'))}');
editor.render_deprecated = false;
}
editor.render();
});
});
</script>
</%block>
<%block name="content">
<div class="wrapper-mast wrapper">
<header class="mast has-subtitle">
<h1 class="page-header">
<small class="subtitle">${_("Settings")}</small>
<span class="sr">&gt; </span>${_("Advanced Settings")}
</h1>
</header>
</div>
<div class="wrapper-content wrapper">
<section class="content">
<article class="content-primary" role="main">
<form id="settings_advanced" class="settings-advanced" method="post" action="">
<div class="message message-status confirm">
${_("Your policy changes have been saved.")}
</div>
<div class="message message-status error">
${_("There was an error saving your information. Please see below.")}
</div>
<section class="group-settings advanced-policies">
<header>
<h2 class="title-2">${_("Manual Policy Definition")}</h2>
</header>
<p class="instructions">${_("<strong>Warning</strong>: Do not modify these policies unless you are familiar with their purpose.")}</p>
<div class="wrapper-options">
<div class="wrapper-deprecated-setting">
<input id="deprecated-settings" class="deprecated-settings-toggle" type="checkbox" name="Show Deprecated">
<label for="deprecated-settings" class="deprecated-settings-label">${_("Show Deprecated Settings")}</label>
</div>
</div>
<ul class="list-input course-advanced-policy-list enum">
</ul>
</section>
</form>
</article>
<aside class="content-supplementary" role="complimentary">
<div class="bit">
<h3 class="title-3">${_("What do advanced settings do?")}</h3>
<p>${_("Advanced settings control specific course functionality. On this page, you can edit manual policies, which are JSON-based key and value pairs that control specific course settings.")}</p>
<p>${_("Any policies you modify here override all other information you've defined elsewhere in Studio. Do not edit policies unless you are familiar with both their purpose and syntax.")}</p>
<p>${_("{em_start}Note:{em_end} When you enter strings as policy values, ensure that you use double quotation marks (&quot;) around the string. Do not use single quotation marks (&apos;).").format(em_start='<strong>', em_end="</strong>")}</p>
</div>
<div class="bit">
% if context_course:
<%
details_url = utils.reverse_course_url('settings_handler', context_course.id)
grading_url = utils.reverse_course_url('grading_handler', context_course.id)
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
%>
<h3 class="title-3">${_("Other Course Settings")}</h3>
<nav class="nav-related">
<ul>
<li class="nav-item"><a href="${details_url}">${_("Details &amp; Schedule")}</a></li>
<li class="nav-item"><a href="${grading_url}">${_("Grading")}</a></li>
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
% if "split_test" in context_course.advanced_modules:
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
% endif
</ul>
</nav>
% endif
</div>
</aside>
</section>
</div>
</%block>