From d65eabd9b78e2e6c260bce17d1bd47247e19cc35 Mon Sep 17 00:00:00 2001 From: Anon Ray Date: Thu, 11 Sep 2014 18:09:16 +0530 Subject: [PATCH] Halfway commit to fix editing issue for annotations --- swtr/static/js/img_swtr.js | 157 +++++++++++-------- swtr/static/js/lib/custom-fields-plugin.js | 33 ++-- swtr/static/js/main.js | 230 +++++++++++++++------------- 3 files changed, 230 insertions(+), 190 deletions(-) diff --git a/swtr/static/js/img_swtr.js b/swtr/static/js/img_swtr.js index 526cbca..a8764bb 100644 --- a/swtr/static/js/img_swtr.js +++ b/swtr/static/js/img_swtr.js @@ -63,6 +63,7 @@ post: function(options) { var new_sweets = this.getNew(); var dummy_collection = new Backbone.Collection(new_sweets); + console.log('swts to be posted', dummy_collection.toJSON()); if(!swtr.access_token) { throw new Error('Access Token is required to sweet'); @@ -106,23 +107,40 @@ events: { 'keydown .annotorious-editor-button-save': 'getFormValue', 'mousedown .annotorious-editor-button-save': 'getFormValue', - 'click #toggle-anno-areas': 'toggleAnnoAreas' + 'click #toggle-anno-areas': 'toggleAnnoAreas', + // HACK: hook to the annotorious editing via the UI :( + 'click .annotorious-popup-button-edit': 'editAnno' }, initialize: function(options) { this.$el = $('#img-annotation-wrapper'); this.listenTo(this.collection, 'add', this.render); + this.listenTo(this.collection, 'change', this.render); + var self = this; + // attach event handlers to the anno object anno.addHandler('onAnnotationCreated', this.showSwtHelp); anno.addHandler('onAnnotationCreated', this.updateNewAnno); - anno.addHandler('onAnnotationUpdated', this.showSwtHelp); + anno.addHandler('onAnnotationUpdated', this.updateNewAnno); anno.addHandler('onSelectionStarted', function(annotation) { anno.hideAnnotations(); }); anno.addHandler('onSelectionCompleted', function(annotation) { anno.showAnnotations(); }); + + // save the current anno in a cache when a user hovers over an anno + // TODO: this is part of a hack to hook into annotorious' edit event + // state and get the current editing annotation + anno.addHandler('onMouseOverAnnotation', function(event) { + self.current_anno = event['$annotation$']; + }); + anno.addHandler('onMouseOutOfAnnotation', function(event) { + self.current_anno = undefined; + }); + anno.addPlugin('CustomFields', {}); - anno.addHandler('onSelectionCompleted', this.hideOriginalEditor); + anno.addHandler('onSelectionCompleted', _.bind(this.hideOriginalEditor, this)); + if(options.img) { this.img = options.img; this.$img = options.$img; @@ -140,13 +158,16 @@ }, render: function(model) { var swt = model.toJSON(); + console.log('rendering swt as anno', swt); + //anno.removeAnnotation(swt.how); swt.how['editable'] = false; - swt.how.text = swtr.imgAnnoView.createPopupText(swt.how); - swt.how.text += '\n - by ' + swt.who; + //swt.how.text = this.createPopupText(swt.how); + //swt.how.text += '\n - by ' + swt.who; + console.log('adding anno to torious', swt.how); anno.addAnnotation(swt.how); }, renderWith: function() { - _.each(this.collection, this.render); + this.collection.each(this.render, this); }, showSwtHelp: function(annotation) { var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback @@ -154,22 +175,10 @@ $('#sweet').show(); }, updateNewAnno: function(annotation) { - console.log('updateNewAnno()'); + //console.log('updateNewAnno()'); var self = swtr.imgAnnoView; - console.log(annotation.text); - // get the final value/input from the editor - /* var selected = $('select option:selected').text().toLowerCase(); - var text_input = $('.annotorious-editor-text').val(); - if( selected === "tags") { - self.new_anno[selected] = $('#tags-input').tags().getTags(); - } - else { - // update it in our annotation object - self.new_anno[selected] = text_input; - }*/ - // prepare the text field self.new_anno.comment = annotation.text; - self.new_anno.text = self.createPopupText(self.new_anno); + //self.new_anno.text = self.createPopupText(self.new_anno); // update the annotorious annotation object with the new values if(self.new_anno.comment) { annotation.comment = annotation.text; @@ -183,31 +192,52 @@ if(self.new_anno.title) { annotation.title = self.new_anno.title; } - annotation.text = self.new_anno.text; - annotation.editable = false; + annotation.text = ''; + //annotation.text = self.new_anno.text; //console.log(self.new_anno, annotation); }, // hide the original editor window, when user has completed selecting part // of the image to annotate.. hideOriginalEditor: function(annotation) { - console.log('hideOriginalEditor()'); - var self = swtr.imgAnnoView; - self.new_anno = {}; - $('#tags-input').tags({ - tagSize: 'md', - promptText: 'Add tags: type a word (and press enter)', - caseInsensitive: true, - suggestions: self.tags_suggestions - }); - self.getSuggestionsForTags(); + //console.log('hideOriginalEditor()'); + this.new_anno = {}; + this.initBSTags([], this.tags_suggestions); + //self.getSuggestionsForTags(); //$('.annotorious-editor-text').hide(); //$('.annotorious-editor').css('width', '100%'); }, + // initialize the bootstrap tags component.. + initBSTags: function(initial_tags, suggested_tags) { + $('#tags-input').tags({ + tagSize: 'md', + promptText: 'Add tags: type a word (and press enter)', + caseInsensitive: true, + tagData: (initial_tags && initial_tags.length) ? + initial_tags : [], + suggestions: (suggested_tags && suggested_tags.length) ? + suggested_tags : [] + }); + }, getFormValue: function(event) { - console.log('getFormValue()'); - var self = swtr.imgAnnoView; - // show the editor field to input text - $('.annotorious-editor-text').each(function(index, element) { + //console.log('getFormValue()'); + var comment = $('.annotorious-editor-text[placeholder="Add a Comment..."]').val(); + if(comment) { + this.new_anno['comment'] = comment; + } + var title = $('#title-input').val(); + if(title) { + this.new_anno['title'] = title; + } + var link = $('#link-input').val(); + if(link) { + this.new_anno['link'] = link; + } + var tags = $('#tags-input').tags().getTags(); + if(tags.length) { + this.new_anno['tags'] = tags; + } + + /*$('.annotorious-editor-text').each(function(index, element) { if( index === 0) { self.new_anno['comment'] = $(element).text(); console.log(index, $(element).text() ); @@ -222,39 +252,27 @@ } else { self.new_anno['tags'] = $(element).tags().getTags(); - console.log(index, $('#tags-input').tags().getTags() ); + console.log(index, $('#tags-input').tags().getTags() ); } - }); - // show the editor field to input text - /* var $anno_form = $('.annotorious-editor-text'); - //$anno_form.slideDown(); - // get the previous item entered - var $selected = $('select option:selected'); - var text_input = $anno_form.val(); - - // if there was a input and it was not tags.. - if(text_input && $selected.prev().text() !== 'Tags') { - var field = $selected.prev().text().toLowerCase(); - // update it in our annotation object - self.new_anno[field] = text_input; + });*/ + }, + editAnno: function(event) { + //console.log('edit anno'); + if(this.current_anno.comment) { + $('.annotorious-editor-text[placeholder="Add a Comment..."]').val(this.current_anno.comment); } - // if it was tags.. - else if ($selected.prev().text() === 'Tags') { - // directly save it.. - self.new_anno['tags'] = $('#tags-input').tags().getTags(); + if(this.current_anno.title) { + $('#title-input').val(this.current_anno.title); + } + if(this.current_anno.link) { + $('#link-input').val(this.current_anno.link); + } + if(this.current_anno.tags) { + this.initBSTags(this.current_anno.tags, this.tags_suggestions); + } + else { + this.initBSTags([], this.tags_suggestions); } - - // if the current selected is tags - $('#tags-input').tags({ - tagSize: 'md', - promptText: 'Type word (and press enter)..', - caseInsensitive: true, - suggestions: self.tags_suggestions - }); - /* $anno_form.val(''); - $anno_form.attr('placeholder', 'Add ' + $selected.text()); - console.log(self.new_anno);*/ - }, createPopupText: function(annotation) { // title @@ -269,7 +287,9 @@ '

' : ''; // tags - text += (annotation.tags) ? '

[' + annotation.tags + ']

' : ''; + if(annotation.tags) { + text += (annotation.tags.length) ? '

[' + annotation.tags + ']

' : ''; + } // if older annotation i.e w/o comment,title etc fields // add text field as text @@ -301,7 +321,7 @@ }, imageLoaded: function(event) { var self = event.data; - console.log('image loaded', self); + //console.log('image loaded', self); swtr.appView.$overlay.hide(); // reset the collection swtr.sweets.reset(); @@ -333,6 +353,7 @@ success: function(data) { if(_.isArray(data)) { swtr.sweets.add(data); + //self.renderWith(); swtr.appView.$overlay.hide(); self.helpview.step(2); } diff --git a/swtr/static/js/lib/custom-fields-plugin.js b/swtr/static/js/lib/custom-fields-plugin.js index 7b398bb..d063ea1 100644 --- a/swtr/static/js/lib/custom-fields-plugin.js +++ b/swtr/static/js/lib/custom-fields-plugin.js @@ -1,21 +1,24 @@ annotorious.plugin.CustomFields = function(opt_config_options) { + var editorTemplate = _.template($('#customEdit-template').html()); //returns the HTML string for the editor + annotorious.plugin.CustomFields.prototype.onInitAnnotator = function(annotorious) { - var dropDownTemplate= _.template($('#customEdit-template').html()); // creates the HTML element for dropdown - from template in index.html - annotorious.editor.addField(dropDownTemplate); // add dropdown to editor UI widget - annotorious.popup.addField( function(annotation){ - var popupTemplate = _.template($('#popup-template').html()); //created a popup template - yet to find how to bind it to newanno - console.log(annotation.text1); - if(annotation.text1 != undefined) { - //console.log(annotation.text1.Comment); annotation.text is Obj - can - //access each element Comment, tags, links.. - return popupTemplate(annotation.text1); - } - else { - return ''; - } - }); - + annotorious.editor.addField(editorTemplate); + annotorious.popup.addField(function(annotation) { + return (annotation.title) ? '

' + annotation.title + '

' : ''; + }); + annotorious.popup.addField(function(annotation) { + return (annotation.comment) ? '

' + annotation.comment + '' : ''; + }); + annotorious.popup.addField(function(annotation) { + return (annotation.link) ? '

' + annotation.link + + '

' : ''; + }); + annotorious.popup.addField(function(annotation) { + return (annotation.tags && annotation.tags.length) ? '

[' + + annotation.tags + ']

' : ''; + }); } }; diff --git a/swtr/static/js/main.js b/swtr/static/js/main.js index c9679f3..e073e66 100644 --- a/swtr/static/js/main.js +++ b/swtr/static/js/main.js @@ -48,9 +48,10 @@ initialize: function(opts) { this.template = _.template($('#sweet-template').html()); this.helpview = opts.helpview; - //this.setElement(opts.el); }, render: function() { + console.log('sweetsview rendering'); + debugger; $('#sweet-list').html('

These are your sweet annotations!

'); _.each(this.collection.models, function(swt) { if(swt.has('id')) { @@ -91,7 +92,10 @@ }); this.collection.remove(notPosted); }, - postSweets: function() { + postSweets: function(event) { + event.preventDefault(); + console.log('posting swts'); + debugger; var appView = swtr.appView; var self = this; this.helpview.step(5); @@ -99,10 +103,12 @@ try { this.collection.post({ success: function(collection, response) { - console.log(collection, response); - swtr.sweets.set(collection); + console.log('updated', collection, response); + swtr.sweets.add(collection, {merge: true}); + console.log('new swtr coll', swtr.sweets); appView.$overlay.hide(); self.helpview.step(6); + self.trigger('postedSweets'); }, error: function(jqxhr, error, text) { console.log(jqxhr, error, text); @@ -125,102 +131,6 @@ } }); - var FilterView = Backbone.View.extend({ - el: $('#filter-div'), - events: { - 'click #filter-user-div input': 'filter', - 'click #filter-tags-div input': 'filter' - }, - initialize: function() { - this.filter_users_template = _.template($('#filter-users').html()); - this.filter_tags_template = _.template($('#filter-tags').html()); - this.render(); - }, - render: function() { - //console.log(this.collection); - // pluck uniq authors of sweets - var authors = _.uniq(this.collection.pluck('who')); - // render them as filter controls - _.each(authors, function(author) { - $('#filter-user-div').append(this.filter_users_template({ - who: author - })); - }, this); - - // pluck uniq tags of sweets - var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). - uniq().value(); - - // render them as filter controls - _.each(tags, function(tag) { - if(tag) { - $('#filter-tags-div').append(this.filter_tags_template({ - tag: tag - })); - } - }, this); - - //this.delegateEvents(); - }, - filter: function(event) { - // get id of div - parent to parent to the clicked input - var target_id = $(event.currentTarget).parent().parent().attr('id'); - // find out user/tag div - var which = target_id.split('-')[1]; - - var selected = []; - $('#'+target_id + ' input:checked').each(function() { - selected.push($(this).attr('name')); - }); - - if(which === 'user') { - this.filterUsers(selected); - } - else if(which === 'tags') { - this.filterTags(selected); - } - }, - filterUsers: function(users) { - if(!users.length) { - return; - } - var filtered_swts = this.collection.filter(function(model) { - if(_.indexOf(users, model.get('who')) > -1) { - return model; - } - }); - if(filtered_swts.length) { - anno.removeAll(); - _.each(filtered_swts, function(swt) { - anno.addAnnotation(swt.get('how')); - }); - } - }, - filterTags: function(tags) { - if(!tags.length) { - return; - } - var filtered_swts = this.collection.filter(function(model) { - //TODO: find a better way of doing this.. - var flag = false; - _.each(model.get('how').tags, function(tag) { - if(_.indexOf(tags, tag) > -1) { - flag = true; - } - }); - if(flag === true) { - return model; - } - }); - if(filtered_swts.length) { - anno.removeAll(); - _.each(filtered_swts, function(swt) { - anno.addAnnotation(swt.get('how')); - }); - } - } - }); - var AppView = Backbone.View.extend({ el: $('body'), events: { @@ -263,7 +173,7 @@ }); var PlayAreaView = Backbone.View.extend({ - id: '#play-page-container', + id: 'play-page-container', events: { 'click #user-input-submit': 'submitUserInput', 'click #sweet': 'sweet' @@ -278,6 +188,7 @@ helpview: this.helpview }); this.$img = $('#annotatable-img'); + //this.sweetsview.on('postedSweets', this.rerenderAnnos); this.helpview.step(1); }, render: function() { @@ -294,6 +205,7 @@ var annos = _.filter(anno.getAnnotations(), function(anno) { return (!_.has(anno, 'editable') || anno.editable === true); }); + console.log(annos); _.each(annos, function(anno) { swtr.sweets.add({ @@ -305,13 +217,17 @@ }); }, showSweets: function() { - console.log('showSweets'); + //console.log('showSweets'); this.sweetsview.render(); }, - sweet: function() { + sweet: function(event) { + event.preventDefault(); console.log('sweeting'); + debugger; this.getSweets(); + debugger; this.showSweets(); + debugger; return false; }, // function to update the urls in the UI if an image is loaded internally @@ -346,9 +262,9 @@ var self = this; $.get('/media-type', {where: url}, function(response) { //console.log(response); - self.appView.$overlay.hide(); + swtr.appView.$overlay.hide(); if(response.type === 'image') { - this.initImageAnno(url); + self.initImageAnno(url); } else { window.location.href = '/annotate?where=' + url; @@ -547,7 +463,7 @@ var url = $(event.currentTarget).parent().parent(). find('img').attr('src'); //TODO: load the image in the play area/workbench - console.log('load image anno', url); + //console.log('load image anno', url); swtr.app_router.loadPlayArea(url, 'image'); }, search: function(data, cb) { @@ -568,6 +484,7 @@ var HelpView = Backbone.View.extend({ id: 'helpview-wrapper', events: { + 'click .close': 'clickedClose' }, initialize: function() { this.template = _.template($('#helpview-template').html()); @@ -578,6 +495,9 @@ $('#helpview-container').html(this.$el); this.$el.html(this.template({})); }, + clickedClose: function(event) { + this.remove(); + }, //TODO: move from number based steps to something else. number based steps //implicitly imply sequential processing..which does not happen in this //case.. @@ -851,7 +771,7 @@ } $('#' + id).show(); this.highlight(id); - console.log('shown', id); + //console.log('shown', id); }, highlight: function(id) { $('#swtr-navbar-collapse li').removeClass('active'); @@ -876,4 +796,100 @@ } }); + var FilterView = Backbone.View.extend({ + el: $('#filter-div'), + events: { + 'click #filter-user-div input': 'filter', + 'click #filter-tags-div input': 'filter' + }, + initialize: function() { + this.filter_users_template = _.template($('#filter-users').html()); + this.filter_tags_template = _.template($('#filter-tags').html()); + this.render(); + }, + render: function() { + //console.log(this.collection); + // pluck uniq authors of sweets + var authors = _.uniq(this.collection.pluck('who')); + // render them as filter controls + _.each(authors, function(author) { + $('#filter-user-div').append(this.filter_users_template({ + who: author + })); + }, this); + + // pluck uniq tags of sweets + var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). + uniq().value(); + + // render them as filter controls + _.each(tags, function(tag) { + if(tag) { + $('#filter-tags-div').append(this.filter_tags_template({ + tag: tag + })); + } + }, this); + + //this.delegateEvents(); + }, + filter: function(event) { + // get id of div - parent to parent to the clicked input + var target_id = $(event.currentTarget).parent().parent().attr('id'); + // find out user/tag div + var which = target_id.split('-')[1]; + + var selected = []; + $('#'+target_id + ' input:checked').each(function() { + selected.push($(this).attr('name')); + }); + + if(which === 'user') { + this.filterUsers(selected); + } + else if(which === 'tags') { + this.filterTags(selected); + } + }, + filterUsers: function(users) { + if(!users.length) { + return; + } + var filtered_swts = this.collection.filter(function(model) { + if(_.indexOf(users, model.get('who')) > -1) { + return model; + } + }); + if(filtered_swts.length) { + anno.removeAll(); + _.each(filtered_swts, function(swt) { + anno.addAnnotation(swt.get('how')); + }); + } + }, + filterTags: function(tags) { + if(!tags.length) { + return; + } + var filtered_swts = this.collection.filter(function(model) { + //TODO: find a better way of doing this.. + var flag = false; + _.each(model.get('how').tags, function(tag) { + if(_.indexOf(tags, tag) > -1) { + flag = true; + } + }); + if(flag === true) { + return model; + } + }); + if(filtered_swts.length) { + anno.removeAll(); + _.each(filtered_swts, function(swt) { + anno.addAnnotation(swt.get('how')); + }); + } + } + }); + })(swtr); -- 1.7.10.4