Commit d65eabd9b78e2e6c260bce17d1bd47247e19cc35

Halfway commit to fix editing issue for annotations
  
6363 post: function(options) {
6464 var new_sweets = this.getNew();
6565 var dummy_collection = new Backbone.Collection(new_sweets);
66 console.log('swts to be posted', dummy_collection.toJSON());
6667
6768 if(!swtr.access_token) {
6869 throw new Error('Access Token is required to sweet');
107107 events: {
108108 'keydown .annotorious-editor-button-save': 'getFormValue',
109109 'mousedown .annotorious-editor-button-save': 'getFormValue',
110 'click #toggle-anno-areas': 'toggleAnnoAreas'
110 'click #toggle-anno-areas': 'toggleAnnoAreas',
111 // HACK: hook to the annotorious editing via the UI :(
112 'click .annotorious-popup-button-edit': 'editAnno'
111113 },
112114 initialize: function(options) {
113115 this.$el = $('#img-annotation-wrapper');
114116 this.listenTo(this.collection, 'add', this.render);
117 this.listenTo(this.collection, 'change', this.render);
118 var self = this;
119
115120 // attach event handlers to the anno object
116121 anno.addHandler('onAnnotationCreated', this.showSwtHelp);
117122 anno.addHandler('onAnnotationCreated', this.updateNewAnno);
118 anno.addHandler('onAnnotationUpdated', this.showSwtHelp);
123 anno.addHandler('onAnnotationUpdated', this.updateNewAnno);
119124 anno.addHandler('onSelectionStarted', function(annotation) {
120125 anno.hideAnnotations();
121126 });
122127 anno.addHandler('onSelectionCompleted', function(annotation) {
123128 anno.showAnnotations();
124129 });
130
131 // save the current anno in a cache when a user hovers over an anno
132 // TODO: this is part of a hack to hook into annotorious' edit event
133 // state and get the current editing annotation
134 anno.addHandler('onMouseOverAnnotation', function(event) {
135 self.current_anno = event['$annotation$'];
136 });
137 anno.addHandler('onMouseOutOfAnnotation', function(event) {
138 self.current_anno = undefined;
139 });
140
125141 anno.addPlugin('CustomFields', {});
126 anno.addHandler('onSelectionCompleted', this.hideOriginalEditor);
142 anno.addHandler('onSelectionCompleted', _.bind(this.hideOriginalEditor, this));
143
127144 if(options.img) {
128145 this.img = options.img;
129146 this.$img = options.$img;
158158 },
159159 render: function(model) {
160160 var swt = model.toJSON();
161 console.log('rendering swt as anno', swt);
162 //anno.removeAnnotation(swt.how);
161163 swt.how['editable'] = false;
162 swt.how.text = swtr.imgAnnoView.createPopupText(swt.how);
163 swt.how.text += '\n - by ' + swt.who;
164 //swt.how.text = this.createPopupText(swt.how);
165 //swt.how.text += '\n - by ' + swt.who;
166 console.log('adding anno to torious', swt.how);
164167 anno.addAnnotation(swt.how);
165168 },
166169 renderWith: function() {
167 _.each(this.collection, this.render);
170 this.collection.each(this.render, this);
168171 },
169172 showSwtHelp: function(annotation) {
170173 var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback
175175 $('#sweet').show();
176176 },
177177 updateNewAnno: function(annotation) {
178 console.log('updateNewAnno()');
178 //console.log('updateNewAnno()');
179179 var self = swtr.imgAnnoView;
180 console.log(annotation.text);
181 // get the final value/input from the editor
182 /* var selected = $('select option:selected').text().toLowerCase();
183 var text_input = $('.annotorious-editor-text').val();
184 if( selected === "tags") {
185 self.new_anno[selected] = $('#tags-input').tags().getTags();
186 }
187 else {
188 // update it in our annotation object
189 self.new_anno[selected] = text_input;
190 }*/
191 // prepare the text field
192180 self.new_anno.comment = annotation.text;
193 self.new_anno.text = self.createPopupText(self.new_anno);
181 //self.new_anno.text = self.createPopupText(self.new_anno);
194182 // update the annotorious annotation object with the new values
195183 if(self.new_anno.comment) {
196184 annotation.comment = annotation.text;
192192 if(self.new_anno.title) {
193193 annotation.title = self.new_anno.title;
194194 }
195 annotation.text = self.new_anno.text;
196 annotation.editable = false;
195 annotation.text = '';
196 //annotation.text = self.new_anno.text;
197197 //console.log(self.new_anno, annotation);
198198 },
199199 // hide the original editor window, when user has completed selecting part
200200 // of the image to annotate..
201201 hideOriginalEditor: function(annotation) {
202 console.log('hideOriginalEditor()');
203 var self = swtr.imgAnnoView;
204 self.new_anno = {};
205 $('#tags-input').tags({
206 tagSize: 'md',
207 promptText: 'Add tags: type a word (and press enter)',
208 caseInsensitive: true,
209 suggestions: self.tags_suggestions
210 });
211 self.getSuggestionsForTags();
202 //console.log('hideOriginalEditor()');
203 this.new_anno = {};
204 this.initBSTags([], this.tags_suggestions);
205 //self.getSuggestionsForTags();
212206 //$('.annotorious-editor-text').hide();
213207 //$('.annotorious-editor').css('width', '100%');
214208 },
209 // initialize the bootstrap tags component..
210 initBSTags: function(initial_tags, suggested_tags) {
211 $('#tags-input').tags({
212 tagSize: 'md',
213 promptText: 'Add tags: type a word (and press enter)',
214 caseInsensitive: true,
215 tagData: (initial_tags && initial_tags.length) ?
216 initial_tags : [],
217 suggestions: (suggested_tags && suggested_tags.length) ?
218 suggested_tags : []
219 });
220 },
215221 getFormValue: function(event) {
216 console.log('getFormValue()');
217 var self = swtr.imgAnnoView;
218 // show the editor field to input text
219 $('.annotorious-editor-text').each(function(index, element) {
222 //console.log('getFormValue()');
223 var comment = $('.annotorious-editor-text[placeholder="Add a Comment..."]').val();
224 if(comment) {
225 this.new_anno['comment'] = comment;
226 }
227 var title = $('#title-input').val();
228 if(title) {
229 this.new_anno['title'] = title;
230 }
231 var link = $('#link-input').val();
232 if(link) {
233 this.new_anno['link'] = link;
234 }
235 var tags = $('#tags-input').tags().getTags();
236 if(tags.length) {
237 this.new_anno['tags'] = tags;
238 }
239
240 /*$('.annotorious-editor-text').each(function(index, element) {
220241 if( index === 0) {
221242 self.new_anno['comment'] = $(element).text();
222243 console.log(index, $(element).text() );
252252 }
253253 else {
254254 self.new_anno['tags'] = $(element).tags().getTags();
255 console.log(index, $('#tags-input').tags().getTags() );
255 console.log(index, $('#tags-input').tags().getTags() );
256256 }
257 });
258 // show the editor field to input text
259 /* var $anno_form = $('.annotorious-editor-text');
260 //$anno_form.slideDown();
261 // get the previous item entered
262 var $selected = $('select option:selected');
263 var text_input = $anno_form.val();
264
265 // if there was a input and it was not tags..
266 if(text_input && $selected.prev().text() !== 'Tags') {
267 var field = $selected.prev().text().toLowerCase();
268 // update it in our annotation object
269 self.new_anno[field] = text_input;
257 });*/
258 },
259 editAnno: function(event) {
260 //console.log('edit anno');
261 if(this.current_anno.comment) {
262 $('.annotorious-editor-text[placeholder="Add a Comment..."]').val(this.current_anno.comment);
270263 }
271 // if it was tags..
272 else if ($selected.prev().text() === 'Tags') {
273 // directly save it..
274 self.new_anno['tags'] = $('#tags-input').tags().getTags();
264 if(this.current_anno.title) {
265 $('#title-input').val(this.current_anno.title);
275266 }
276
277 // if the current selected is tags
278 $('#tags-input').tags({
279 tagSize: 'md',
280 promptText: 'Type word (and press enter)..',
281 caseInsensitive: true,
282 suggestions: self.tags_suggestions
283 });
284 /* $anno_form.val('');
285 $anno_form.attr('placeholder', 'Add ' + $selected.text());
286 console.log(self.new_anno);*/
287
267 if(this.current_anno.link) {
268 $('#link-input').val(this.current_anno.link);
269 }
270 if(this.current_anno.tags) {
271 this.initBSTags(this.current_anno.tags, this.tags_suggestions);
272 }
273 else {
274 this.initBSTags([], this.tags_suggestions);
275 }
288276 },
289277 createPopupText: function(annotation) {
290278 // title
287287 '</a></p>' : '';
288288
289289 // tags
290 text += (annotation.tags) ? '<p>[' + annotation.tags + ']</p>' : '';
290 if(annotation.tags) {
291 text += (annotation.tags.length) ? '<p>[' + annotation.tags + ']</p>' : '';
292 }
291293
292294 // if older annotation i.e w/o comment,title etc fields
293295 // add text field as text
321321 },
322322 imageLoaded: function(event) {
323323 var self = event.data;
324 console.log('image loaded', self);
324 //console.log('image loaded', self);
325325 swtr.appView.$overlay.hide();
326326 // reset the collection
327327 swtr.sweets.reset();
353353 success: function(data) {
354354 if(_.isArray(data)) {
355355 swtr.sweets.add(data);
356 //self.renderWith();
356357 swtr.appView.$overlay.hide();
357358 self.helpview.step(2);
358359 }
  
11annotorious.plugin.CustomFields = function(opt_config_options) {
22
3 var editorTemplate = _.template($('#customEdit-template').html()); //returns the HTML string for the editor
4
35 annotorious.plugin.CustomFields.prototype.onInitAnnotator = function(annotorious) {
4 var dropDownTemplate= _.template($('#customEdit-template').html()); // creates the HTML element for dropdown - from template in index.html
5 annotorious.editor.addField(dropDownTemplate); // add dropdown to editor UI widget
6 annotorious.popup.addField( function(annotation){
7 var popupTemplate = _.template($('#popup-template').html()); //created a popup template - yet to find how to bind it to newanno
8 console.log(annotation.text1);
9 if(annotation.text1 != undefined) {
10 //console.log(annotation.text1.Comment); annotation.text is Obj - can
11 //access each element Comment, tags, links..
12 return popupTemplate(annotation.text1);
13 }
14 else {
15 return '';
16 }
17 });
18
6 annotorious.editor.addField(editorTemplate);
197
8 annotorious.popup.addField(function(annotation) {
9 return (annotation.title) ? '<h4>' + annotation.title + '</h4>' : '';
10 });
11 annotorious.popup.addField(function(annotation) {
12 return (annotation.comment) ? '<p>' + annotation.comment + '</h4>' : '';
13 });
14 annotorious.popup.addField(function(annotation) {
15 return (annotation.link) ? '<p><a target="blank" href="' +
16 swtr.utils.linkify(annotation.link) + '">' + annotation.link +
17 '</a></p>' : '';
18 });
19 annotorious.popup.addField(function(annotation) {
20 return (annotation.tags && annotation.tags.length) ? '<p>[' +
21 annotation.tags + ']</p>' : '';
22 });
2023 }
2124};
  
4848 initialize: function(opts) {
4949 this.template = _.template($('#sweet-template').html());
5050 this.helpview = opts.helpview;
51 //this.setElement(opts.el);
5251 },
5352 render: function() {
53 console.log('sweetsview rendering');
54 debugger;
5455 $('#sweet-list').html('<h4>These are your sweet annotations!</h4>');
5556 _.each(this.collection.models, function(swt) {
5657 if(swt.has('id')) {
9292 });
9393 this.collection.remove(notPosted);
9494 },
95 postSweets: function() {
95 postSweets: function(event) {
96 event.preventDefault();
97 console.log('posting swts');
98 debugger;
9699 var appView = swtr.appView;
97100 var self = this;
98101 this.helpview.step(5);
103103 try {
104104 this.collection.post({
105105 success: function(collection, response) {
106 console.log(collection, response);
107 swtr.sweets.set(collection);
106 console.log('updated', collection, response);
107 swtr.sweets.add(collection, {merge: true});
108 console.log('new swtr coll', swtr.sweets);
108109 appView.$overlay.hide();
109110 self.helpview.step(6);
111 self.trigger('postedSweets');
110112 },
111113 error: function(jqxhr, error, text) {
112114 console.log(jqxhr, error, text);
131131 }
132132 });
133133
134 var FilterView = Backbone.View.extend({
135 el: $('#filter-div'),
136 events: {
137 'click #filter-user-div input': 'filter',
138 'click #filter-tags-div input': 'filter'
139 },
140 initialize: function() {
141 this.filter_users_template = _.template($('#filter-users').html());
142 this.filter_tags_template = _.template($('#filter-tags').html());
143 this.render();
144 },
145 render: function() {
146 //console.log(this.collection);
147 // pluck uniq authors of sweets
148 var authors = _.uniq(this.collection.pluck('who'));
149 // render them as filter controls
150 _.each(authors, function(author) {
151 $('#filter-user-div').append(this.filter_users_template({
152 who: author
153 }));
154 }, this);
155
156 // pluck uniq tags of sweets
157 var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten().
158 uniq().value();
159
160 // render them as filter controls
161 _.each(tags, function(tag) {
162 if(tag) {
163 $('#filter-tags-div').append(this.filter_tags_template({
164 tag: tag
165 }));
166 }
167 }, this);
168
169 //this.delegateEvents();
170 },
171 filter: function(event) {
172 // get id of div - parent to parent to the clicked input
173 var target_id = $(event.currentTarget).parent().parent().attr('id');
174 // find out user/tag div
175 var which = target_id.split('-')[1];
176
177 var selected = [];
178 $('#'+target_id + ' input:checked').each(function() {
179 selected.push($(this).attr('name'));
180 });
181
182 if(which === 'user') {
183 this.filterUsers(selected);
184 }
185 else if(which === 'tags') {
186 this.filterTags(selected);
187 }
188 },
189 filterUsers: function(users) {
190 if(!users.length) {
191 return;
192 }
193 var filtered_swts = this.collection.filter(function(model) {
194 if(_.indexOf(users, model.get('who')) > -1) {
195 return model;
196 }
197 });
198 if(filtered_swts.length) {
199 anno.removeAll();
200 _.each(filtered_swts, function(swt) {
201 anno.addAnnotation(swt.get('how'));
202 });
203 }
204 },
205 filterTags: function(tags) {
206 if(!tags.length) {
207 return;
208 }
209 var filtered_swts = this.collection.filter(function(model) {
210 //TODO: find a better way of doing this..
211 var flag = false;
212 _.each(model.get('how').tags, function(tag) {
213 if(_.indexOf(tags, tag) > -1) {
214 flag = true;
215 }
216 });
217 if(flag === true) {
218 return model;
219 }
220 });
221 if(filtered_swts.length) {
222 anno.removeAll();
223 _.each(filtered_swts, function(swt) {
224 anno.addAnnotation(swt.get('how'));
225 });
226 }
227 }
228 });
229
230134 var AppView = Backbone.View.extend({
231135 el: $('body'),
232136 events: {
173173 });
174174
175175 var PlayAreaView = Backbone.View.extend({
176 id: '#play-page-container',
176 id: 'play-page-container',
177177 events: {
178178 'click #user-input-submit': 'submitUserInput',
179179 'click #sweet': 'sweet'
188188 helpview: this.helpview
189189 });
190190 this.$img = $('#annotatable-img');
191 //this.sweetsview.on('postedSweets', this.rerenderAnnos);
191192 this.helpview.step(1);
192193 },
193194 render: function() {
205205 var annos = _.filter(anno.getAnnotations(), function(anno) {
206206 return (!_.has(anno, 'editable') || anno.editable === true);
207207 });
208 console.log(annos);
208209
209210 _.each(annos, function(anno) {
210211 swtr.sweets.add({
217217 });
218218 },
219219 showSweets: function() {
220 console.log('showSweets');
220 //console.log('showSweets');
221221 this.sweetsview.render();
222222 },
223 sweet: function() {
223 sweet: function(event) {
224 event.preventDefault();
224225 console.log('sweeting');
226 debugger;
225227 this.getSweets();
228 debugger;
226229 this.showSweets();
230 debugger;
227231 return false;
228232 },
229233 // function to update the urls in the UI if an image is loaded internally
262262 var self = this;
263263 $.get('/media-type', {where: url}, function(response) {
264264 //console.log(response);
265 self.appView.$overlay.hide();
265 swtr.appView.$overlay.hide();
266266 if(response.type === 'image') {
267 this.initImageAnno(url);
267 self.initImageAnno(url);
268268 }
269269 else {
270270 window.location.href = '/annotate?where=' + url;
463463 var url = $(event.currentTarget).parent().parent().
464464 find('img').attr('src');
465465 //TODO: load the image in the play area/workbench
466 console.log('load image anno', url);
466 //console.log('load image anno', url);
467467 swtr.app_router.loadPlayArea(url, 'image');
468468 },
469469 search: function(data, cb) {
484484 var HelpView = Backbone.View.extend({
485485 id: 'helpview-wrapper',
486486 events: {
487 'click .close': 'clickedClose'
487488 },
488489 initialize: function() {
489490 this.template = _.template($('#helpview-template').html());
495495 $('#helpview-container').html(this.$el);
496496 this.$el.html(this.template({}));
497497 },
498 clickedClose: function(event) {
499 this.remove();
500 },
498501 //TODO: move from number based steps to something else. number based steps
499502 //implicitly imply sequential processing..which does not happen in this
500503 //case..
771771 }
772772 $('#' + id).show();
773773 this.highlight(id);
774 console.log('shown', id);
774 //console.log('shown', id);
775775 },
776776 highlight: function(id) {
777777 $('#swtr-navbar-collapse li').removeClass('active');
793793 loadPlayArea: function(url, type) {
794794 this.navigate('play', {trigger: true});
795795 this.mounted_component.loadURL(url, type);
796 }
797 });
798
799 var FilterView = Backbone.View.extend({
800 el: $('#filter-div'),
801 events: {
802 'click #filter-user-div input': 'filter',
803 'click #filter-tags-div input': 'filter'
804 },
805 initialize: function() {
806 this.filter_users_template = _.template($('#filter-users').html());
807 this.filter_tags_template = _.template($('#filter-tags').html());
808 this.render();
809 },
810 render: function() {
811 //console.log(this.collection);
812 // pluck uniq authors of sweets
813 var authors = _.uniq(this.collection.pluck('who'));
814 // render them as filter controls
815 _.each(authors, function(author) {
816 $('#filter-user-div').append(this.filter_users_template({
817 who: author
818 }));
819 }, this);
820
821 // pluck uniq tags of sweets
822 var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten().
823 uniq().value();
824
825 // render them as filter controls
826 _.each(tags, function(tag) {
827 if(tag) {
828 $('#filter-tags-div').append(this.filter_tags_template({
829 tag: tag
830 }));
831 }
832 }, this);
833
834 //this.delegateEvents();
835 },
836 filter: function(event) {
837 // get id of div - parent to parent to the clicked input
838 var target_id = $(event.currentTarget).parent().parent().attr('id');
839 // find out user/tag div
840 var which = target_id.split('-')[1];
841
842 var selected = [];
843 $('#'+target_id + ' input:checked').each(function() {
844 selected.push($(this).attr('name'));
845 });
846
847 if(which === 'user') {
848 this.filterUsers(selected);
849 }
850 else if(which === 'tags') {
851 this.filterTags(selected);
852 }
853 },
854 filterUsers: function(users) {
855 if(!users.length) {
856 return;
857 }
858 var filtered_swts = this.collection.filter(function(model) {
859 if(_.indexOf(users, model.get('who')) > -1) {
860 return model;
861 }
862 });
863 if(filtered_swts.length) {
864 anno.removeAll();
865 _.each(filtered_swts, function(swt) {
866 anno.addAnnotation(swt.get('how'));
867 });
868 }
869 },
870 filterTags: function(tags) {
871 if(!tags.length) {
872 return;
873 }
874 var filtered_swts = this.collection.filter(function(model) {
875 //TODO: find a better way of doing this..
876 var flag = false;
877 _.each(model.get('how').tags, function(tag) {
878 if(_.indexOf(tags, tag) > -1) {
879 flag = true;
880 }
881 });
882 if(flag === true) {
883 return model;
884 }
885 });
886 if(filtered_swts.length) {
887 anno.removeAll();
888 _.each(filtered_swts, function(swt) {
889 anno.addAnnotation(swt.get('how'));
890 });
891 }
796892 }
797893 });
798894