DoneJS StealJS jQuery ++ FuncUnit DocumentJS
3.0.0
2.3.27

 

  • Github
  • Twitter
  • Chat
  • Forum
  • Guides
  • Core
  • Ecosystem
  • Infrastructure
    • can-construct
    • can-control
    • can-event
    • can-event/async/async
    • can-event/batch/batch
    • can-observation
    • can-simple-map
    • can-util
    • can-view-callbacks
      • types
        • attrData
        • tagData
      • methods
        • attr
        • tag
    • can-view-live
    • can-view-model
    • can-view-nodelist
    • can-view-parser
    • can-view-scope
    • can-view-target
  • Legacy
  • Bitovi
    • Bitovi.com
    • Blog
    • Consulting
    • Training
    • Open Source
  • Chat
  • Forum
  • Star
  • Follow @canjs
  • CanJS
  • /
  • Infrastructure
  • /
  • can-view-callbacks
  • /
  • tag
  • / On this page
    • tag

      function
      • source

      callbacks.tag(tagName, tagHandler(el, tagData))

      Registers the tagHandler callback when tagName is found in a template.

      var $ = require("jquery");
      require("jquery-datepicker");
      var canViewCallbacks = require("can-view-callbacks");
      
      canViewCallbacks.tag("date-picker", function(el, tagData){
          $(el).datePicker();
      });
      

      Parameters

      1. tagName {String}:

        A lower-case, hypenated or colon-seperated html tag. Example: "my-widget" or "my:widget". It is considered a best-practice to have a hypen or colon in all custom-tag names.

      2. tagHandler {function(el, tagData)}:

        Adds custom behavior to el. If tagHandler returns data, it is used to render tagData.subtemplate and the result is inserted as the childNodes of el.

      Use

      canViewCallbacks.tag is a low-level way to add custom behavior to custom elements. Often, you want to do this with can-component. However, callbacks.tag is useful for when can-component might be considered overkill. For example, the following creates a jQueryUI DatePicker everytime a <jqui-datepicker> element is found:

      callbacks.tag("jqui-datepicker", function(el, tagData){
        $(el).datepicker()
      })
      

      The tagHandler's tagData argument is an object that contains the stache Scope and helper Options where el is found and a subtemplate that renders the contents of the template within the custom tag.

      Getting values from the template

      tagData.scope can be used to read data from the template. For example, if I wanted the value of "format" within the current template, it could be read like:

      callbacks.tag("jqui-datepicker", function(el, tagData){
        $(el).datepicker({format: tagData.scope.get("format")})
      })
      
      var template = mustache("<jqui-datepicker></jqui-datepicker>")
      template({format: "mm/dd/yy"})
      

      tagData.options contains the helpers and partials provided to the template. A helper function might need to be called to get the current value of format like:

      callbacks.tag("jqui-datepicker", function(el, tagData){
        $(el).datepicker({format: tagData.options.get("helpers.format")()})
      })
      
      var template = mustache("<jqui-datepicker></jqui-datepicker>")
      template({},{format: function(){
        return "mm/dd/yy"
      }})
      

      Responding to changing data

      Often, data passed to a template is observable. If you use tag, you must listen and respond to chagnes yourself. Consider if format is property on a settings [can.Map] like:

      var settings = new Map({
        format: "mm/dd/yy"
      })
      

      You want to update the datepicker if format changes. The easiest way to do this is to use Scope's compute method which returns a get-set compute that is tied to a key value:

      callbacks.tag("jqui-datepicker", function(el, tagData){
      
        var formatCompute = tagData.scope.compute("format"),
            changeHandler = function(ev, newVal){
              $(el).datepicker("option","format", newVal});
            }
      
        formatCompute.bind("change",changeHandler)
      
        changeHandler({}, formatCompute());
      
        ...
      
      })
      
      var template = mustache("<jqui-datepicker/>")
      template(settings)
      

      If you listen on something outside the tag, it's a good practice to stop listening when the element is removed from the page:

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

      Subtemplate

      If content is found within a custom tag like:

      var template = stache(
        "<my-form>\
           <input value="{{first}}"/>\
           <input value="{{last}}"/>\
         </my-form>")
      

      A separate template function is compiled and passed as tagData.subtemplate. That subtemplate can be rendered with custom data and options. For example:

      callbacks.tag("my-form", function(el, tagData){
         var frag = tagData.subtemplate({
           first: "Justin"
         }, tagData.options)
      
         $(el).html( frag )
      })
      
      template({
        last: "Meyer"
      })
      

      In this case, the sub-template will not get a value for last. To include the original data in the subtemplate's scope, add to the old scope like:

      callbacks.tag("my-form", function(el, tagData){
         var frag = tagData.subtemplate(
           tagData.scope.add({ first: "Justin" }),
           tagData.options)
      
         $(el).html( frag )
      })
      
      template({
        last: "Meyer"
      })
      

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