Commit 95e15c44 by Chris Dodge

time/date setting on Release Date and Due date

parent 758c4469
...@@ -440,15 +440,28 @@ def save_item(request): ...@@ -440,15 +440,28 @@ def save_item(request):
# cdodge: also commit any metadata which might have been passed along in the # cdodge: also commit any metadata which might have been passed along in the
# POST from the client, if it is there # POST from the client, if it is there
# note, that the postback is not the complete metadata, as there's system metadata which is # NOTE, that the postback is not the complete metadata, as there's system metadata which is
# not presented to the end-user for editing. So let's fetch the original and # not presented to the end-user for editing. So let's fetch the original and
# 'apply' the submitted metadata, so we don't end up deleting system metadata # 'apply' the submitted metadata, so we don't end up deleting system metadata
if request.POST['metadata']: if request.POST['metadata']:
posted_metadata = request.POST['metadata'] posted_metadata = request.POST['metadata']
# fetch original # fetch original
existing_item = modulestore().get_item(item_location) existing_item = modulestore().get_item(item_location)
logging.debug(posted_metadata)
# update existing metadata with submitted metadata (which can be partial) # update existing metadata with submitted metadata (which can be partial)
# IMPORTANT NOTE: if the client passed pack 'null' (None) for a piece of metadata that means 'remove it'
for metadata_key in posted_metadata.keys():
if posted_metadata[metadata_key] is None:
# remove both from passed in collection as well as the collection read in from the modulestore
del existing_item.metadata[metadata_key]
del posted_metadata[metadata_key]
# overlay the new metadata over the modulestore sourced collection to support partial updates
existing_item.metadata.update(posted_metadata) existing_item.metadata.update(posted_metadata)
# commit to datastore
modulestore().update_metadata(item_location, existing_item.metadata) modulestore().update_metadata(item_location, existing_item.metadata)
return HttpResponse() return HttpResponse()
......
...@@ -60,6 +60,27 @@ function onUnitReordered() { ...@@ -60,6 +60,27 @@ function onUnitReordered() {
}); });
} }
function getEdxTimeFromDateTimeInputs(date_id, time_id, format) {
var input_date = $('#'+date_id).val();
var input_time = $('#'+time_id).val();
var edxTimeStr = null;
if (input_date != '') {
if (input_time == '')
input_time = '00:00';
// Note, we are using date.js utility which has better parsing abilities than the built in JS date parsing
date = Date.parse(input_date+" "+input_time);
if (format == null)
format = 'yyyy-MM-ddTHH:mm';
edxTimeStr = date.toString(format);
}
return edxTimeStr;
}
function saveSubsection(e) { function saveSubsection(e) {
e.preventDefault(); e.preventDefault();
...@@ -74,6 +95,15 @@ function saveSubsection(e) { ...@@ -74,6 +95,15 @@ function saveSubsection(e) {
metadata[$(el).data("metadata-name")] = el.value; metadata[$(el).data("metadata-name")] = el.value;
} }
// OK, we have some metadata (namely 'Release Date' (aka 'start') and 'Due Date') which has been normalized in the UI
// we have to piece it back together. Unfortunate 'start' and 'due' use different string formatters. Rather than try to
// replicate the string formatting which is used in the backend here in JS, let's just pass back a unified format
// and let the server re-format into the expected persisted format
metadata['start'] = getEdxTimeFromDateTimeInputs('start_date', 'start_time');
metadata['due'] = getEdxTimeFromDateTimeInputs('due_date', 'due_time', 'MMMM dd HH:mm');
// reordering is done through immediate callbacks when the resorting has completed in the UI
children =[]; children =[];
$.ajax({ $.ajax({
......
<%inherit file="base.html" /> <%inherit file="base.html" />
<%! <%!
import time from time import mktime
import dateutil.parser import dateutil.parser
import logging
from datetime import datetime from datetime import datetime
now = datetime.now()
%> %>
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
<label>Units:</label> <label>Units:</label>
${units.enum_units(subsection)} ${units.enum_units(subsection)}
</div> </div>
<div> <div class='wip-box'>
<label>Policy:</label> <label>Policy:</label>
<textarea class="text-editor">Policy blah, blah, blah…</textarea> <textarea class="text-editor">Policy blah, blah, blah…</textarea>
</div> </div>
...@@ -46,10 +45,13 @@ ...@@ -46,10 +45,13 @@
<div class="scheduled-date-input row"> <div class="scheduled-date-input row">
<label>Release date:<!-- <span class="description">Determines when this subsection and the units within it will be released publicly.</span>--></label> <label>Release date:<!-- <span class="description">Determines when this subsection and the units within it will be released publicly.</span>--></label>
<div class="datepair" data-language="javascript"> <div class="datepair" data-language="javascript">
<input type="text" value="${subsection.start.strftime('%Y-%m-%d') if subsection.start is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15'/> <%
<input type="text" value="${subsection.start.strftime('%H:%M') if subsection.start is not None else ''}" placeholder="HH:MM" class="time" size='10'/> start_time = datetime.fromtimestamp(mktime(subsection.start)) if subsection.start is not None else None
%>
<input type="text" id="start_date" value="${start_time.strftime('%m/%d/%Y') if start_time is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15'/>
<input type="text" id="start_time" value="${start_time.strftime('%H:%M') if start_time is not None else ''}" placeholder="HH:MM" class="time" size='10'/>
</div> </div>
<p class="notice">The date above differs from the release date of Week 1 – 10/10/2012 at 12:00 am. <a href="#" class="sync-date">Sync to Week 1.</a></p> <p class="notice wip-box">The date above differs from the release date of Week 1 – 10/10/2012 at 12:00 am. <a href="#" class="sync-date">Sync to Week 1.</a></p>
</div> </div>
<div class="due-date-input row"> <div class="due-date-input row">
<label>Due date:</label> <label>Due date:</label>
...@@ -57,10 +59,11 @@ ...@@ -57,10 +59,11 @@
<div class="datepair date-setter"> <div class="datepair date-setter">
<p class="date-description"> <p class="date-description">
<% <%
due_date = dateutil.parser.parse(subsection.metadata.get('get')) if 'due' in subsection.metadata else None # 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" value="${due_date.strftime('%Y-%m-%d') if due_date is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15' /> <input type="text" id="due_date" value="${due_date.strftime('%Y-%m-%d') if due_date is not None else ''}" placeholder="MM/DD/YYYY" class="date" size='15' />
<input type="text" 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_time" value="${due_date.strftime('%H:%M') if due_date is not None else ''}" placeholder="HH:MM" class="time" size='10' />
<a href="#" class="remove-date">Remove due date</a> <a href="#" class="remove-date">Remove due date</a>
</p> </p>
</div> </div>
...@@ -79,4 +82,14 @@ ...@@ -79,4 +82,14 @@
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" /> <link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
<script src="${static.url('js/vendor/timepicker/jquery.timepicker.js')}"></script> <script src="${static.url('js/vendor/timepicker/jquery.timepicker.js')}"></script>
<script src="${static.url('js/vendor/timepicker/datepair.js')}"></script> <script src="${static.url('js/vendor/timepicker/datepair.js')}"></script>
<script src="${static.url('js/vendor/date.js')}"></script>
<script type="text/javascript">
$(document).ready(function() {
if ($('#due_date').val() != '') {
var $block = $('.set-date').closest('.due-date-input');
$('.set-date').hide();
$block.find('.date-setter').show();
}
})
</script>
</%block> </%block>
...@@ -17,7 +17,7 @@ This def will enumerate through a passed in subsection and list all of the units ...@@ -17,7 +17,7 @@ This def will enumerate through a passed in subsection and list all of the units
<a href="${reverse('edit_unit', args=[unit.location])}" class="private-item"> <a href="${reverse('edit_unit', args=[unit.location])}" class="private-item">
<span class="${unit.category}-icon"></span> <span class="${unit.category}-icon"></span>
${unit.display_name} ${unit.display_name}
<span class="private-tag">- private</span> <span class="private-tag wip">- private</span>
</a> </a>
% if actions: % if actions:
<div class="item-actions"> <div class="item-actions">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment