-1

I have a row-like layout, and on the rows, there are several text areas in embedded divs, just like the following:

 <div class="row-192">
  <div class="inner">
     <p>
       text
     </p>
     <textarea rows="4" cols="40"></textarea>
   </div>
 </div>

If the user resizes the textArea with the small triangle button, I need to adjust the current row height (and other properties) accordingly. I found some solutions in jQuery, but I need to stick to Angular directives only.

demo: http://jsfiddle.net/o0yvysL5/1/

Preferably, I would require some kind of an event, that I can subscribe to, like <textarea (resize)="resizeEvent($event)" ... but there are none.

Any ideas?

ForestG
  • 17,538
  • 14
  • 52
  • 86

2 Answers2

4

resizable.textarea.directive.ts

@Directive({
  selector: 'textarea[resize]'
})
export class ResizableTextAreaDirective {
  @Output() resize = new EventEmitter();

  width: number;
  height: number;

  mouseMoveListener: Function;

  @HostListener('mousedown', ['$event.target'])
  onMouseDown(el) {
    this.width = el.offsetWidth;
    this.height = el.offsetHeight;
    this.mouseMoveListener = this.renderer.listen('document', 'mousemove', () => {
      if (this.width !== el.offsetWidth || this.height !== el.offsetHeight) {
        this.resize.emit({ width: el.offsetWidth, height: el.offsetHeight });
      }
    });
  }

  @HostListener('document:mouseup')
  onMouseUp(el) {
    this.ngOnDestroy();
  }

  constructor(private renderer: Renderer2) {}

  ngOnDestroy() {
    if (this.mouseMoveListener) {
      this.mouseMoveListener();
    }
  }
}

Use it as follows:

<textarea (resize)="resizeEvent($event)"></textarea>

Stackblitz Example

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • this is a really nice solution! One minor thing though. with Google Chrome Version 59.0.3071.115 (Official Build) (64-bit) I can produce this with rapid mouse drag [screenshot](https://drive.google.com/file/d/16TaEfOJ0IsXPZON88Xv_XQgenpzl2vms/view?usp=sharing). In here, The height of the container div (green-grey lane) is set to the last emitted value. The last emit is still showing that the height is 67, although the textarea itself is smaller now (only 24px). I can only reproduce it in extreme cases, (moving the mouse down, then quickly up, passing over the textarea itself) – ForestG Nov 07 '17 at 14:34
1

This will fire a few extra events, but should work:

<textarea rows="4" cols="40" #ta 
    (mousemove)="$event.buttons === 1 ? updateSize(ta.clientHeight, ta.clientWidth) : null">
</textarea>

see also https://stackoverflow.com/a/526352/217408

or maybe even better:

<textarea rows="4" cols="40" #ta 
    (mouseup)="updateSize(ta.clientHeight, ta.clientWidth) : null">
</textarea>

see also https://stackoverflow.com/a/10218286/217408

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • The problem is that this won't work in the following scenario: 1. User clicks and start dragging the triangle 2. User moves the drag OUTSIDE the textArea 3. as the textArea cannot grow horizontally, the mouse will move outside the element 4. when the user is outside, or releases the click outside the textArea, no event will be called. – ForestG Nov 07 '17 at 13:43
  • also, for me, the mouseup and mousemove events fire if you click on the textArea, but not the triangle in the corner too. – ForestG Nov 07 '17 at 14:01
  • that's sad :-/ . – Günter Zöchbauer Nov 07 '17 at 14:18