Polymer 1.0: How to pass an argument to a Polymer function from an attribute?

29,583

Solution 1

You could utilize HTML5 data attributes instead. Try like this:

<paper-button id="foo" on-tap="bar" data-args="foo,some other value,2">Click</paper-button>
...
<script>
(function() {
  Polymer({
    is: 'example',
    properties: {...},
    bar: function(e){
      var args = e.target.getAttribute('data-args').split(',');
      // now args = ['foo', 'some other value', '2']
    }
  });
})();
</script>

Solution 2

After searching a lot, I found what I think is the cleanest possible solution.

If the paper-button is inside a template, e.g.

<template is="dom-repeat" items="{{allItems}}" as="item">
 <paper-button on-tap="itemTapped">[[item.text]]</paper-button>
</template>

Then the properties can be accessed via "model" property in event object passed to function.

itemTapped: function(oEvent){
// oEvent.model.get is the getter for all properties of "item" in your bound array
console.log(oEvent.model.get('item.task'));
}

Solution 3

Shining more light on a subtle difference mentioned in the comments above.

Notice $= must be used if reading a data binding.

<paper-button on-tap="_handleTap" data-foo="foo" data-bar$="[[bar]]">Tap</paper-button>

...

_handleTap: function(e) {
  var foo = e.target.dataset.foo;
  var bar = e.target.dataset.bar;
}

Inside dom-repeat, the item (or whichever name you give it) is available at e.model.item.

<template is="dom-repeat" items="[[items]]" as="someItem">
  <paper-button on-tap="_handleTap">Tap</paper-button>
</template>

...

_handleTap: function(e) {
  var item = e.model.someItem;
}

Solution 4

Is there a way to pass an argument to a Polymer function from an attribute of an element inside its <template>.

Instead of using an event use a computed binding. Computed bindings can accept literal strings.

Checkout the working example below. In this example a button can be hidden based on the parameter that is passed.

<script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html" />
<dom-module id="example-element">
	<template>
		<button id="foo-one" on-tap="barEvent">Click foo-one</button>
		<button id="foo-two" hidden="{{barTest('value-two')}}">Click foo-two</button>
		<button id="foo-three" hidden="{{barTest('value-three')}}">Click foo-three</button>
	</template>
</dom-module>
<script>
	Polymer({
		is: "example-element",
		barEvent: function (event) {
			console.log(event.target.id);
		},
		barTest: function (arg) {
			if (arg === "value-two") {
				return true;
			} else {
				return false;
			}
		}
	});
</script>

<example-element></example-element>

Note: You can get the id or other attributes of an element that an event is run on through event.target. If you are only looking for other attributes as parameters this might also be a valid solution.

Solution 5

After trying the solutions suggested here which none of them worked, I did a slight modification of @Amit and @Mowzer solutions I got it working like this:

<dom-module id="dial-buttons">

    <template>
        <div on-click="handleClick" data-args="0, num-input">
            <p>0</p>
            <paper-ripple></paper-ripple>
        </div>
    </template>

    <script>
        Polymer({
            is: 'dial-buttons',
            properties: { ... },
            handleClick: function(e) {
                var args = Polymer.dom(e).path[1].getAttribute('data-args').split(',');
                alert(args[0] + args[1]);
            }
        });
    </script>

</dom-module>
Share:
29,583
Let Me Tink About It
Author by

Let Me Tink About It

Just here to learn and grow as a coder/developer. I appreciate all the knowledge others share and I try to help out where I can. I am very thankful for your wisdom and grateful that you are willing to share it. I always ACCEPT and UPVOTE answers! 01101000011101000111010001110000011100110011101000101111001011110111011101110111011101110010111001111001011011110111010101110100011101010110001001100101001011100110001101101111011011010010111101110111011000010111010001100011011010000011111101110110001111010110010001010001011101110011010001110111001110010101011101100111010110000110001101010001 My formula for writing questions. State your goal. Describe the behavior you expect to see. Describe what you actually see. List the detailed steps to recreate the problem. (Optional) Describe any solutions you might have tried or areas where you think the problem might be. Ask the actual question itself. (Highlighting optional). Show your code. (Preferably in a demo like jsBin, plunkr, jsFiddle or CodePen.) See this example SO question.

Updated on July 17, 2020

Comments

  • Let Me Tink About It
    Let Me Tink About It almost 4 years

    Is there a way to pass an argument to a Polymer function from an element attribute inside its <template>?

    <script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html" />
    <dom-module id="example-element">
      <template>
        ...
        <paper-button id="foo" on-tap="bar">Click</paper-button>
        ...
      </template>
    </dom-module>
    <script>
      (function() {
        Polymer({
          is: 'example-element',
          properties: {...},
          bar: function(arg){
            // Do stuff using argument arg
          }
        });
      })();
    </script>
    

    Background Research

    I have combed through the documentation which appears silent on the matter. It doesn't say whether you can or can not. But when I try it, it fails. But maybe I'm not doing it correctly. So I need some assistance.

    The only thing I have come across is event listeners which doesn't seem to be able to take the arguments I want to pass. Say, an id or a name.

    Previous Attempts

    I have tried (unsuccessfully) doing things like:

    <paper-button id="foo" on-tap="bar('foo')"> Click </paper-button>
    

    but nothing seems to work.

    The event listeners idea doesn't work because they limit the arguments and I can't get the, say, id I need.

  • Let Me Tink About It
    Let Me Tink About It almost 9 years
    Actually, I had to use Polymer.dom(e).path[2].getAttribute('data-args'). See here: polymer-project.org/1.0/docs/devguide/events.html#retargetin‌​g Answer accepted!
  • Andrew
    Andrew over 8 years
    e.target.dataset.args has worked for me and looks a little cleaner.
  • Amit
    Amit over 8 years
    @Andrew - you're right. that's a better an cleaner syntax, and considering that I myself wrote HTML5, it's legitimate to use. But in reality, if not using the dataset property and doing it the way I did, you get better backward compatibility.
  • Goce Ribeski
    Goce Ribeski over 8 years
    What is the argument is from property, as: data-args="{{some_prop}}", upper solutions are not working. Any idea? (ping @Amit @Mowzer)
  • Goce Ribeski
    Goce Ribeski over 8 years
    founded, should be: data-args$="{{some_prop}}" polymer-project.org/1.0/docs/devguide/…
  • Mathter
    Mathter almost 8 years
    I used e.target.dataArgs and worked (maybe a more recent version?)
  • Raffaeu
    Raffaeu over 7 years
    Actually this is the correct answer using Polymer 1.7.0 APIs, the previous answer is now obsolete
  • Vaibhav Arora
    Vaibhav Arora over 7 years
    With the speed this framework is progressing, stack overflow can be misleading at times :).
  • Vaibhav Arora
    Vaibhav Arora over 7 years
    I think that holds true for every framework... For all it counts, I'll be active here, answering as many questions I encounter while developing since I'm working on Polymer for my weekend projects now ...
  • sudheeshix
    sudheeshix over 7 years
    In item.task, what does task signify? Couldn't find it in the template mentioned above.
  • Raffaeu
    Raffaeu over 7 years
    This is actually the correct version for Polymer >= 1.x So, this one should be marked as correct, according to Polymer docs
  • polarise
    polarise almost 7 years
    Hmm... this should be the right answer. Simple and clear.
  • Ch Faizan Mustansar
    Ch Faizan Mustansar almost 7 years
    It worked for me... and I think perhaps the best approach.
  • GGirard
    GGirard over 6 years
    This looks really linked to the dom-repeat feature only: polymer-project.org/2.0/docs/devguide/templates#handling-eve‌​nts