UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

833 lines (559 loc) 24.3 kB
<!DOCTYPE html> <!--#################################################################### THIS IS A GENERATED FILE -- ANY CHANGES MADE WILL BE OVERWRITTEN INSTEAD CHANGE: source: [object Object] @function can-view-callbacks.attr ######################################################################## --> <html lang="en"> <head> <meta charset="utf-8"> <title>CanJS - attr</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <link rel="stylesheet" type="text/css" href="./static/bundles/bit-docs-site/static.css"> <link rel="shortcut icon" sizes="16x16 24x24 32x32 48x48 64x64" href="/docs/images/canjs_favicon.ico"> <link rel="apple-touch-icon" sizes="57x57" href="../docs/images/canjs_favicon_57x57.png"> <link rel="apple-touch-icon-precomposed" sizes="57x57" href="../docs/images/canjs_favicon_57x57.png"> <link rel="apple-touch-icon" sizes="72x72" href="../docs/images/canjs_favicon_72x72.png"> <link rel="apple-touch-icon" sizes="114x114" href="../docs/images/canjs_favicon_114x114.png"> <link rel="apple-touch-icon" sizes="120x120" href="../docs/images/canjs_favicon_128x128.png"> <link rel="apple-touch-icon" sizes="144x144" href="../docs/images/canjs_favicon_144x144.png"> <link rel="apple-touch-icon" sizes="152x152" href="../docs/images/canjs_favicon_152x152.png"> <meta content="yes" name="apple-mobile-web-app-capable"> <meta name="apple-mobile-web-app-status-bar-style" content="white-translucent"> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-2302003-11', 'auto'); ga('send', 'pageview'); </script> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger"/> <label for="nav-trigger">Menu</label> <div id="everything"> <div id="left" class="column"> <div class="top-left"> <div class="brand"> <div class="logo"> <a href="../index.html" alt="CanJS"></a> <div class="dropdown project-dropdown"> <a href="https://donejs.com/">DoneJS</a> <a href="http://stealjs.com/">StealJS</a> <a href="http://jquerypp.com/">jQuery ++</a> <a href="https://funcunit.com/">FuncUnit</a> <a href="http://documentjs.com/">DocumentJS</a> </div> </div> <div class="version"> <div class="version-number"> 3.0.0 </div> <div class="dropdown version-dropdown"> <a href="https://v2.canjs.com">2.3.27</a> </div> </div> </div> <div class="search-bar"> <p> &nbsp; </p> </div> </div> <div class="bottom-left"> <div class="social-side-container"> <ul class="social-side"> <li> <a class="header-mobile github" href="https://github.com/canjs/canjs" target="_blank"><img class="social-icon-small" src="../docs/images/github.png">Github</a> </li> <li> <a class="header-mobile twitter" href="https://twitter.com/canjs" target="_blank"><img class="social-icon-small" src="../docs/images/twitter.png">Twitter</a> </li> </ul> <ul class="social-side"> <li> <a class="header-mobile" href="https://gitter.im/canjs/canjs" target="_blank">Chat</a> </li> <li> <a class="header-mobile" href="http://forums.donejs.com/c/canjs" target="_blank">Forum</a> </li> </ul> </div> <ul> <li class=" "> <a class="page" href="guides.html" title="Welcome to CanJS! These guides are here to help you develop and improve your relationship with CanJS. After all, picking a JavaScript framework is a commitment. We want CanJS to be the framework you marry. This page helps you know how advance through the different stages of this relationship:"> Guides </a> </li> <li class=" "> <a class="page" href="can-core.html" title="The best, most hardened and generally useful libraries in CanJS."> Core </a> </li> <li class=" "> <a class="page" href="can-ecosystem.html" title="Useful libraries that extend or add important features to the core collection."> Ecosystem </a> </li> <li class=" parent expanded"> <a class="page" href="can-infrastructure.html" title="Utility libraries that power the core and ecosystem collection."> Infrastructure </a> <ul> <li class=" "> <a class="module" href="can-construct.html" title="Provides a way to easily use the power of prototypal inheritance without worrying about hooking up all the particulars yourself. Use can-construct.extend to create an inheritable constructor function of your own."> can-construct </a> </li> <li class=" "> <a class="module" href="can-control.html" title="Create organized, memory-leak free, rapidly performing, stateful controls with declarative event binding. Use Control to create UI controls like tabs, grids, and context menus, and organize them into higher-order business rules with can.route. It can serve as both a traditional view and a traditional controller."> can-control </a> </li> <li class=" "> <a class="module" href="can-event.html" title="Add event functionality into your objects. The canEvent object provides a number of methods for handling events in objects. This functionality is best used by mixing the canEvent object into an object or prototype. However, event listeners can still be used even on objects that don&#x27;t include canEvent. All methods provided by canEvent assume that they are mixed into an object -- this should be the object dispatching the events."> can-event </a> </li> <li class=" "> <a class="module" href="can-event/async/async.html" title="Makes the event system asynchronous. WARNING: This is experimental technology."> can-event/async/async </a> </li> <li class=" "> <a class="module" href="can-event/batch/batch.html" title="Adds task batching abilities to event dispatching."> can-event/batch/batch </a> </li> <li class=" "> <a class="module" href="can-observation.html" title="Provides a mechanism to notify when an observable has been read and a way to observe those reads called within a given function."> can-observation </a> </li> <li class=" "> <a class="module" href="can-simple-map.html" title="A performant live-bound map."> can-simple-map </a> </li> <li class=" "> <a class="page" href="can-util.html" title="A set of utilities."> can-util </a> </li> <li class=" parent expanded"> <a class="module" href="can-view-callbacks.html" title="Registered callbacks for behaviors"> can-view-callbacks </a> <ul> <li> <span>types</span> <ul> <li class=" "> <a class="typedef" href="can-view-callbacks.attrData.html" title="The data provided to can-view-callbacks.attr."> attrData </a> </li> <li class=" "> <a class="typedef" href="can-view-callbacks.tagData.html" title="The data passed to can-view-callbacks.tag."> tagData </a> </li> </ul> </li> <li> <span>methods</span> <ul> <li class="current parent expanded"> <a class="function" href="can-view-callbacks.attr.html" title="Register custom behavior for an attribute."> attr </a> </li> <li class=" "> <a class="function" href="can-view-callbacks.tag.html" title=""> tag </a> </li> </ul> </li> </ul> </li> <li class=" "> <a class="module" href="can-view-live.html" title="Setup live-binding between the DOM and a compute manually."> can-view-live </a> </li> <li class=" "> <a class="module" href="can-view-model.html" title="Gets the ViewModel of an element."> can-view-model </a> </li> <li class=" "> <a class="module" href="can-view-nodelist.html" title="Adds nesting of text nodes can.view.nodeLists are used to make sure &quot;directly nested&quot; live-binding sections update content correctly. Consider the following template: &lt;div&gt; {{#if items.length}} Items: {{#items}} &lt;label&gt;&lt;/label&gt; {{/items}} {{/if}} &lt;/div&gt; The {{#if}} and {{#items}} seconds are &quot;directly nested&quot; because they share the same &lt;div&gt; parent element. If {{#items}} changes the DOM by adding more &lt;labels&gt;, {{#if}} needs to know about the &lt;labels&gt; to remove them if {{#if}} is re-rendered. {{#if}} would be re-rendered, for example, if all items were removed."> can-view-nodelist </a> </li> <li class=" "> <a class="module" href="can-view-parser.html" title="Parse HTML and mustache tokens."> can-view-parser </a> </li> <li class=" "> <a class="module" href="can-view-scope.html" title="Create a lookup node for keys."> can-view-scope </a> </li> <li class=" "> <a class="module" href="can-view-target.html" title=""> can-view-target </a> </li> </ul> </li> <li class=" "> <a class="page" href="can-legacy.html" title="Former libraries that we still accept patches for, but are not under active development."> Legacy </a> </li> </ul> </div> </div> <div id="right" class="column"> <div class="top-right"> <div class="top-right-top"> <ul class="top-right-bitovi"> <li class="dropdown"> <a href="http://bitovi.com" class="bitovi icon-bits">Bitovi</a> <ul class="dropdown-menu"> <li><a href="http://bitovi.com">Bitovi.com</a></li> <li><a href="http://bitovi.com/blog/">Blog</a></li> <li><a href="http://bitovi.com/consulting/">Consulting</a></li> <li><a href="http://bitovi.com/training/">Training</a></li> <li><a href="http://bitovi.com/open-source/">Open Source</a></li> </ul> </li> </ul> <div class="brand"> <div class="logo"> <a href="../index.html" alt="CanJS"></a> </div> </div> <ul class="top-right-links"> <li> <a href="https://gitter.im/canjs/canjs">Chat</a> </li> <li> <a href="http://forums.donejs.com/c/canjs">Forum</a> </li> <li> <a class="github-button nav-social" href="https://github.com/canjs/canjs" data-count-href="/canjs/canjs/stargazers" data-count-api="/repos/canjs/canjs#stargazers_count">Star</a> </li> <li> <a href="https://twitter.com/canjs" class="twitter-follow-button nav-social" data-show-count="true" data-show-screen-name="false">Follow @canjs</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> </li> </ul> </div> <div class="breadcrumb"> <li><a href="../index.html">CanJS</a></li> / <li><a href="can-infrastructure.html">Infrastructure</a></li> / <li><a href="can-view-callbacks.html">can-view-callbacks</a></li> / <li><a href="can-view-callbacks.attr.html">attr</a></li> <li class="breadcrumb-dropdown">/ <a> On this page</a> <ul class="on-this-page"></ul> </li> <div class="nav-toggle" title="Back to top"></div> </div> </div> <div class="bottom-right"> <article> <section class="title"> <div class="page-type"> <h1>attr</h1> <div>function</div> </div> <section class="description"> <p>Register custom behavior for an attribute.</p> </section> </section> <section class="on-this-page-table"> </section> <section class="title-footer"> <ul class="title-links"> <!-- <li><a href="#">docco</a></li> --> <li><a href="//github.com/canjs/can-view-callbacks/tree/v3.0.1/docs/attr.md">source</a></li> <!-- <li><a href="#">download</a></li> --> <!-- <li><a href="#">tests</a></li> --> </ul> </section> <div class="signature"> <h2 class="signature-title"> <code>callbacks.attr(attributeName, attrHandler(el, attrData))</code> </h2> <p>Registers the <code>attrHandler</code> callback when <code>attributeName</code> is found in a template.</p> <pre><code class="language-js">var canViewCallbacks = require(&quot;can-view-callbacks&quot;); canViewCallbacks.attr(&quot;show-when&quot;, function(el, attrData){ var prop = el.getAttribute(&quot;show-when&quot;); var compute = attrData.compute(prop); var showOrHide = function(){ var val = compute(); if(val) { el.style.display = 'block'; } else { el.style.display = 'hidden'; } }; compute.on(&quot;change&quot;, showOrHide); showOrHide(); domEvents.addEventListener.call( el, &quot;removed&quot;, function onremove(){ compute.off(&quot;change&quot;, showOrHide); domEvents.removeEventListener.call(&quot;removed&quot;, onremove); }); }); </code></pre> <div class="parameters"> <h3 class="parameters-title">Parameters</h3> <ol> <li><b>attributeName</b> <code>{String|RegExp}</code>: <p>A lower-case attribute name or regular expression that matches attribute names. Examples: <code>&quot;my-fill&quot;</code> or <code>/my-\w/</code>.</p> </li> <li><b>attrHandler</b> <code>{function(el, <a href="can-view-callbacks.attrData.html" title="The data provided to can-view-callbacks.attr.">attrData</a>)}</code>: <p>A function that adds custom behavior to <code>el</code>.</p> </li> </ol> </div> </div> <section class="body"> <h2>Use</h2> <p><code>canViewCallbacks.attr</code> is used to add custom behavior to elements that contain a specified html attribute. Typically it is used to mixin behavior (whereas <a href="can-view-callbacks.tag.html" title="">tag</a> is used to define behavior).</p> <p>The following example adds a jQueryUI tooltip to any element that has a <code>tooltip</code> attribute like <code>&lt;div tooltip=&quot;Click to edit&quot;&gt;Name&lt;/div&gt;</code>.</p> <div class='demo_wrapper' data-demo-src='demos/can-view-callbacks/tooltip.html'></div> <h2>Listening to attribute changes</h2> <p>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:</p> <pre><code>&lt;button tooltip=&quot;{{deleteTooltip}}&quot;&gt; Delete &lt;/button&gt; </code></pre> <p>Where <code>deleteTooltip</code> changes depending on how many users are selected:</p> <pre><code>deleteTooltip: function(){ var selectedCount = selected.length; if(selectedCount) { return &quot;Delete &quot;+selectedCount+&quot; users&quot;; } else { return &quot;Select users to delete them.&quot;; } } </code></pre> <p>The <a href="can-util/dom/events/attributes/attributes.html" title="Adds a listenable &quot;attributes&quot; event to DOM nodes, which fires when the node's attributes change.">attributes</a> event can be used to listen to when the toolip attribute changes its value like:</p> <pre><code class="language-js">canViewCallbacks.attr(&quot;tooltip&quot;, function( el, attrData ) { // A helper that updates or sets up the tooltip var updateTooltip = function(){ $(el).tooltip({ content: el.getAttribute(&quot;tooltip&quot;), items: &quot;[tooltip]&quot; }) } // When the tooltip attribute changes, update the tooltip domEvents.addEventListener.call(el, &quot;attributes&quot;, function(ev){ if(ev.attributeName === &quot;tooltip&quot;) { updateTooltip(); } }); // Setup the tooltip updateTooltip(); }); </code></pre> <p>To see this behavior in the following demo, hover the mouse over the &quot;Delete&quot; button. Then select some users and hover over the &quot;Delete&quot; button again:</p> <div class='demo_wrapper' data-demo-src='demos/can-view-callbacks/dynamic_tooltip.html'></div> <h2>Reading values from the scope.</h2> <p>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 <a href="can.view.Scope.html" title="undefined">scope</a>. For example, <strong>toggle</strong> and <strong>fade-in-when</strong> will need the value of <code>showing</code> in:</p> <pre><code>&lt;button toggle=&quot;showing&quot;&gt; {{#showing}}Show{{else}}Hide{{/showing}} more info&lt;/button&gt; &lt;div fade-in-when=&quot;showing&quot;&gt; Here is more info! &lt;/div&gt; </code></pre> <p>These values can be read from <a href="can-view-callbacks.attrData.html" title="The data provided to can-view-callbacks.attr.">attrData</a>'s scope like:</p> <pre><code>attrData.scope.attr(&quot;showing&quot;) </code></pre> <p>But often, you want to update scope value or listen when the scope value changes. For example, the <strong>toggle</strong> mixin might want to update <code>showing</code> and the <strong>fade-in-when</strong> mixin needs to know when the <code>showing</code> changes. Both of these can be achived by using <a href="can-view-scope.prototype.compute.html" title="">compute</a> to get a get/set compute that is tied to the value in the scope:</p> <pre><code>var showing = attrData.scope.compute(&quot;showing&quot;) </code></pre> <p>This value can be written to by <code>toggle</code>:</p> <pre><code>canViewCallbacks.attr(&quot;toggle&quot;, function(el, attrData){ var attrValue = el.getAttribute(&quot;toggle&quot;) toggleCompute = attrData.scope.compute(attrValue); $(el).click(function(){ toggleCompute(! toggleCompute() ) }) }) </code></pre> <p>Or listened to by <code>fade-in-when</code>:</p> <pre><code>canViewCallbacks.attr(&quot;fade-in-when&quot;, function( el, attrData ) { var attrValue = el.getAttribute(&quot;fade-in-when&quot;); fadeInCompute = attrData.scope.compute(attrValue), handler = function(ev, newVal, oldVal){ if(newVal &amp;&amp; !oldVal) { $(el).fadeIn(&quot;slow&quot;) } else if(!newVal){ $(el).hide() } } fadeInCompute.on(&quot;change&quot;,handler); ... }); </code></pre> <p>When you listen to something other than the attribute's element, remember to unbind the event handler when the element is <a href="can-util/dom/events/removed/removed.html" title="This event fires when the bound element is detached or destroyed.">removed</a> from the page:</p> <pre><code class="language-js">domEvents.addEventListener.call(el,&quot;removed&quot;, function(){ fadeInCompute.off(handler); }); </code></pre> <div class='demo_wrapper' data-demo-src='demos/can-view-callbacks/fade_in_when.html'></div> <h2>When to call</h2> <p><code>canViewCallbacks.attr</code> must be called before a template is processed. When <a href="http://canjs.com/docs/can.view.html#sig_can_view_idOrUrl_">using <code>can.view</code> to create a renderer function</a>, <code>canViewCallbacks.attr</code> must be called before the template is loaded, not simply before it is rendered.</p> <pre><code> //Call canViewCallbacks.attr first canViewCallbacks.attr('tooltip', tooltipFunction); //Preload a template for rendering var renderer = stache(&quot;&lt;div tooltip='Hi There'&gt;...&lt;/div&gt;&quot;); //No calls to canViewCallbacks.attr after this will be used by `renderer` </code></pre> </section> <script type="text/javascript"> var docObject = {"src":{"path":"node_modules/can-view-callbacks/docs/attr.md"},"description":"\nRegister custom behavior for an attribute.\n","title":"attr","name":"can-view-callbacks.attr","type":"function","parent":"can-view-callbacks/methods","signatures":[{"code":"callbacks.attr(attributeName, attrHandler(el, attrData))","description":"\n\nRegisters the `attrHandler` callback when `attributeName` is found\nin a template.\n\n```js\nvar canViewCallbacks = require(\"can-view-callbacks\");\n\ncanViewCallbacks.attr(\"show-when\", function(el, attrData){\n\tvar prop = el.getAttribute(\"show-when\");\n\tvar compute = attrData.compute(prop);\n\n\tvar showOrHide = function(){\n\t\tvar val = compute();\n\t\tif(val) {\n\t\t\tel.style.display = 'block';\n\t\t} else {\n\t\t\tel.style.display = 'hidden';\n\t\t}\n\t};\n\n\tcompute.on(\"change\", showOrHide);\n\tshowOrHide();\n\n\tdomEvents.addEventListener.call( el, \"removed\", function onremove(){\n\t\tcompute.off(\"change\", showOrHide);\n\t\tdomEvents.removeEventListener.call(\"removed\", onremove);\n\t});\n});\n```\n\n\n","params":[{"types":[{"type":"String"},{"type":"RegExp"}],"name":"attributeName","description":"A lower-case attribute name or regular expression\nthat matches attribute names. Examples: `\"my-fill\"` or `/my-\\w/`. \n"},{"types":[{"type":"function","returns":{"types":[{"type":"undefined"}]},"params":[{"types":[{"type":"HTMLElement"}],"name":"el"},{"types":[{"type":"can-view-callbacks.attrData"}],"name":"attrData"}]}],"name":"attrHandler","description":"\nA function that adds custom behavior to `el`. \n"}]}],"_curParam":{"types":[{"type":"function","returns":{"types":[{"type":"undefined"}]},"params":[{"types":[{"type":"HTMLElement"}],"name":"el"},{"types":[{"type":"can-view-callbacks.attrData"}],"name":"attrData"}]}],"name":"attrHandler","description":"\nA function that adds custom behavior to `el`. \n"},"comment":" ","pathToRoot":".."}; </script> </article> <footer><p>CanJS is part of <a href="http://donejs.com" target="_blank">DoneJS</a>. Created and maintained by the core <a href="https://donejs.com/About.html#section=section_Team" target="_blank">DoneJS team</a> and <a href="http://bitovi.com" target="_blank">Bitovi</a>. <strong>Currently 3.0.0.</strong></p></footer> </div> </div> </div> <script> steal = { instantiated: { "bundles/bit-docs-site/static.css!$css" : null } }; </script> <script type='text/javascript' data-main="bit-docs-site/static" src="./static/node_modules/steal/steal.production.js"></script> <script async defer src="https://buttons.github.io/buttons.js"></script> </body> </html>