Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_metadata_view.js @ b042eb04

History | View | Annotate | Download (7.9 kB)

1
;(function(root){
2

    
3
    // root
4
    var root = root;
5
    
6
    // setup namepsaces
7
    var snf = root.synnefo = root.synnefo || {};
8
    var models = snf.models = snf.models || {}
9
    var storage = snf.storage = snf.storage || {};
10
    var ui = snf.ui = snf.ui || {};
11
    var util = snf.util = snf.util || {};
12

    
13
    var views = snf.views = snf.views || {}
14

    
15
    // shortcuts
16
    var bb = root.Backbone;
17

    
18

    
19
    views.MetadataView = views.Overlay.extend({
20
        
21
        view_id: "metadata_view",
22
        content_selector: "#metadata-overlay-content",
23
        css_class: 'overlay-metadata overlay-info',
24
        overlay_id: "metadata-overlay",
25

    
26
        subtitle: "",
27
        title: "Manage metadata",
28

    
29
        initialize: function(options) {
30
            views.MetadataView.__super__.initialize.apply(this);
31
            _.bindAll(this);
32

    
33
            this.current_vm = undefined;
34
            this.list = this.$(".options-list");
35
            this.tpl = this.$("li.meta-object-tpl");
36
            this.editor = this.$(".editor");
37

    
38
            this.pre_init_handlers();
39
        },
40

    
41
        pre_init_handlers: function() {
42
            this.$(".editor .cancel").click(_.bind(function(){
43
                this.close_editor();
44
            }, this))
45
            this.$(".editor .create").click(_.bind(function(){
46
                this.submit_editor();
47
            }, this));
48
        },
49

    
50
        show: function(vm) {
51
            this.current_vm = vm;
52
            this.current_vm.bind("change", this.handle_vm_change);
53
            views.MetadataView.__super__.show.apply(this);
54
        },
55

    
56
        get_meta: function() {
57
            return this.current_vm.get_meta();
58
        },
59
        
60
        get_meta_el: function(key, value) {
61
            return this.tpl.clone();
62
        },
63

    
64
        beforeOpen: function() {
65
            this.update_layout();
66
        },
67

    
68
        update_layout: function() {
69
            if (!this.editing) {
70
                this.editor.hide();
71
            }
72

    
73
            this.update_vm_details();
74
            // update metadata
75
            this.list.empty();
76
            _.each(this.get_meta(), _.bind(function(value, key) {
77
                var el = this.get_meta_el();
78
                el.find(".title").text(util.truncate(key, 15)).attr("title", key);
79
                el.find(".value").text(util.truncate(value, 15)).attr("title", value);
80
                el.data('meta', {'key':key, 'value':value});
81
                this.list.append(el);
82
                $(el).data({key:key, value:value});
83
            }, this));
84

    
85
            this.list.append('<li class="options-object create">' + 
86
                             '<div class="options-object-cont">' +
87
                             '<span class="title">Add new</span>' + 
88
                             '<span class="value">metadata key</span>' + 
89
                             '</div>' + 
90
                             '</li>')
91

    
92
            this.list.show();
93
            this.init_handlers();
94
        },
95
        
96
        meta_from_el: function(el) {
97
            return el.closest("li").data("meta");
98
        },
99
    
100
        show_editor: function(meta, el) {
101
            this.editing = true;
102

    
103
            this.editor.find("label").removeClass("error");
104
            if (meta) {
105
                this.editor.find(".predefined").hide();
106
                this.editor.find("input.meta-key").val(meta.key).attr("disabled", true);
107
                this.editor.find("input.meta-value").val(meta.value);
108
            } else {
109
                this.editor.find(".predefined").show();
110
                this.editor.find("input.meta-key").val("").attr("disabled", false);
111
                this.editor.find("input.meta-value").val("");
112
            }
113
            this.$(".editor").fadeIn(200);
114

    
115
            if (meta) {
116
                this.editor.find("input.meta-value").focus().select();
117
            } else {
118
                this.editor.find("input.meta-key").focus();
119
            }
120
            
121
            // remove predefined for existing keys
122
            var existing_keys = this.current_vm.get_meta();
123
            if (!meta) {
124
                this.editor.find(".predefined-meta-key").each(function(i, el){
125
                    if (existing_keys[$(el).text()]) {
126
                        $(el).hide();
127
                    } else {
128
                        $(el).show();
129
                    }
130
                })
131
            }
132
        },
133

    
134
        update_vm_details: function() {
135
            // show proper title
136
            this.set_subtitle(this.current_vm.get("name") + snf.ui.helpers.vm_icon_tag(this.current_vm, "small"));
137
        },
138

    
139
        validate: function(meta) {
140
            if (!meta) { return false };
141
            if ((meta.key && meta.key != "") && (meta.value && meta.value != "")) {
142
                return true;
143
            }
144
            return false;
145
        },
146

    
147
        get_editor_values: function() {
148
            var meta = {};
149
            meta.key = this.editor.find("input.meta-key").val();
150
            meta.value = this.editor.find("input.meta-value").val();
151

    
152
            meta.key = _(meta.key).trim();
153
            meta.value = _(meta.value).trim();
154
            return meta;
155
        },
156
    
157
        submit_editor: function() {
158
            if (!this.editing) { return };
159
            this.editing = false;
160
            var meta = this.get_editor_values();
161
            if (this.validate(meta)) {
162
                this.$(".editor .create").addClass('in-progress');
163
                this.current_vm.save_meta(meta, _.bind(function() {
164
                    this.close_editor();
165
                    this.$(".editor .create").removeClass('in-progress');
166
                }, this));
167
            } else {
168
                this.editor.find(".form-field label").addClass("error");
169
            }
170

    
171
        },
172

    
173
        remove_meta: function(key) {
174
            this.current_vm.remove_meta(key);
175
        },
176

    
177
        close_editor: function() {
178
            this.$(".editor").fadeOut(100);
179
            this.editing = false;
180
        },
181

    
182
        init_handlers: function() {
183
            var self = this;
184
            this.list.find(".remove").click(function(e){
185
                e.preventDefault();
186
                var meta = self.meta_from_el($(this));
187
                self.remove_meta(meta.key);
188
                $(this).parent().remove();
189
            });
190

    
191
            this.list.find(".edit").click(function(e) {
192
                e.preventDefault();
193
                var meta = self.meta_from_el($(this));
194
                self.show_editor(meta, $(this));
195
            })
196

    
197
            //this.list.find(".options-object").dblclick(function(e) {
198
                //e.preventDefault();
199
                //var meta = self.meta_from_el($(this));
200
                //self.show_editor(meta, $(this));
201
            //})
202

    
203
            this.list.find("li.create").click(function(){
204
                self.show_create();
205
            })
206
            
207
            this.editor.find("input").keyup(_.bind(function(e){
208
                if (e.keyCode == 13) { this.submit_editor() };    
209
            }, this));
210

    
211
            this.editor.find(".predefined-meta-key").click(function() {
212
                self.editor.find("input.meta-key").val($(this).text());
213
                self.editor.find("input.meta-value").focus();
214
            })
215

    
216
        },
217

    
218
        show_create: function() {
219
            this.$(".editor .create").removeClass('in-progress');
220
            this.show_editor();
221
        },
222

    
223
        unbind_vm_handlers: function() {
224
            if (!this.current_vm) { return }
225
            this.current_vm.unbind("change", this.handle_vm_change);
226
        },
227

    
228
        handle_vm_change: function(vm) {
229
            // if overlay has been closed and for
230
            // some reason change event still triggers
231
            // force event unbind
232
            if (!this.current_vm) {
233
                vm.unbind("change", this.handle_vm_change);
234
                return;
235
            } 
236

    
237
            this.update_vm_details();
238
            this.update_layout();
239
        },
240

    
241
        onClose: function() {
242
            this.editing = false;
243
            this.unbind_vm_handlers();
244
            this.current_vm = undefined;
245
        }
246
    });
247
    
248
})(this);