Text wrapping element with binding in Polymer 1.0
Asked Answered
M

1

11

I have created a custom web component with Polymer, that wraps text and alters it slightly (transforming to uppercase in this proof of concept).

The element itself works OK with static content. However, when the content is dynamically binded, the component fails to show the content.

For example:

<my-wrapper>Hello, World!</my-wrapper> <!-- Works -->
<my-wrapper>[[someText]]</my-wrapper> <!-- Doesn't work -->

Currently I am using observeNodes, which manages to trigger the initial text transform, but fails to trigger sub-sequential changes.

My current prototype is defined as:

<dom-module id="my-wrapper">
  <template>
    <span id="placeholder"></span>
  </template>
  <script>
    Polymer({
      is: 'my-wrapper',
      ready: function() {
        var self = this;
        Polymer.dom(Polymer.dom(this)).observeNodes(function(info) {
          self.$.placeholder.textContent = info.target.textContent.toUpperCase();
        });
        /*var mutationObserver = new MutationObserver(function(e) {
          console.log(e);
        });
        mutationObserver.observe(this.root, {characterData: true, childList: true});*/
      },
    });
  </script>
</dom-module>

And a working JSBin for the aforementioned problem can be found here: http://jsbin.com/jumewuzuho/1/edit?html,console,output.

Any suggestions on how to capture the change of the (light DOM) content, so that I can re-transform the text?

As you can see in the commented block of code, I have already tried using MutationObserver, but failed to create a working prototype. My guess is that I didn't used the correct node (this.root in my case).

Molarity answered 23/8, 2016 at 9:13 Comment(2)
have you found a solution to this? I'm also writing a text wrapper at the moment, but no solution has worked for me so far. The only thing that would do the job is passing the text as an attribute (which is not clean in my opinion)Phonics
@Yorrd: No, I haven't found the solution yet. I have also tried putting the element's content inside template tag along with the Templatizer behavior, but failed to produce any useful results.Molarity
T
1

I don't think ObserveNodes (or MutationObserver) are the best way to approach this. ObserveNodes tracks when children nodes are added and removed from your element.

In your case, DOM nodes are not being added or removed, it's simply the inner text of the element that is changing. Those changes are not picked up by the ObserveNodes.

I would recommend another approach, which in my modest opinion is more aligned with the polymer way of doing things, using the content tag:

To support composition of an element's light DOM with its local DOM, Polymer supports the content element. The content element provides an insertion point at which an element's light DOM is combined with its local DOM

I would use the content tag to create an insertion point and then style it via shadow DOM (text-transform: uppercase):

<dom-module id="my-wrapper">
  <template>
    <style>
      :host {
        text-transform: uppercase;
      }
    </style>
    <content></content>
  </template>
  <script>
    Polymer({
      is: 'my-wrapper'
    });
  </script>
</dom-module>
Tautomer answered 30/8, 2016 at 10:8 Comment(1)
Thank you for your input, but I am looking for a generic solution for detecting text change, since I will not be doing such simple transformations as presented in the question. I will try to create a text shortener, with a "View more" and "View less" toggle links. Currently I am binding the text to an attribute and it works for now. But I am still looking for a solution for the proposed problem.Molarity

© 2022 - 2024 — McMap. All rights reserved.