forked from jupiterjs/jquerymx
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelements.js
More file actions
145 lines (137 loc) · 4.2 KB
/
elements.js
File metadata and controls
145 lines (137 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
steal('jquery',function($){
var getId = function( inst ) {
return inst[inst.constructor.id]
},
each = $.each,
// returns a collection of unique items
// this works on objects by adding a "__u Nique" property.
unique = function( items ) {
var collect = [];
// check unique property, if it isn't there, add to collect
each(items, function( i, item ) {
if (!item["__u Nique"] ) {
collect.push(item);
item["__u Nique"] = 1;
}
});
// remove unique
return each(collect, function( i, item ) {
delete item["__u Nique"];
});
};
$.extend($.Model.prototype,
{
/**
* Returns a unique identifier for the model instance. For example:
* @codestart
* new Todo({id: 5}).identity() //-> 'todo_5'
* @codeend
* Typically this is used in an element's shortName property so you can find all elements
* for a model with [jQuery.Model.prototype.elements elements].
* @return {String}
*/
identity: function() {
var id = getId(this),
constructor = this.constructor;
return (constructor._fullName + '_' + (constructor.escapeIdentity ? encodeURIComponent(id) : id)).replace(/ /g, '_');
},
/**
* Returns elements that represent this model instance. For this to work, your element's should
* us the [jQuery.Model.prototype.identity identity] function in their class name. Example:
*
* <div class='todo <%= todo.identity() %>'> ... </div>
*
* This also works if you hooked up the model:
*
* <div <%= todo %>> ... </div>
*
* Typically, you'll use this as a response to a Model Event:
*
* "{Todo} destroyed": function(Todo, event, todo){
* todo.elements(this.element).remove();
* }
*
*
* @param {String|jQuery|element} context If provided, only elements inside this element
* that represent this model will be returned.
*
* @return {jQuery} Returns a jQuery wrapped nodelist of elements that have this model instances
* identity in their class name.
*/
elements: function( context ) {
var id = this.identity();
if( this.constructor.escapeIdentity ) {
id = id.replace(/([ #;&,.+*~\'%:"!^$[\]()=>|\/])/g,'\\$1')
}
return $("." + id, context);
},
hookup: function( el ) {
var shortName = this.constructor._shortName,
models = $.data(el, "models") || $.data(el, "models", {});
$(el).addClass(shortName + " " + this.identity());
models[shortName] = this;
}
});
/**
* @add jQuery.fn
*/
// break
/**
* @function models
* Returns a list of models. If the models are of the same
* type, and have a [jQuery.Model.List], it will return
* the models wrapped with the list.
*
* @codestart
* $(".recipes").models() //-> [recipe, ...]
* @codeend
*
* @param {jQuery.Class} [type] if present only returns models of the provided type.
* @return {Array|jQuery.Model.List} returns an array of model instances that are represented by the contained elements.
*/
$.fn.models = function( type ) {
//get it from the data
var collection = [],
kind, ret, retType;
this.each(function() {
each($.data(this, "models") || {}, function( name, instance ) {
//either null or the list type shared by all classes
kind = kind === undefined ? instance.constructor.List || null : (instance.constructor.List === kind ? kind : null);
collection.push(instance);
});
});
ret = new(kind || $.Observe.List);
ret.push.apply(ret, unique(collection));
return ret;
};
/**
* @function model
*
* Returns the first model instance found from [jQuery.fn.models] or
* sets the model instance on an element.
*
* //gets an instance
* ".edit click" : function(el) {
* el.closest('.todo').model().destroy()
* },
* // sets an instance
* list : function(items){
* var el = this.element;
* $.each(item, function(item){
* $('<div/>').model(item)
* .appendTo(el)
* })
* }
*
* @param {Object} [type] The type of model to return. If a model instance is provided
* it will add the model to the element.
*/
$.fn.model = function( type ) {
if ( type && type instanceof $.Model ) {
type.hookup(this[0]);
return this;
} else {
return this.models.apply(this, arguments)[0];
}
};
});