Search code examples
jquery-templatesjsrenderjsviews

Set data to elements in jsrender


I try to set the data to the elements in jsrender.

Eg: {{setdata:id 'hai' 'hello'}}

jQuery.views.converters({
          setdata: function(id){
              var key = this.tagCtx.args[1];
              var value = this.tagCtx.args[2];

              jQuery("#" + id).data(key, value);
              return "";
          },
});

Is there any way to set the data easily instead of directly in html.


Solution

  • Your example would not work because JsRender render method converts from data to a string (HTML markup) which you then insert into the DOM (http://www.jsviews.com/#rendertmpl). So when the converter is called, the element you are targeting has not yet been instantiated.

    So to set data you have to use the HTML markup data-xxx="..." so it gets set on the element when you insert it into the DOM.

    Here are some variants. You can write:

    <div id="a" data-foo="bar"></div>
    <div id="b" data-{{:key}}="{{:value}}"></div>
    <div id="c" {{setdata:'hai' 'hello'}}></div>
    <div id="d" {{setdata:key value}}></div>
    

    with

    jQuery.views.converters({
      setdata: function(key, value){
        return "data-" + key + "='" + value + "'";
      }
    });
    

    and get

    console.log($("#a").data('foo')
      + " " + $("#b").data('hai')
      + " " + $("#c").data('hai')
      + " " + $("#d").data('hai')); // bar hello hello hello
    

    Passing and object to an HTML element: use JsViews:

    If you want to pass in an object as data, not a string (your examples above are strings, so your question is not clear on this), then you need to use jsviews.js, not jsrender.js, and the link() method, rather than the render method (http://www.jsviews.com/#jsv-quickstart). Now you have access to the elements so you can do these variants too:

    <div id="e" data-link="data-key{:~myOb}"></div>
    <div id="f" data-link="{setdata 'myKey' ~myOb}"></div>
    

    using

    jQuery.views.tags({
      setdata: function(key, value) {
        $(this.linkCtx.elem).data(key, value);
      }
    });
    

    and

    tmpl.link("#result", myData, {myOb: {foo: "fooValue"}});
    console.log($("#e").data('myKey').foo
      + " " + $("#f").data('myKey').foo); //fooValue fooValue