diff --git a/opentech/apply/activity/templates/activity/include/listing_base.html b/opentech/apply/activity/templates/activity/include/listing_base.html
index c5c1cd67af7f313e8f22081a827d78d7d2408d8e..f830163c13fb7c72c8b2e1aa5fdae842f74849ed 100644
--- a/opentech/apply/activity/templates/activity/include/listing_base.html
+++ b/opentech/apply/activity/templates/activity/include/listing_base.html
@@ -8,11 +8,13 @@
             <p class="feed__label feed__label--{{ activity.type }} feed__label--mobile">{{ activity.type|capfirst }}</p>
             <p class="feed__meta-item"><span>{{ activity|display_author:request.user }}</span> – {{ activity.timestamp|date:"Y-m-d H:i" }}</p>
             <p class="feed__meta-item">
-                <a class="link link--edit-submission is-active js-edit-comment" href="{% url 'funds:submissions:edit' object.id %}">
+                <a class="link link--edit-submission is-active js-edit-comment" href="#">
                     Edit
                     <svg class="icon icon--pen"><use xlink:href="#pen"></use></svg>
                 </a>
             </p>
+            <!-- TODO: only show if has been previously edited -->
+            <p class="feed__meta-item">Last edited: <span class="js-last-edited">{{ activity.edited }}</span></p>
             {% if activity.private %}
                 <p class="feed__meta-item feed__meta-item--right">
                     <svg class="icon icon--eye"><use xlink:href="#eye"></use></svg>
@@ -25,11 +27,11 @@
                 updated <a href="{{ activity.submission.get_absolute_url }}">{{ activity.submission.title }}</a>
             {% endif %}
 
-            <div class="feed__comment js-comment" data-comment="{{activity.message}}">
+            <div class="feed__comment js-comment" data-id="{{activity.id}}" data-comment="{{activity.message}}">
                 {{ activity|display_for:request.user|submission_links|markdown|bleach }}
             </div>
 
-            <div class="js-edit-form"></div>
+            <div class="js-edit-block" aria-live="polite"></div>
 
             {% if not submission_title and activity|user_can_see_related:request.user %}
                 {% with url=activity.related_object.get_absolute_url %}
diff --git a/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html b/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
index 65245f86c555f17db65810e15a4ab156a504fa15..537f0b371d5aab914f588cb50f814f08f04cb5db 100644
--- a/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
+++ b/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
@@ -47,6 +47,7 @@
     {{ comment_form.media.js }}
     {{ partner_form.media.js }}
     <script src="//cdnjs.cloudflare.com/ajax/libs/fancybox/3.4.1/jquery.fancybox.min.js"></script>
+    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
     <script src="{% static 'js/apply/fancybox-global.js' %}"></script>
     <script src="{% static 'js/apply/tabs.js' %}"></script>
     <script src="{% static 'js/apply/toggle-actions-panel.js' %}"></script>
diff --git a/opentech/static_src/src/javascript/apply/edit-comment.js b/opentech/static_src/src/javascript/apply/edit-comment.js
index 113e6a1e699ce282471e9e1e5038914b33793897..913745aa89b685a580f3bbcf8059ae1987647e1a 100644
--- a/opentech/static_src/src/javascript/apply/edit-comment.js
+++ b/opentech/static_src/src/javascript/apply/edit-comment.js
@@ -2,11 +2,23 @@
 
     'use strict';
 
