leonidas / transparency

Transparency is a semantic template engine for the browser. It maps JSON objects to DOM elements by id, class and data-bind attributes.
http://leonidas.github.com/transparency/
MIT License
969 stars 112 forks source link

onclick events / bind to function #148

Open coderofsalvation opened 8 years ago

coderofsalvation commented 8 years ago

right now im solving it like this, but it would be nice if the transparency would not treat directives as strings-only.

           items: {
              item: {
  +             onclick: function(params){
  +               return '('+function(){                                                                                                                                                            
  +                 alert('hello') 
  +                 alert("world") // using doublequotes will break
  +               }+')()'
  +             }
              }
            }

I've also tried this:

           items: {
              item: {
  +             onclick: function(params){
  +               $(params.element).click( function(){                                                                                                                                                            
  +                 alert('hello') 
  +                 alert("world")
  +               })
  +             }
              }
            }

How do you people handle click-events? Should we be able to do this in the future? :

            items: {
              item: {
  +             onclick: function(params){
  +               return function(){                                                                                                                                                            
  +                 alert('hello')
  +                 alert("world")
  +               } // currently this will be converted to a string unfortunately (so it doesn't work)
  +             }
              }
            }
woubuc commented 8 years ago

I don't think you should be able to set event handlers through Transparency. But to answer your question, you can simply bind the events after the items are rendered and use data-attributes to store information. At least, that's how I usually do it.

<div id="items">
    <div class="item">
        Click me
    </div>
</div>
// Data
var data = [
    { id: 'itemOne' },
    { id: 'itemTwo' },
    { id: 'itemThree' }
];

// Directives
var options = {
    item: {
        'data-id': function() { return this.id; }
    }
};

// Render everything
$('#items').render(data, options);

// After that, bind all the events you want
$('#items .item').on('click', function(){
    var id = $(this).data('id');
    // Use the id (or any other data-attribute you set) to identify which one was clicked
    // This is basically the method that you wanted to put in the directives.
    // I didn't test this code but it should give you an idea of what I'm talking about
});
coderofsalvation commented 8 years ago

Thank you for your time and reply. Yes this is also how i do things for simple key/values. However, references to objects are not possible like this. Don't you think this idea is a quite easy patch to enable twoway databinding?

woubuc commented 8 years ago

If I have apps with a more complex data structure, I usually have an object in the window scope called app (or something similar), containing all data and methods of the app. So when loading the objects I put them in app.items and then pass the key of each object to the element.

So, adding that to my previous example code:

window.app = {
    items: {}
};

app.items.itemOne = yourObject;
app.items.itemTwo = yourOtherObject;
app.items.itemThree = yourThirdObject;

And the click handler:

$('#items .item').on('click', function() {
    var id = $(this).data('id');
    var object = app.items[id];
    // Now you have your object.
});

That should do the trick.

On the topic of your suggestion: As far as I know, two-way data binding is out of the scope of the Transparency project. As for just adding click handlers: the whole idea of this library is to have a simple yet flexible way to render DOM elements on the page based on a JSON object. By nature, JSON objects don't contain methods, only primitive datatypes. So this type of functionality not being in Transparency is purely by design, not because it would be too complex to add it in.

That being said, you can of course always fork the repo and patch in any additional behaviour you need. I've done this too, for specific projects of mine that needed some additional features. But I doubt your suggestion will be implemented here. Of course, I'm just another Transparency user and not the dev, so I might be wrong.

If you really need 2-way binding or other advanced features, I would recommend you take a look at Knockout, which is my go-to library for more complex projects.