Statistics
| Branch: | Tag: | Revision:

root / snf-app / synnefo / ui / static / snf / js / ui / web / ui_metadata_view.js @ 483c9197

History | View | Annotate | Download (8.1 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 tags",
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">tag</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.editing = true;
169
                this.editor.find(".form-field label").addClass("error");
170
            }
171

    
172
        },
173

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

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

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

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

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

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

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

    
219
        },
220

    
221
        show_create: function() {
222
            this.$(".editor .create").removeClass('in-progress');
223
            this.show_editor();
224
        },
225

    
226
        unbind_vm_handlers: function() {
227
            if (!this.current_vm) { return }
228
            this.current_vm.unbind("change", this.handle_vm_change);
229
        },
230

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

    
240
            this.update_vm_details();
241
            this.update_layout();
242
        },
243

    
244
        onClose: function() {
245
            this.editing = false;
246
            this.unbind_vm_handlers();
247
            this.current_vm = undefined;
248
        }
249
    });
250
    
251
})(this);