From 95e15c4455ba7da281f87a0c1060344c80dc5d85 Mon Sep 17 00:00:00 2001 From: Chris Dodge Date: Fri, 5 Oct 2012 13:17:51 -0400 Subject: [PATCH] time/date setting on Release Date and Due date --- cms/djangoapps/contentstore/views.py | 15 +++++++++++- cms/static/js/base.js | 34 +++++++++++++++++++++++++-- cms/templates/edit_subsection.html | 35 +++++++++++++++++++--------- cms/templates/widgets/units.html | 2 +- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index fe9204c21a..df2a6fd986 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -440,15 +440,28 @@ def save_item(request): # cdodge: also commit any metadata which might have been passed along in the # 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 # 'apply' the submitted metadata, so we don't end up deleting system metadata if request.POST['metadata']: posted_metadata = request.POST['metadata'] # fetch original existing_item = modulestore().get_item(item_location) + + logging.debug(posted_metadata) + # 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) + + # commit to datastore modulestore().update_metadata(item_location, existing_item.metadata) return HttpResponse() diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 3508c80aed..bc637b0075 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -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) { e.preventDefault(); @@ -70,10 +91,19 @@ function saveSubsection(e) { metadata = {}; for(var i=0; i< metadata_fields.length;i++) { - el = metadata_fields[i]; - metadata[$(el).data("metadata-name")] = el.value; + el = metadata_fields[i]; + 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 =[]; $.ajax({ diff --git a/cms/templates/edit_subsection.html b/cms/templates/edit_subsection.html index b05c2121fc..3fa1e135dd 100644 --- a/cms/templates/edit_subsection.html +++ b/cms/templates/edit_subsection.html @@ -1,10 +1,9 @@ <%inherit file="base.html" /> <%! - import time + from time import mktime import dateutil.parser + import logging from datetime import datetime - - now = datetime.now() %> <%! from django.core.urlresolvers import reverse %> @@ -32,7 +31,7 @@ ${units.enum_units(subsection)} -
+
@@ -46,10 +45,13 @@
- - + <% + start_time = datetime.fromtimestamp(mktime(subsection.start)) if subsection.start is not None else None + %> + +
-

The date above differs from the release date of Week 1 – 10/10/2012 at 12:00 am. Sync to Week 1.

+

The date above differs from the release date of Week 1 – 10/10/2012 at 12:00 am. Sync to Week 1.

@@ -57,10 +59,11 @@

<% - 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 + %> + + Remove due date

@@ -79,4 +82,14 @@ + + diff --git a/cms/templates/widgets/units.html b/cms/templates/widgets/units.html index 8207b485a7..67e956561c 100644 --- a/cms/templates/widgets/units.html +++ b/cms/templates/widgets/units.html @@ -17,7 +17,7 @@ This def will enumerate through a passed in subsection and list all of the units ${unit.display_name} - - private + - private % if actions: