validate cover extension in metadata dialog
[fnpeditor.git] / src / editor / plugins / core / metadataEditor / view.js
1 define([
2 'libs/jquery',
3 'libs/underscore',
4 'libs/text!./templates/main.html',
5 'libs/text!./templates/item.html',
6 'views/openSelect/openSelect',
7 'views/attachments/attachments'
8 ], function($, _, mainTemplate, itemTemplate, OpenSelectView, attachments) {
9
10 'use strict';
11 /* globals gettext */
12
13
14 var View = function(node, metadataConfig) {
15     this.node = node;
16     this.metadataConfig = metadataConfig;
17     this.dom = $(_.template(mainTemplate)());
18     this.adding = false;
19
20     var metaTable = this.metaTable = this.dom.find('table');
21     
22     this.dom.find('.rng-module-metadataEditor-addBtn').click(function() {
23         this.adding = true;
24         this.node.document.transaction(function() {
25             this.node.getMetadata().add('','');
26         }.bind(this), {
27             metadata: {
28                 description: gettext('Add metadata row')
29             }
30         });
31     }.bind(this));
32     
33     this.metaTable.on('click', '.rng-visualEditor-metaRemoveBtn', function(e) {
34         this.node.document.transaction(function() {
35             $(e.target).closest('tr').data('row').remove();
36         }, {
37             metadata: {
38                 description: gettext('Remove metadata row')
39             }
40         });
41     }.bind(this));
42     
43     this.metaTable.on('keydown', '[contenteditable]', function(e) {
44         /* globals document */
45         if(e.which === 13) {
46             if($(document.activeElement).hasClass('rng-module-metadataEditor-metaItemKey')) {
47                 metaTable.find('.rng-module-metadataEditor-metaItemValue').focus();
48             } else {
49                 var input = $('<input>');
50                 input.appendTo('body').focus();
51                 this.dom.find('.rng-module-metadataEditor-addBtn').focus();
52                 input.remove();
53             }
54             e.preventDefault();
55         }
56     }.bind(this));
57
58     this.metaTable.on('keyup', '[contenteditable]', _.throttle(function(e) {
59         if(e.which !== 13) {
60             var editable = $(e.target),
61                 toSet = editable.text(),
62                 row = editable.parents('tr').data('row'),
63                 isKey = _.last(editable.attr('class').split('-')) === 'metaItemKey',
64                 method = isKey ? 'setKey' : 'setValue';
65             row.metadata.node.document.transaction(function() {
66                 row[method](toSet);
67             }, {
68                 metadata: {
69                     description: gettext('Metadata edit')
70                 }
71             });
72         }
73     }, 500));
74
75     this.setMetadata(this.node); //
76
77     this.node.document.on('change', this.handleEvent, this);
78 };
79
80 _.extend(View.prototype, {
81     close: function() {
82         this.node.document.off('change', this.handleEvent);
83     },
84     handleEvent: function(event) {
85         if(event.type === 'metadataAdded' && event.meta.node.sameNode(this.node)) {
86             this.addMetadataRow(event.meta.row);
87         }
88         if(event.type === 'metadataChanged' && event.meta.node.sameNode(this.node)) {
89             this.updateMetadataRow(event.meta.row);
90         }
91         if(event.type === 'metadataRemoved' && event.meta.node.sameNode(this.node)) {
92             this.removeMetadataRow(event.meta.row);
93         }
94         if(event.type === 'nodeDetached' && event.meta.node.containsNode(this.node)) {
95             this.setMetadata(null);
96         }
97     },
98     getValuesForKey: function(key) {
99         var toret = [];
100         this.metadataConfig.some(function(configRow) {
101             if(configRow.key === key) {
102                 toret = configRow.values || [];
103                 return true;
104             }
105         });
106         return toret;
107     },
108     getIsFileForKey: function(key) {
109         var toret = false;
110         this.metadataConfig.some(function(configRow) {
111             if (configRow.key == key) {
112                 toret = configRow.isFile || false;
113                 return true
114             }
115         });
116         return toret;
117     },
118     setMetadata: function(node) {
119         this.dom.find('.rng-module-metadataEditor-addBtn').attr('disabled', !node);
120         if(!node) {
121             this.metaTable.html('');
122             return;
123         }
124         var view = this,
125             metadata = node.getMetadata();
126         this.metaTable.find('tr').remove();
127         metadata.forEach(function(row) {
128             view.addMetadataRow(row);
129         });
130     },
131     getMetadataByKey: function (key) {
132         var ret;
133         this.node.getMetadata().some(function (row) {
134             if (row.key == 'relation.coverimage.url') {
135                 ret = row.value;
136                 return true;
137             }
138         });
139         return ret;
140     },
141     addMetadataRow: function(row) {
142         console.log(row);
143         var newRow = $(_.template(itemTemplate)({key: row.getKey() || '', value: row.getValue() || ''}));
144         newRow.appendTo(this.metaTable);
145         newRow.data('row', row);
146
147         var keySelectView = new OpenSelectView({
148             value: row.getKey() || '',
149             inputTemplate: _.template('<div class="openInput rng-module-metadataEditor-metaItemKey" contentEditable="true"><%= value %></div>')({value: row.getKey() || '' }),
150             setInput: function(inputDOM, value) {
151                 if(inputDOM.text() !== value) {
152                     inputDOM.text(value);
153                     row.setKey(value);
154                 }
155                 valueSelectView.clearItems();
156                 this.getValuesForKey(value).forEach(function(value) {
157                     valueSelectView.addItem(value);
158                 });
159                 
160             }.bind(this)
161         });
162         newRow.find('td:first').append(keySelectView.el).data('view', keySelectView);
163
164
165         var valueSelectView = new OpenSelectView({
166             value: row.getValue(),
167             inputTemplate: _.template('<div class="openInput rng-module-metadataEditor-metaItemValue" contentEditable="true"><%= value %></div>')({value: row.getValue() || '' }),
168             maxHeight: '300px',
169             maxWidth: '100px',
170             setInput: function(inputDOM, value) {
171                 if(inputDOM.text() !== value) {
172                     inputDOM.text(value);
173                     row.setValue(value);
174                 }
175             }
176         });
177         newRow.find('td:nth-child(2)').append(valueSelectView.el).data('view', valueSelectView);
178
179         if (this.getIsFileForKey(row.getKey())) {
180             var el = $("<a href='#-' class='attachment-library' style='float: right'>" + gettext('attachments') + "</a>");
181             el.on('click', function() {
182                 attachments.select(function(v) {
183                     valueSelectView.setInput(v);
184                 });
185                 return false;
186             });
187             newRow.find('td:nth-child(2)').append(el);
188         }
189
190
191         this.metadataConfig.forEach(function(configRow) {
192             keySelectView.addItem(configRow.key);
193             if(row.getKey() === configRow.key) {
194                 (configRow.values || []).forEach(function(value) {
195                     valueSelectView.addItem(value);
196                 });
197             }
198         });
199
200         if(this.adding) {
201             $(newRow.find('td div')[0]).focus();
202             this.adding = false;
203         }
204         return newRow;
205     },
206     updateMetadataRow: function(row) {
207         this._getRowTr(row, function(tr) {
208             var tds = tr.find('td'),
209                 keyTd = $(tds[0]),
210                 valueTd = $(tds[1]);
211
212             keyTd.data('view').setInput(row.getKey());
213             valueTd.data('view').setInput(row.getValue());
214         });
215     },
216     removeMetadataRow: function(row) {
217         this._getRowTr(row, function(tr) {
218             tr.remove();
219         });
220     },
221     _getRowTr: function(row, callback) {
222         this.metaTable.find('tr').each(function() {
223             var tr = $(this);
224             if(tr.data('row') === row) {
225                 callback(tr);
226                 return false;
227             }
228         });
229     }
230 });
231
232
233 return View;
234
235
236 });