-    $('.js-edit-comment').click(function (e) {
+    const comment = '.js-comment';
+    const pageDown = '.js-pagedown';
+    const feedMeta = '.js-feed-meta';
+    const editBlock = '.js-edit-block';
+    const lastEdited = '.js-last-edited';
+    const editButton = '.js-edit-comment';
+    const feedContent = '.js-feed-content';
+    const cancelEditButton = '.js-cancel-edit';
+    const submitEditButton = '.js-submit-edit';
+
+    // handle edit
+    $(editButton).click(function (e) {
         e.preventDefault();
-        const editFormWrapper = $(this).closest('.js-feed-content').children('.js-edit-form');
-        const commentWrapper = $(this).closest('.js-feed-content').children('.js-comment');
-        const commentContents = $(this).closest('.js-feed-content').children('.js-comment').data('comment');
+
+        const editBlockWrapper = $(this).closest(feedContent).find(editBlock);
+        const commentWrapper = $(this).closest(feedContent).find(comment);
+        const commentContents = $(commentWrapper).data('comment');
 
         // hide the edit link and original comment
         $(this).hide();
@@ -17,27 +29,80 @@
                 <div id="wmd-button-bar-edit-comment" class="wmd-button-bar"></div>
                 <textarea id="wmd-input-edit-comment" class="wmd-input" rows="10">${commentContents}</textarea>
                 <div id="wmd-preview-edit-comment" class="wmd-preview"></div>
-                <div class="wrapper--top-outer-space-small">
-                    <button class="button button--primary" type="submit">Update</button>
+                <div class="wrapper--outer-space-medium">
+                    <button class="button button--primary js-submit-edit" type="submit">Update</button>
                     <button class="button button--white js-cancel-edit">Cancel</button>
                 </div>
             </div>
         `;
 
         // add the comment to the editor
-        $(editFormWrapper).append(markup);
+        $(editBlockWrapper).append(markup);
 
         // run the editor
-        const converterOne = Markdown.getSanitizingConverter();
-        const commentEditor = new Markdown.Editor(converterOne, '-edit-comment');
-        commentEditor.run();
+        initEditor();
     });
 
-    $(document).on('click', '.js-cancel-edit', function () {
-        // show the comment, edit button and remove the editor
-        $(this).closest('.js-edit-form').prev('.js-comment').show();
-        $(this).closest('.js-edit-form').siblings('.js-feed-meta').find('.js-edit-comment').show();
-        $(this).closest('.js-pagedown').remove();
+    // handle cancel
+    $(document).on('click', cancelEditButton, function () {
+        showComment(this);
+        showEditButton(this);
+        hidePageDownEditor(this);
+    });
+
+    // handle submit
+    $(document).on('click', submitEditButton, function () {
+        const commentContainer = $(this).closest(editBlock).siblings(comment);
+        const id = $(commentContainer).data('id');
+        const editedComment = $(this).closest(pageDown).find('.wmd-preview').html();
+
+        // TODO - get correct URL
+        const url = `${window.location.origin}/apply/api/comments/${id}/edit/`;
+
+        fetch(url, {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'X-CSRFToken': $.cookie('csrftoken')
+            },
+            body: JSON.stringify({
+                message: editedComment
+            })
+
+        }).then(response => response.json())
+        .then(data => {
+            updateComment(commentContainer, data.id, data.message);
+            updateLastEdited(this, data.edited);
+            showComment(this);
+            showEditButton(this);
+            hidePageDownEditor(this);
+        });
     });
 
+    const initEditor = () => {
+        const converterOne = window.Markdown.getSanitizingConverter();
+        const commentEditor = new window.Markdown.Editor(converterOne, '-edit-comment');
+        commentEditor.run();
+    };
+
+    const showEditButton = (el) => {
+        $(el).closest(editBlock).siblings(feedMeta).find(editButton).show();
+    };
+
+    const hidePageDownEditor = (el) => {
+        $(el).closest(pageDown).remove();
+    };
+
+    const showComment = (el) => {
+        $(el).closest(editBlock).siblings(comment).show();
+    };
+
+    // TODO - parse date
+    const updateLastEdited = (el, date) => {
+        $(el).closest(feedContent).find(lastEdited).html(date);
+    };
+
+    const updateComment = (el, id, newComment) => {
+        $(el).html(newComment).data('comment', newComment).data('id', id);
+    };
 })(jQuery);