DoneJS StealJS jQuery++ FuncUnit DocumentJS
3.14.1
5.0.0 4.3.0 2.3.35
  • About
  • Guides
  • API Docs
  • Community
  • Contributing
  • Bitovi
    • Bitovi.com
    • Blog
    • Design
    • Development
    • Training
    • Open Source
    • About
    • Contact Us
  • About
  • Guides
  • API Docs
    • Observables
      • can-compute
      • can-define
      • can-define/list/list
      • can-define/map/map
      • can-define-stream
      • can-define-stream-kefir
      • can-event
      • can-event/async/async
      • can-event/batch/batch
      • can-event/lifecycle/lifecycle
      • can-kefir
      • can-list
      • can-map
      • can-map-backup
      • can-map-define
      • can-observation
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
    • Data Modeling
      • can-connect
      • can-connect-cloneable
      • can-connect-feathers
      • can-connect-ndjson
      • can-connect-signalr
      • can-fixture
      • can-fixture-socket
      • can-ndjson-stream
      • can-set
    • Views
      • can-component
      • can-ejs
      • can-element
      • can-react-component
      • can-stache
      • can-stache/helpers/route
      • can-stache-bindings
      • can-stache-converters
      • can-view-autorender
      • can-view-callbacks
        • types
          • attrData
          • tagData
        • methods
          • attr
          • tag
      • can-view-href
      • can-view-import
      • can-view-live
      • can-view-model
      • can-view-nodelist
      • can-view-parser
      • can-view-scope
      • can-view-target
      • react-view-model
      • react-view-model/component
      • steal-stache
    • Routing
      • can-deparam
      • can-param
      • can-route
      • can-route-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-globals
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-string
      • can-string-to-any
      • can-util
      • can-zone
      • can-zone-storage
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-control
      • can-dom-events
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-jquery
    • Data Validation
      • can-define-validate-validatejs
      • can-validate
      • can-validate-interface
      • can-validate-legacy
      • can-validate-validatejs
    • Typed Data
      • can-cid
      • can-construct
      • can-construct-super
      • can-namespace
      • can-reflect
      • can-reflect-promise
      • can-types
    • Polyfills
      • can-symbol
      • can-vdom
    • Core
    • Infrastructure
      • can-global
      • can-test-helpers
    • Ecosystem
    • Legacy
  • Community
  • Contributing
  • GitHub
  • Twitter
  • Chat
  • Forum
  • News
Bitovi

attr

  • Edit on GitHub

Register custom behavior for an attribute.

callbacks.attr(attributeName, attrHandler(el, attrData))

Registers the attrHandler callback when attributeName is found in a template.

Handlers must be registered before templates using them are parsed.

var canViewCallbacks = require("can-view-callbacks");

canViewCallbacks.attr("show-when", function(el, attrData){
    var prop = el.getAttribute("show-when");
    var compute = attrData.compute(prop);

    var showOrHide = function(){
        var val = compute();
        if(val) {
            el.style.display = 'block';
        } else {
            el.style.display = 'hidden';
        }
    };

    compute.on("change", showOrHide);
    showOrHide();

    domEvents.addEventListener.call( el, "removed", function onremove(){
        compute.off("change", showOrHide);
        domEvents.removeEventListener.call("removed", onremove);
    });
});

Parameters

  1. attributeName {String|RegExp}:

    A lower-case attribute name or regular expression that matches attribute names. Examples: "my-fill" or /my-\w/.

  2. attrHandler {function(el, attrData)}:

    A function that adds custom behavior to el. Note that el might not be in the DOM when the callback is called.

Use

canViewCallbacks.attr is used to add custom behavior to elements that contain a specified html attribute. Typically it is used to mixin behavior (whereas tag is used to define behavior).

The following example adds a jQueryUI tooltip to any element that has a tooltip attribute like <div tooltip="Click to edit">Name</div>.

Listening to attribute changes

In the previous example, the content of the tooltip was static. However, it’s likely that the tooltip’s value might change. For instance, the template might want to dynamically update the tooltip like:

<button tooltip="{{deleteTooltip()}}">
  Delete
</button>

Where deleteTooltip() changes depending on how many users are selected:

    deleteTooltip: function(){
        var selectedCount = selected.length
        if(selectedCount) {
            return "Delete "+selectedCount+" users";
        } else {
            return "Select users to delete them.";
        }
    },

The attributes event can be used to listen to when the tooltip attribute changes its value like:

canViewCallbacks.attr("tooltip", function( el, attrData ) {
    // A helper that updates or sets up the tooltip
    var updateTooltip = function(){
        $(el).tooltip({
            content: el.getAttribute("tooltip"),
            items: "[tooltip]"
        })
    }
    // When the tooltip attribute changes, update the tooltip
    domEvents.addEventListener.call(el, "attributes", function(ev){
        if(ev.attributeName === "tooltip") {
            updateTooltip();
        }
    });
    // Setup the tooltip
    updateTooltip();

});

To see this behavior in the following demo, hover the mouse over the “Delete” button. Then select some users and hover over the “Delete” button again:

Reading values from the scope.

It’s common that attribute mixins need complex, observable data to perform rich behavior. The attribute mixin is able to read data from the element’s scope. For example, toggle and fade-in-when will need the value of showing in:

<button toggle="showing">
    {{#if(showing)}}Hide{{else}}Show{{/if}} more info
</button>
<div fade-in-when="showing">
    Here is more info!
</div>

These values can be read from attrData’s scope like:

attrData.scope.attr("showing")

But often, you want to update scope value or listen when the scope value changes. For example, the toggle mixin might want to update showing and the fade-in-when mixin needs to know when the showing changes. Both of these can be achieved by using compute to get a get/set compute that is tied to the value in the scope:

var showing = attrData.scope.compute("showing")

This value can be written to by toggle:

canViewCallbacks.attr("toggle", function(el, attrData){

    var attrValue = el.getAttribute("toggle")
        toggleCompute = attrData.scope.compute(attrValue);

    $(el).click(function(){
        toggleCompute(! toggleCompute() )
    })

})

Or listened to by fade-in-when:

canViewCallbacks.attr("fade-in-when", function( el, attrData ) {
    var attrValue = el.getAttribute("fade-in-when");
        fadeInCompute = attrData.scope.compute(attrValue),
        // handler for when the compute changes
        handler = function(ev, newVal, oldVal){
            if(newVal && !oldVal) {
                $(el).fadeIn("slow")
            } else if(!newVal){
                $(el).hide()
            }
        }

    fadeInCompute.on("change",handler);

    ...

})

When you listen to something other than the attribute’s element, remember to unbind the event handler when the element is removed from the page:

domEvents.addEventListener.call(el,"removed", function(){
    fadeInCompute.off(handler);
});

When to call

canViewCallbacks.attr must be called before a template is processed. When using can-stache to create a renderer function, canViewCallbacks.attr must be called before the template is loaded, not simply before it is rendered.

//Call canViewCallbacks.attr first
canViewCallbacks.attr('tooltip', tooltipFunction);
//Preload a template for rendering
var renderer = stache("<div tooltip='Hi There'>...</div>");
//No calls to canViewCallbacks.attr after this will be used by `renderer`

CanJS is part of DoneJS. Created and maintained by the core DoneJS team and Bitovi. Currently 3.14.1.

On this page

Get help

  • Chat with us
  • File an issue
  • Ask questions
  • Read latest news