Revision 34f802f7

b/snf-cyclades-app/synnefo/ui/static/snf/js/lib/rivets.conf.js
1
function _resolve_keypath(obj, keypath) {
2
  _obj = obj;
3
  _key = keypath;
4
  
5
  var map = [];
6
  
7
  keypath = keypath.replace(/^model\./, '');
8
  keypath = keypath.replace(/^item\./, '');
9

  
10
  _.each(keypath.split("."), function(key) {
11
    // key = vm, name
12
    var is_last = (keypath.indexOf(key) == (keypath.length-key.length))
13
    if (is_last) {
14
      map.push([_obj, key]);
15
      return;
16
    }
17

  
18
    map.push([_obj, key]);
19
    _key = key;
20
    _obj = _obj.get(key);
21
  });
22
  
23
  return map
24
}
25

  
26
COLLECTION_EVENTS = ['add', 'remove', 'update', 'reset']
27

  
28
_.extend(rivets.formatters, {
29

  
30
  prefix: function(value, prefix) {
31
    return prefix + value.toString();
32
  },
33
  
34
  collection_size: function(col) {
35
    return col.models.length;
36
  },
37

  
38
  collection_machines_size: function(col) {
39
    var items = {};
40
    col.each(function(m) {
41
      if (!items[m.get('device_id')]) {
42
        items[m.get('device_id')] = 1
43
      }
44
    });
45
    return _.keys(items).length
46
  },
47

  
48
  lower: function(value) {
49
    return value.toString().toLowerCase();
50
  },
51

  
52
  parenthesize: function(value) {
53
    return "({0})".format(value);
54
  },
55
  
56
  intEq: function(value, cmp) {
57
    return parseInt(value) == parseInt(cmp);
58
  }
59

  
60
});
61

  
62
_.extend(rivets.binders, {
63
  'collection-view': {
64
    block: true,
65
    bind: function(el) {
66
      if (this.bound) { return }
67
    },
68

  
69
    unbind: function(el) {
70
    },
71
    
72
    update: function(el, value) {
73
    },
74

  
75
    routine: function(el, value) {
76
      if (!value) {
77
        try {
78
          if (this.keypath) {
79
            value = this.view.models.model.get(this.keypath);
80
          } else {
81
            value = this.view.models.model;
82
          }
83
        } catch (err) {
84
          console.log("value error");
85
        }
86
      }
87

  
88
      if (!value || this._bind_value != value) {
89
        if (this.bound) {
90
          this._bind_view.hide();
91
          this.view.models.view.remove_view(this._bind_view);
92
          delete this._bind_view;
93
          delete this._bind_value;
94
        }
95
        this.bound = false;
96
      }
97
      
98
      if (!this.bound && value) {
99
        var specs = this.options.formatters[0].split(",");
100
        var cls_name = specs[0];
101
        var params = specs[1];
102
        var view_cls = synnefo.views[cls_name];
103
        var view_params = {collection: value};
104
        if (params) {
105
          _.extend(view_params, JSON.parse(params));
106
        }
107
        var view = this.view.models.view.create_view(view_cls, view_params);
108
        this.view.models.view.add_subview(view);
109
        view.show(true);
110
        this._bind_view = view;
111
        this._bind_value = value;
112

  
113
        this.bound = true;
114
        $(el).append(view.el);
115
      }
116
    }
117
  },
118
  'model-view': {
119
    block: true,
120
    bind: function(el) {
121
      if (this.bound) { return }
122
    },
123

  
124
    unbind: function(el) {
125
    },
126
    
127
    update: function(el, value) {
128
    },
129

  
130
    routine: function(el, value) {
131
      if (!value) {
132
        try {
133
          if (this.keypath) {
134
            value = this.view.models.model.get(this.keypath);
135
          } else {
136
            value = this.view.models.model;
137
          }
138
        } catch (err) {
139
          console.log("value error");
140
        }
141
      }
142

  
143
      if (!value || this._bind_value != value) {
144
        if (this.bound) {
145
          this._bind_view.hide();
146
          this.view.models.view.remove_view(this._bind_view);
147
          delete this._bind_view;
148
          delete this._bind_value;
149
        }
150
        this.bound = false;
151
      }
152
      
153
      if (!this.bound && value) {
154
        var specs = this.options.formatters[0].split(",");
155
        var cls_name = specs[0];
156
        var params = specs[1];
157
        var view_cls = synnefo.views[cls_name];
158
        var view_params = {model: value};
159
        if (params) {
160
          _.extend(view_params, JSON.parse(params));
161
        }
162
        var view = this.view.models.view.create_view(view_cls, view_params);
163
        this.view.models.view.add_subview(view);
164
        view.show(true);
165
        this._bind_view = view;
166
        this._bind_value = value;
167

  
168
        this.bound = true;
169
        $(el).append(view.el);
170
      }
171
    }
172
  }
173
});
174

  
175
rivets.configure({
176
  prefix: 'rv',
177
  preloadData: true,
178

  
179
  handler: function(target, event, binding) {
180
    var func = binding.model[binding.keypath];
181
    func.call(binding.model, binding.view.models.model, event);
182
  },
183

  
184
  adapter: {
185

  
186
    subscribe: function(root_obj, keypath, callback) {
187
      if (!(root_obj instanceof Backbone.Model) && 
188
          !(root_obj instanceof Backbone.Collection)) {
189
        return;
190
      }
191

  
192
      var bind_map = _resolve_keypath(root_obj, keypath);
193
      var last_key, last_obj;
194
      last_key = bind_map[0][1];
195
      last_obj = bind_map[0][0];
196

  
197
      // TODO: Clean up :)
198
      _.each(bind_map, function(data) {
199
        var obj, key;
200
        obj = data[0]; key = data[1];
201
        
202
        var collection = last_obj[key] || last_obj.get && last_obj.get(key);
203
        if (collection instanceof Backbone.Collection) {
204
          obj = collection;
205
          _.each(COLLECTION_EVENTS, function(e) {
206
            obj.bind(e, callback);
207
          });
208
          last_obj = obj;
209
          last_key = key;
210
          return;
211
        }
212

  
213
        if (!obj) {
214
          var cb = function() {
215
            obj.bind('change:' + key, callback);
216
          }
217
          function reg_handler(last_obj, lkey, obj, callback) {
218
            var last_key = lkey;
219
            var resolve_obj = function(model, value, key) {
220
              if (value) {
221
                last_obj.unbind('change:' + key, resolve_obj);
222
                delete last_obj['__pending_rivet_bind'];
223
              }
224
              var key = last_key;
225
            }
226
            last_obj.bind('change:' + last_key, resolve_obj);
227
          }
228
          last_obj.__pending_rivet_bind = [last_key, reg_handler];
229
          reg_handler(last_obj, last_key, obj, callback);
230
        } else {
231
          obj.bind('change:' + key, callback);
232
        }
233
        last_key = key;
234
        last_obj = obj;
235
      });
236
    },
237
    
238
    unsubscribe: function(obj, keypath, callback) {
239
      if (!(obj instanceof Backbone.Model) && 
240
          !(obj instanceof Backbone.Collection)) {
241
        return;
242
      }
243
      var bind_map = _resolve_keypath(obj, keypath);
244
      _.each(bind_map, function(data) {
245
        var obj, key;
246
        obj = data[0]; key = data[1];
247
        if (!obj) {
248
          return
249
        }
250
        if ('__pending_rivet_bind' in obj) {
251
          var opts = obj.__pending_rivet_bind;
252
          obj.unbind('change:'+opts[0], opts[1]);
253
        }
254
        if (obj instanceof Backbone.Collection) {
255
          _.each(COLLECTION_EVENTS, function(e) {
256
            obj.unbind(e, callback);
257
          });
258
        } else {
259
          obj.unbind('change:' + key, callback);
260
        }
261
      });
262
    },
263
    
264
    read: function(obj, keypath) {
265
      if (!(obj instanceof Backbone.Model) && !(obj instanceof Backbone.Collection)) {
266
        return;
267
      }
268
      var result;
269
      var bind_map = _resolve_keypath(obj, keypath);
270
      var last = _.last(bind_map);
271
      if (!last[0]) {
272
        return '';
273
      }
274
      result = last[0].get(last[1]);
275
      // array of models or collection ????
276
      //if (result instanceof Backbone.Collection) {
277
        //return result
278
      //}
279
      return result
280
    },
281
    
282
    publish: function(obj, keypath, value) {
283
      throw "Publish not available"
284
    },
285

  
286
  }
287
});

Also available in: Unified diff