allow for adding/deleting of new 'policy' metadata in the edit subsection page
This commit is contained in:
@@ -158,11 +158,19 @@ def edit_subsection(request, location):
|
||||
# this should blow up if we don't find any parents, which would be erroneous
|
||||
parent = modulestore().get_item(parent_locs[0])
|
||||
|
||||
# remove all metadata from the generic dictionary that is presented in a more normalized UI
|
||||
|
||||
policy_metadata = dict((key,value) for key, value in item.metadata.iteritems()
|
||||
if key not in ['display_name', 'start', 'due', 'format'] and key not in item.system_metadata_fields)
|
||||
|
||||
logging.debug(policy_metadata)
|
||||
|
||||
return render_to_response('edit_subsection.html',
|
||||
{'subsection': item,
|
||||
'create_new_unit_template': Location('i4x', 'edx', 'templates', 'vertical', 'Empty'),
|
||||
'lms_link': lms_link,
|
||||
'parent_item' : parent
|
||||
'parent_item' : parent,
|
||||
'policy_metadata' : policy_metadata
|
||||
})
|
||||
|
||||
@login_required
|
||||
|
||||
@@ -36,8 +36,31 @@ $(document).ready(function() {
|
||||
$('.set-date').bind('click', showDateSetter);
|
||||
$('.remove-date').bind('click', removeDateSetter);
|
||||
|
||||
// add/remove policy metadata button click handlers
|
||||
$('.add-policy-data').bind('click', addPolicyMetadata);
|
||||
$('.remove-policy-data').bind('click', removePolicyMetadata);
|
||||
|
||||
});
|
||||
|
||||
function addPolicyMetadata(e) {
|
||||
e.preventDefault();
|
||||
var template =$('#add-new-policy-element-template > li');
|
||||
var newNode = template.clone();
|
||||
var _parent_el = $(this).parent('ol:.policy-list');
|
||||
newNode.insertBefore('.add-policy-data');
|
||||
$('.remove-policy-data').bind('click', removePolicyMetadata);
|
||||
}
|
||||
|
||||
function removePolicyMetadata(e) {
|
||||
e.preventDefault();
|
||||
policy_name = $(this).data('policy-name');
|
||||
var _parent_el = $(this).parent('li:.policy-list-element');
|
||||
//$(_parent_el).remove();
|
||||
|
||||
_parent_el.appendTo("#policy-to-delete");
|
||||
}
|
||||
|
||||
|
||||
// This method only changes the ordering of the child objects in a subsection
|
||||
function onUnitReordered() {
|
||||
var subsection_id = $(this).data('subsection-id');
|
||||
@@ -86,7 +109,7 @@ function saveSubsection(e) {
|
||||
|
||||
var id = $(this).data('id');
|
||||
|
||||
// pull all metadata editable fields on page
|
||||
// pull all 'normalized' metadata editable fields on page
|
||||
var metadata_fields = $('input[data-metadata-name]');
|
||||
|
||||
metadata = {};
|
||||
@@ -95,6 +118,19 @@ function saveSubsection(e) {
|
||||
metadata[$(el).data("metadata-name")] = el.value;
|
||||
}
|
||||
|
||||
// now add 'free-formed' metadata which are presented to the user as dual input fields (name/value)
|
||||
$('ol.policy-list > li.policy-list-element').each( function(i, element) {
|
||||
name = $(element).children('.policy-list-name').val();
|
||||
val = $(element).children('.policy-list-value').val();
|
||||
metadata[name] = val;
|
||||
});
|
||||
|
||||
// now add any 'removed' policy metadata which is stored in a separate hidden div
|
||||
// 'null' presented to the server means 'remove'
|
||||
$("#policy-to-delete > li.policy-list-element").each(function(i, element) {
|
||||
name = $(element).children('.policy-list-name').val();
|
||||
metadata[name] = null;
|
||||
});
|
||||
|
||||
// Piece back together the date/time UI elements into one date/time string
|
||||
// NOTE: our various "date/time" metadata elements don't always utilize the same formatting string
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<label>Format:</label>
|
||||
<input type="text" value="${subsection.metadata['format'] if 'format' in subsection.metadata else ''}" class="unit-subtitle" data-metadata-name="subtitle"/>
|
||||
<input type="text" value="${subsection.metadata['format'] if 'format' in subsection.metadata else ''}" class="unit-subtitle" data-metadata-name="format"/>
|
||||
</div>
|
||||
<div class="unit-list">
|
||||
<label>Units:</label>
|
||||
@@ -33,11 +33,25 @@
|
||||
</div>
|
||||
<div class='wip-box'>
|
||||
<label>Policy:</label>
|
||||
<textarea class="text-editor">Policy blah, blah, blah…</textarea>
|
||||
<ol class='policy-list'>
|
||||
% for policy_name in policy_metadata.keys():
|
||||
<li class="policy-list-element">
|
||||
<input type="text" class="policy-list-name" name="${policy_name}" value="${policy_name}" disabled />: <input type="text" class="policy-list-value" name="${policy_metadata[policy_name]}" value="${policy_metadata[policy_name]}" size="30"/><a href="#" class="delete-icon remove-policy-data"></a>
|
||||
</li>
|
||||
% endfor
|
||||
<a href="#" class="add-button add-policy-data">Add</a>
|
||||
</ol>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div id="policy-to-delete" style="display:none">
|
||||
</div>
|
||||
|
||||
<div id="add-new-policy-element-template" style="display:none">
|
||||
<li class="policy-list-element"><input type="text" class="policy-list-name" autocomplete="off"/>: <input type="text" class="policy-list-value" size=30 autocomplete="off"/><a href="#" class="delete-icon remove-policy-data"></a></li>
|
||||
</div>
|
||||
|
||||
<div class="sidebar">
|
||||
<div class="unit-properties window">
|
||||
<h4>Subsection Settings</h4>
|
||||
@@ -49,8 +63,8 @@
|
||||
start_date = datetime.fromtimestamp(mktime(subsection.start)) if subsection.start is not None else None
|
||||
parent_start_date = datetime.fromtimestamp(mktime(parent_item.start)) if parent_item.start is not None else None
|
||||
%>
|
||||
<input type="text" id="start_date" value="${start_date.strftime('%m/%d/%Y') if start_date is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15'/>
|
||||
<input type="text" id="start_time" value="${start_date.strftime('%H:%M') if start_date is not None else ''}" placeholder="HH:MM" class="time" size='10'/>
|
||||
<input type="text" id="start_date" name="start_date" value="${start_date.strftime('%m/%d/%Y') if start_date is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
|
||||
<input type="text" id="start_time" name="start_time" value="${start_date.strftime('%H:%M') if start_date is not None else ''}" placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
|
||||
</div>
|
||||
% if start_date != parent_start_date and parent_start_date is not None:
|
||||
<p class="notice">The date above differs from the release date of ${parent_item.display_name} – ${parent_start_date.strftime('%m/%d/%Y')} at ${parent_start_date.strftime('%H:%M')}. <a href="#" class="sync-date">Sync to ${parent_item.display_name}.</a></p>
|
||||
@@ -65,8 +79,8 @@
|
||||
# due date uses it own formatting for stringifying the date. As with capa_module.py, there's a utility module available for us to use
|
||||
due_date = dateutil.parser.parse(subsection.metadata.get('due')) if 'due' in subsection.metadata else None
|
||||
%>
|
||||
<input type="text" id="due_date" value="${due_date.strftime('%m/%d/%Y') if due_date is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15' />
|
||||
<input type="text" id="due_time" value="${due_date.strftime('%H:%M') if due_date is not None else ''}" placeholder="HH:MM" class="time" size='10' />
|
||||
<input type="text" id="due_date" name="due_date" value="${due_date.strftime('%m/%d/%Y') if due_date is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
|
||||
<input type="text" id="due_time" name="due_time" value="${due_date.strftime('%H:%M') if due_date is not None else ''}" placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
|
||||
<a href="#" class="remove-date">Remove due date</a>
|
||||
</p>
|
||||
</div>
|
||||
@@ -88,6 +102,7 @@
|
||||
<script src="${static.url('js/vendor/date.js')}"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
// expand the due-date area if the values are set
|
||||
if ($('#due_date').val() != '') {
|
||||
var $block = $('.set-date').closest('.due-date-input');
|
||||
$('.set-date').hide();
|
||||
|
||||
Reference in New Issue
Block a user