somecallmejosh somecallmejosh - 5 months ago 23
Javascript Question

Default Param on Polymer.js Input Range

I'm trying to use Polymer.js with an

input[type="range"]
to bind the current value of the range slider in an associated
<output>
element. Everything works with the exception of my default input value in the
input
. The value param doesn't show up in the DOM, and my range sliders are set to zero, as seen here:

Initial Load

enter image description here

After Slide Event

After I update/slide the sliders on the input, the expected value is bound to the
<output>
as seen below.

enter image description here

Template

<dom-module id="item-selection">
<link rel="stylesheet" href="item-selection.scss" />
<template>
<template is="dom-repeat" items="{{sliders}}">
<div class="slider-group">
<label>{{item.name}}</label>
<output>{{item.initialValue}}</output>
<input type="range"
min="{{item.minValue}}"
max="{{item.maxValue}}"
value="{{item.initialValue::input}}"
id="{{item.id}}"
step="1"
>
</div>
</template>
<a href="#" class="button">Button Text</a>
</template>

<script src="item-selection.js"></script>
</dom-module>


JS:

Polymer({
is: "item-selection",
ready: function() {
this.sliders = [
{
name: "item-one",
id: "item-one-id",
initialValue: 175,
minValue: 100,
maxValue: 200
},
{
name: "item-two",
id: "item-one-id",
initialValue: 175,
minValue: 100,
maxValue: 281
},
{
name: "item-three",
id: "item-one-id",
initialValue: 150,
minValue: 100,
maxValue: 200
}
]
}
});


DOM Inspection

<div class="slider-group style-scope item-selection">
<label class="style-scope item-selection">item-two</label>
<output class="style-scope item-selection">175</outpute>
<input type="range" step="1"
class="style-scope item-selection"
id="item-one-id"
max="281" min="100">
</div>
...


Is there a way to set a default value as well as allow the databinding on the input elements? I looked through https://www.polymer-project.org/1.0/docs/devguide/data-binding to see if I could find a solution, but nothing seems obvious to me.

Answer

UPDATE As you discovered, the order of the max and value bindings changes whether the <input>'s value is initialized (and that varies by browser). I've created a GitHub issue for this Polymer bug.

You might consider using a <paper-slider> instead, which doesn't exhibit this problem in any browser:

<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-slider/paper-slider.html">
</head>

<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
    <template is="dom-repeat" items="{{sliders}}">
      <div class="slider-group">
        <label>{{item.name}}</label>
        <output>{{item.initialValue}}</output>
        <paper-slider
               min="{{item.minValue}}"
               max="{{item.maxValue}}"
               value="{{item.initialValue}}"
               step="1"></paper-slider>
      </div>
    </template>
    </template>
    <script>
      HTMLImports.whenReady(function() {
        Polymer({
          is: 'x-foo',
          properties : {
            sliders: {
              type: Array,
              value: function() {
                return [
                  {
                    name: "item-one",
                    id: "item-one-id",
                    initialValue: 120,
                    minValue: 100,
                    maxValue: 200
                  },
                  {
                    name: "item-two",
                    id: "item-one-id",
                    initialValue: 175,
                    minValue: 100,
                    maxValue: 200
                  },
                  {
                    name: "item-three",
                    id: "item-one-id",
                    initialValue: 150,
                    minValue: 100,
                    maxValue: 200
                  }
                ];
              }
            }
          }
        });
      });
    </script>
  </dom-module>
</body>

codepen


Binding max seems to cause the problem for some reason. Removing the max binding and hard-coding it allows the initial value to take effect, as seen in the demo below.

<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>

<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
    <template is="dom-repeat" items="{{sliders}}">
      <div class="slider-group">
        <label>{{item.name}}</label>
        <output>{{item.initialValue}}</output>
        <input type="range"
               min="{{item.minValue}}"
               max="200"
               value="{{item.initialValue::input}}"
               step="1">
      </div>
    </template>
    </template>
    <script>
      HTMLImports.whenReady(function() {
        Polymer({
          is: 'x-foo',
          properties : {
            sliders: {
              type: Array,
              value: function() {
                return [
                  {
                    name: "item-one",
                    id: "item-one-id",
                    initialValue: 120,
                    minValue: 100,
                    maxValue: 200
                  },
                  {
                    name: "item-two",
                    id: "item-one-id",
                    initialValue: 175,
                    minValue: 100,
                    maxValue: 200
                  },
                  {
                    name: "item-three",
                    id: "item-one-id",
                    initialValue: 150,
                    minValue: 100,
                    maxValue: 200
                  }
                ];
              }
            }
          }
        });
      });
    </script>
  </dom-module>
</body>

codepen

Comments