jQuery & jQuery UI Documentation

jQuery & jQuery UI

jQuery Plugin

.link()

.link( target [, settings] ) Returns: jQuery

Description: Link changes to the matched elements to an object.

This documentation topic concerns the jQuery Datalink plugin (jquery-datalink), which can be downloaded from: http://github.com/jquery/jquery-datalink.

The .link() method links form fields to an object. Any changes to the form field values are automatically represented in the object. For example, when an input element whose name attribute is "firstName" is changed, the firstName property of the target is set to the new value:

var person = {};
$("form").link(person);
$("[name=firstName]").val("NewValue"); // Set firstName to a value.
person.firstName; // NewValue

// User types a value into the form field.
person.firstName; // firstName now contains the user-ented value.

By default, links are two-way, meaning changes to the object are also automatically changed in the corresponding form field. For example, if the firstName of the target is changed using the .setField() method, the value of input element named "firstName" is set to the new value.

// Set the object property.
$(person).setField("firstName", "NewValue");
// The change is automatically pushed to the input element.
$("[name=firstName]").val(); // The value is now "NewValue"

Customizing the Mapping Between Elements and Objects

By default, all change events that occur for (or bubble up to) the selected element or elements are processed, and the changes are made to the property whose name corresponds to the name of the element that changed. By providing a mapping object, you can explicitly choose which elements participate in linking behavior, and what target properties they set.

var person = {};
$("form").link(person, {
    firstName: "first-name",
    lastName: "last-name"
});

The preceeding example shows how to link only the input element named "first-name" to person.firstName, and the input element named "last-name" to person.lastName. Changes in other input elements and changes to other fields of the person object are ignored (by this link).

Specifying One-Way Linking

You can disable two-way linking for individual fields with the twoWay field in the custom mapping. The following example shows how to create a link from the form field named "firstName" to the firstName property of a person object, but not the other way around.

var person = {};
$("form").link(person, {
    firstName: {
      twoWay: false
    }
});
$(person).setField("firstName", "NewValue");
$("[name=firstName]").val(); // unchanged

Converting Values

By default, any changed value is assigned as-is to the target object. Often times, it is necessary to modify the value, as converting null to "None", formating or parsing a date, or parsing a string into a number. To perform these conversions, you can specify a convert field in the mapping that includes a conversion function, as shown in the following example:

var person = {};
$("[name=age]")
  .link(person, {
      age: {
          convert: function(value) {
              return Math.round( parseFloat( value ) );
          }
      }
  })
  .val("7.5");
person.age; // 8

You can also define a converter using the $.convertFn object and refer to it by name instead:

var person = {};
$.convertFn.round = function(value) {
    return Math.round( parseFloat( value ) );
}
$("[name=age]")
  .link(person, {
      age: {
          convert: "round"
      }
  })
  .val("7.5");
person.age; // 8

You can customize the name in a custom mapping at the same time as a converter by specifying the name. The following example creates a link from the input element named "first-name" to the firstName property of the person object using a converter named "titleCase".

$("form").link(person, {
    firstName: {
        name: "first-name",
        convert: "titleCase"
    }
});

For two-way links, you can specify a converter for both directions using convertBack setting:

$("form").link(obj, {
    field: {
        // converter1 and converter2 functions are defined elsewhere.
        convert: converter1,
        convertBack: converter2
    }
});

Converters receive the value and you can optionally also get the source object and the target object as parameters. The source is where the value comes from, and target is the object to set the value for. If the converter returns a value, it is assigned to the target automatically.

Using Converters to Create Custom Linking Behavior

If the converter does not return a value or if it returns "undefined", no automatic update occurs. You can use this feature to customize the behavior of a link by updating the source and target objects in your code directly and not returning a value. The following example uses a converter that does not return a value, so no automatic update takes place. Instead, the converter code explicitly updates properties of the target object:

var person = {};
$("[name=age]").link(person, {
    age: {
        convert: function(value, source, target) {
            var age = Math.round( parseFloat( value ) );
            target.age = age;
            target.canVote = age >= 18;
        }
    }
});
$("[name=age]").val("7.5");
person.age; // 8
person.canVote; // false
$("[name=age]").val("18");
person.canVote; // true

You can also use this technique to establish links between any available DOM elements. This following example links the age property of the person object to the height of the target DOM element.

var person = {};
$("#ageDiv").link(person, {
  age: {
    convertBack: function(value, source, target) {
      $(target).height(parseFloat(value * 2));
    }
  }
});
$(person).setField("age", 21);
$("#ageDiv").height(); // 42

Example:

Link all input elements of a form to an object.

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://github.com/jquery/jquery-datalink/raw/master/jquery.datalink.js"></script>
</head>
<body>
  
<form>
    <div>
        First Name:
        <input type="text" name="firstName" />
    </div>
    <div>
        Last Name:
        <input type="text" name="lastName" />
    </div>
</form>
Object.firstName: <span id="objFirst"></span><br/>
Object.lastName: <span id="objLast"></span>

<script>
    var person = { };
    $("form").link(person);

    // Chain link the person object to these elements to show the results
    $("#objFirst").link(person, {
        firstName: {
            name: "objFirst",
            convertBack: function(value, source, target) {
                $(target).text(value);
            }
        }
    });
    $("#objLast").link(person, {
        lastName: {
            name: "objLast",
            convertBack: function(value, source, target) {
                $(target).text(value);
            }
        }
    });
</script>

</body>
</html>