You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+81-36Lines changed: 81 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
<h1>Introduction</h1>
2
-
2
+
<p>
3
3
This proposal describes how support for "data linking" can be added to the jQuery core library. The term "data linking" is used here to mean "automatically linking the field of an object to another field of another object." That is to say, the two objects are "linked" to each other, where changing the value of one object (the 'source') automatically updates the value in the other object (the 'target').
4
-
4
+
</p>
5
5
<h2>Mutation Events</h2>
6
6
In order to link a source to a target, it is necessary to be notified when a data associated with the source object changes, so that it can be pushed onto the target object. This plugin adds some special events to jQuery to facilitiate this, which are also useful on their own.
7
7
8
8
<h3>attrChange</h3>
9
-
9
+
<p>
10
10
The 'attrChange' event fires when an attribute of a DOM element or object is changed through the jQuery.fn.attr or jQuery.attr methods. An interesting feature of this plugin is that it specifically allows for jQuery.fn.attr to be usable on plain objects or arrays. The data(), bind(), and trigger() methods all work with plain objects, so this is a natural extension which already mostly works. However, a small change was necessary to jQuery.attr to avoid the special cases applied when the target is a plain object, like class->className, and readonly->readOnly, and that negative values of "width" are ignored, etc. So this plugin also makes it officially possible to use attr() to set fields of an object as you would expect.
11
-
11
+
</p>
12
12
<pre>
13
13
function report(ev) {
14
14
alert("Change attr '" + ev.attrName + "' from '" +
// Note no event for 'z' because the scope of 'x' and 'y' was passed in
37
37
.attr( { x: "1", y: "2", z: "3" } );
38
38
</pre>
39
-
39
+
<p>
40
40
The attrChange event can also be used to capture changes made through the val() and data() methods. Notice that special treatment is given to how the change is represented by the event. This consolidation of the different mutation methods causing the same event makes it simpler to handle and prevents the need for separate "dataChange" and "valChange" events. It would be nice, actually, if attr() was thought of as a general purpose mutation method and also supported this construct. For example, $(..).attr("data:foo", "bar") or $(..).attr("val", "123"). However, that is not implemented and open to discussion.
The 'attrChanging' event fires when an attribute of a DOM element or object is about to be changed. The ev.preventDefault() method may be called in order to prevent the change from occuring.
60
+
</p>
59
61
60
62
<pre>
61
63
$("#el")
@@ -74,7 +76,9 @@ $("#el")
74
76
75
77
<h3>arrayChange</h3>
76
78
79
+
<p>
77
80
Like the attrChange event, but fires when an Array is mutated through any of the new array mutation APIs. Information about what the mutation was is available on the event object.
81
+
</p>
78
82
79
83
<pre>
80
84
var arr = [1,2,3];
@@ -86,10 +90,12 @@ $([arr])
86
90
$.push(arr, 4, 5);
87
91
</pre>
88
92
93
+
<p>
89
94
The following array mutation events are available as static methods on the jQuery object: push, pop, splice, shift, unshift, reverse, sort. The arguments supported for each are exactly like their built-ins, except the array is passed as the first parameter.
90
-
95
+
</p>
96
+
<p>
91
97
Like 'attrChange', the 'arrayChange' event supports filtering by the operation.
Exactly like the attrChanging event, but for arrays. Operation can be cancelled via the ev.preventDefault() method.
116
+
</p>
109
117
118
+
<h2>Linking Objects</h2>
110
119
111
-
<h2>Linking Objects<h2>
112
-
120
+
<p>
113
121
When objects are linked, changes to one are automatically forwarded to another. For example, this allows you to very quickly and easily link fields of a form to an object. Any changes to the form fields are automatically pushed onto the object, saving you from writing retrieval code. Furthermore, built-in support for converters lets you modify the format or type of the value as it flows between objects (for example, formatting a phone number, or parsing a string to a number).
122
+
</p>
114
123
115
124
<h3>jQuery.link</h3>
116
125
126
+
<p>
117
127
Sets up a link that pushes changes to any of the source objects to all target objects.
128
+
</p>
118
129
119
130
<pre>
120
131
var person = {};
@@ -128,13 +139,15 @@ alert(person.name); // foo
128
139
alert(person.name); // <usertypedvalue>
129
140
</pre>
130
141
131
-
The 'source' may be an object, DOM element, or string selector.
132
-
<strong>object</strong>
133
-
Changes to that object through a jQuery set wrapping it will trigger the link. e.g.:
142
+
<p>
143
+
The 'source' may be an object, DOM element, or string selector.<br/>
144
+
<strong>object</strong><br/>
145
+
Changes to that object through a jQuery set wrapping it will trigger the link. e.g.:<br/>
134
146
<code>$(obj).attr("foo", "bar");</code>
135
-
136
-
<strong>DOM element or selector</strong>
147
+
<br/>
148
+
<strong>DOM element or selector</strong><br/>
137
149
This sets up a link from all the matching elements (if it is a selector) to all matching targets. For example, if there are 3 inputs and 3 spans on the page, 9 links are created, one from each input to each span.
150
+
</p>
138
151
139
152
<pre>
140
153
$.link({
@@ -143,36 +156,42 @@ $.link({
143
156
});
144
157
</pre>
145
158
146
-
<strong>Attributes and Microdata</strong>
159
+
<strong>Attributes and Microdata</strong><br/>
147
160
The 'sourceAttr' and 'targetAttr' fields are optional. If omitted, the attribute is determined automatically:
148
-
161
+
<p>
149
162
The source attribute is determined as follows:
150
163
input, textarea, or select: "val"
151
164
any other dom element: "text"
152
-
165
+
</p>
166
+
<p>
153
167
The target attribute is determined as follows:
154
168
Source is a DOM element, and has 'itemprop' microdata attribute? Use the value.
155
169
Otherwise, use source.name or source.id.
156
170
If source is not a DOM element, use the same rules as source attribute.
157
-
171
+
</p>
172
+
<p>
158
173
This allows for simple links that target complex scenarios. For example, the following creates a link from all input elements inside #form1 to a single target object. The field set on the object is determined by first seeing if the input causing the event has an 'itemprop' attribute. If not, the input's name or id is used. In this example, the target's 'fullName' and 'birthday' fields would be set.
$.link supports creating multiple links with different rules at the same time. In this example, two form elements are mapped to two different fields of the same object.
194
+
</p>
176
195
177
196
<pre>
178
197
$.link({
@@ -186,7 +205,9 @@ $.link({
186
205
});
187
206
</pre>
188
207
208
+
<p>
189
209
Each value specified can be an array, or not. If not, the one value is applied to all cases. If an array, corresponding indexes of each array are used to create each link. Note that each source may also still match multiple elements if it is a selector. The full syntax is:
210
+
</p>
190
211
191
212
<pre>
192
213
$.link({
@@ -206,13 +227,17 @@ $.link({
206
227
});
207
228
</pre>
208
229
209
-
<strong>twoWay</strong>
230
+
<strong>twoWay</strong><br/>
210
231
232
+
<p>
211
233
The twoWay option sets up links in both directions -- from source to target, and target to source. Changes in either will be reflected in the other. This is the reason for the 'convert' option on the 'to' settings -- those converters would be used when pushing changes from a target to a source (reverse).
234
+
</p>
212
235
213
-
<strong>Updating immediately</strong>
236
+
<strong>Updating immediately</strong><br/>
214
237
238
+
<p>
215
239
Sometimes it is desired that the target of a link reflect the source value immediately, even before the source is changed. You can tell link() to update the target immediately using the 'update' setting:
Note that this is particularly useful when relying on the automatic target attribute determination. You can quickly populate an object with a form's current values by relying on <code>itemprop</code> attributes or input <code>name</code>, and setting update to true to force an immediate update.
231
-
257
+
</p>
258
+
<p>
232
259
Note that if you put 'update' on the 'from' settings, the source is updated with the target value, even though the link usually flows from the source to the target. This allows you, for example, to setup a link from an input to an object, but have the input initially reflect the value already in the target.
233
-
234
-
<strong>Context</strong>
235
-
260
+
</p>
261
+
<strong>Context</strong><br/>
262
+
<p>
236
263
$.link in both direct and from/to forms allows a 2nd jQuery context parameter. This context is used if any selectors are given. For example, these are equivalent:
237
-
264
+
</p>
238
265
<pre>
239
266
$.link({
240
267
from: {
@@ -258,16 +285,20 @@ $.link({
258
285
259
286
<h3>jQuery.unlink</h3>
260
287
288
+
<p>
261
289
This removes a link previously established with $.link. The syntax is exactly like $.link, including the from/to syntax, except that the 'convert' and 'update' parameters are not used. A link is identified by four pieces of data: source, sourceAttr, target, and targetAttr. Note that it is possible to remove only a portion of a link previously created. For example, assuming there are two elements on the page with css class "foo" (#foo1 and #foo2), the following creates two links -- one from each, then removes only one of them.
Links are cleaned up when its target or source is a DOM element that is being destroyed. For example, the following setups a link between an input and a span, then destroys the span by clearing it's parent html. The link is automatically removed.
$.liveLink is a powerful tool that links multiple elements now or in the future. For example, to map all the input fields of a form to an object, even when form fields are dynamically added in the future:
312
+
</p>
280
313
281
314
<pre>
282
315
$.liveLink({
@@ -289,18 +322,24 @@ $.liveLink({
289
322
});
290
323
</pre>
291
324
325
+
<p>
292
326
Note however that currently you cannot use 'twoWay' on a live link. You may use 'update'.
327
+
</p>
293
328
294
329
<h3>jQuery.unlinkLive</h3>
295
330
331
+
<p>
296
332
Removes a live link previously created with $.linkLive. Syntax is the same as unlink. Note that unlike regular links, live links do not expand into all the possible sources and targets when they are created. This means you cannot 'unliveLink' a portion of a live link, you may only remove the entire live link.
333
+
</p>
297
334
298
335
<h3>Conversion and jQuery.convertFn</h3>
299
336
337
+
<p>
300
338
Often times, it is necessary to modify the value as it flows from one side of a link to the other. For example, to convert null to "None", to format or parse a date, or parse a string to a number. The link APIs support specifying a converter function, either as a name of a function defined on jQuery.convertFn, or as a function itself.
301
-
339
+
</p>
340
+
<p>
302
341
The plugin comes with one converter named "!" which negates the value.
303
-
342
+
</p>
304
343
<pre>
305
344
var person = {};
306
345
$.convertFn.round = function(value) {
@@ -311,7 +350,9 @@ $("#name").val("7.5");
311
350
alert(person.age); // 8
312
351
</pre>
313
352
353
+
<p>
314
354
It is nice to reuse converters by naming them this way. But you may also specified the converter directly as a function.
355
+
</p>
315
356
316
357
<pre>
317
358
var person = {};
@@ -322,7 +363,9 @@ $("#name").val("7.5");
322
363
alert(person.age); // 8
323
364
</pre>
324
365
366
+
<p>
325
367
Converter functions receive the value that came from the source as the first parameter. They also receive a settings object which corresponds to the parameters given to the link API (if the from/to syntax was used, the settings are expanded into the more granular source/target form). This allows you to easily parameterize a converter.
368
+
</p>
326
369
327
370
<pre>
328
371
var person = {};
@@ -336,7 +379,9 @@ $("#name").val("red");
336
379
alert(person.age); // #FF0000
337
380
</pre>
338
381
382
+
<p>
339
383
The settings object also contains the source and target parameters. Say you wanted to link two different fields on the source to one field the target, as in combining the first and last name fields of an object onto a single "full name" span.
384
+
</p>
340
385
341
386
<pre>
342
387
var person = { firstName: "Some", lastName: "User" };
0 commit comments