stevenrskelton / sortable-table

Polymer Web Component that generates a sortable <table> from inlined or AJAX JSON, JSON5, and arrays.
https://stevenrskelton.github.io/sortable-table/
MIT License
196 stars 37 forks source link

how to add button click even in cellTemplate? #12

Closed Hacky-DH closed 10 years ago

Hacky-DH commented 10 years ago

When I put paper-button in the my own cellTemplate, the on-click event does not fired. So how to make this happen? And how to add parameters to that click function?

ChrisMcKenzie commented 10 years ago

This is because the template is being bound inside the table element instead of in your element or definition. not sure how to get around this.

ChrisMcKenzie commented 10 years ago

Sooo I found a way accomplish this albeit not optimal, but you can extend the table and give the extended element a new attribute in which you pass a function through. then in your cellTemplate you can access that method. the only issue is I don't believe you get access to the table record

Example

usage:

<my-extended-table cellTemplate="myTemplate" myCustomAction="{{myFunc}}">
  <template ref="myTemplate">
    <td><button on-click="{{myFunc}}">
  </template>
</my-extended-table>

definition:

<polymer-element name="my-extended-table" attributes="myCustomAction" noscript>
</polymer-element>
stevenrskelton commented 10 years ago

The more generalized approach is to use a custom event. Binding the event handler directly to the event's source means every element between the event's source and the handler function has to explicitly pass through a reference to the function. There's no work when the function is in the same element/scope as the event source, but you've found you need to do extra work if the function is in a parent element. Now imagine the work if it was in the parent's parent element!

This code will have the button raise a custom event called myclick that can be caught by any other element. By including this as the event's payload msg you'll have access to every variable that this would have via it's template model.

<polymer-element name="special-button" extends="button" on-click="{{domystuff}}">
    <script>
        Polymer({
            domystuff: function(){ this.fire('myclick', this); }
        })
    </script>
</polymer-element>
<polymer-element name="click-example" on-myclick="{{dostuff}}">
    <template>
        <sortable-table>
            <sortable-column name="fruit" cellTemplate="myevent"></sortable-column>

            <template id="myevent">
                <td>
                    <button is="special-button">{{value}}</button>
                </td>
            </template>

            [
                {fruit: 'apple', alice: 4, bill: 10, casey: 2 },
                {fruit: 'banana', alice: 0, bill: 4, casey: 0 },
                {fruit: 'grape', alice: 2, bill: 3, casey: 5 },
                {fruit: 'pear', alice: 4, bill: 2, casey: 8 },
                {fruit: 'strawberry', alice: 0, bill: 14, casey: 0 },
                {fruit: 'apple', alice: 5, bill: 6, casey: 4 },
                {fruit: 'banana', alice: 3, bill: 9, casey: 2 },
                {fruit: 'grape', alice: 8, bill: 3, casey: 0 },
                {fruit: 'pear', alice: 0, bill: 7, casey: 4 },
                {fruit: 'strawberry', alice: 4, bill: 5, casey: 2 }
            ]
        </sortable-table>
    </template>
    <script>
    Polymer({
        dostuff: function(event,msg){
            console.log(msg.templateInstance.model);
        }
    });
    </script>
</polymer-element>
<click-example></click-example>

Back to the original post, the easiest way is to either wrap the paper-button inside a new custom element, or to expand the paper-button like I did in the code above. In all but the simplest cases you'll likely need to wrap it.

MetaMemoryT commented 9 years ago

This custom element approach should be mentioned in the docs.