0

I would like to synchronize the width of DOM elements such that the width is always the smallest width that can accommodate the content. I can successfully increase the size by $watching for an increase (based on ref1 & ref2), but I can't figure out how to shrink the element after it's been enlarged.

Angular directive:

app.directive('syncWidth', function () { //declaration; identifier master
  return {
    restrict: 'A',
    link: function (scope, element) {
      var linkElement = element[0];

      scope.$watch(
        function () {
          return (linkElement.scrollWidth);
        },
        function (newValue, oldValue) {
          if (newValue > oldValue) {
            scope.testWidth = {
              'min-width': newValue + 'px'
            }
          }
        },
        true
      );
    }
  };
});

HTML:

<input type="text" ng-model="myText">
<input type="text" ng-model="myText2">

<div sync-width="test" style="background-color: lightblue" ng-style="testWidth">1 [{{myText}}]</div>
<div sync-width="test" style="background-color: lightcoral" ng-style="testWidth">2 [{{myText2}}]</div>

I'm assuming the issue is that the two elements are referencing another. I'm thinking the pseudocode would look something like:

Set a global groupMinWidth variable
Detect element.contentWidth changed
If newContentWidth > groupMinWidth {
  groupMinWidth = newContentWidth;
}

If oldContentWidth == groupMinWidth {
  check all synchronized elements and set groupMinWidth to the largest contentWidth;
}

Thanks for the help.

3
  • can't really understand your requirement.. there are two divs, once increase the width of one of them, you want to increase the other to the same width ? is that right ? when you shrink one of them, do you want to shrink the other to the same width ? Commented Apr 21, 2016 at 21:43
  • Correct, although the content will change dynamically (e.g. from the input boxes in my example). I've been able to expand each element as I add text, but I would like to shrink both of them if I delete text. Here's a plunker of what I have so far: plnkr.co/edit/ZsL3OnYwyglxEciSbXYp?p=preview Commented Apr 21, 2016 at 22:18
  • I still can't quite get it to work, but I think the (or at least a) solution might require nesting a <div> inside and grabbing the scroll-width from the child and using that with a widthManager that stores all the widths of the synchronized content and updates the parent (which will probably need to have an overflow:hidden property so it only gets its width updated via the script). Commented Apr 22, 2016 at 2:17

1 Answer 1

0

I'm now working on the plunkr but not fully working yet : https://plnkr.co/edit/6XfGMzI1su8cpHjkyDWC?p=preview . The point is $watching the change on the text, when the text gets reduced, use a shared value/global value to record and check which one's width is the widest , set the min-width to that value to both of the elements.

===EDIT===

Finally make this work: https://plnkr.co/edit/c2FOu5LfPfGfnkU12KTG?p=preview

So the principle behind this is : I need a changeable div to measure the scrollWidth/offsetWidth when the content changed. So I add a new nested div which include the content. I made the inner div as a float and once the content changed I will update the outer div's width by setting it's width to the inner div's width. The key point is because the inner div is FLOAT, it can overflows the outer div's right border, but the out div is watching the change on the content, so the outer div's width will be updated immediately.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.