4

I'm using Dragula for drag and drop on my tables. Also I'm using plugin angular resizier element for resizing table columns. All this I've been working in Angular2.

So what I want is this. My current situation is like this gray column on image. Whole column width is draggable and that makes me a problem when resizing column. so when I'm trying to resize my column it acts like drag and drop. I want that my colum is like this yellow one. To have some space for resizing.

And here si part of my html code:

<div class="row" [dragula]='"one-bag"' [dragulaModel]='names'>
    <div class="col" *ngFor="let name of names"
         mwlResizable
         [validateResize]="validate"
         [resizeEdges]="{right: true}"
         [enableGhostResize]="false">
         <label>{{name}}</label>
    </div>  
</div>

here is resizer I've been using. https://github.com/mattlewis92/angular-resizable-element

Question: How could I use ng2-dragula and resizer on same table columns?

RubyDigger19
  • 775
  • 8
  • 34

1 Answers1

1

I've been having the same problem myself, but with ngDraggable instead of dragula...

Only solution i have thought of is to set Handlers for both, like mwlResizeableHandler HTMLElement for the resizeable module and another for the ngDraggable module, stop propagation of click events on both and force them to update the same Style object within the Component, which is then passed with ngStyle on to the element to determine its position on the browser.

I think that the source of the problem is the fact that ngDraggable implements a transformation : translate(x,y) while resizeable refers to an Styles Object, meaning top/left positioning.

I haven't implemented the solution yet, but once i configure it in code i will post an update.

EDIT/UPDATE:

okay, what i did was implement my own draggable functions, which proved easier on the long run. this is my resizable:

<div @fade id="{{index}}" class="box" [ngStyle]="style"
    mwlResizable 
    [validateResize]="validate"
    [resizeCursorPrecision]="resizeCursor"
    [enableGhostResize]="true"
    [ghostElementPositioning]="style.position"
    (resizeEnd)="onResizeEnd($event)"
    (click)="setSelected($event)"
    [ngClass]="{selected : selected}">
    <div 
    style="cursor: move; height: 50px; width: 50px; border: 2px solid black; background-color: green;"
    (mousedown)="onMouseDown($event)" 
    (mousemove)="onMove($event)"
    (mouseup)="finalPosition($event)"
    (mouseleave)="finalPosition($event)">
    </div>
    <img class="resize-handle-top-left" 
    mwlResizeHandle  
    [resizeEdges]="{top: true, left: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
    <img class="resize-handle-top-right" 
    mwlResizeHandle  
    [resizeEdges]="{top: true, right: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
    <img class="resize-handle-bottom-left" 
    mwlResizeHandle  
    [resizeEdges]="{bottom: true, left: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
    <img class="resize-handle-bottom-right" 
    mwlResizeHandle  
    [resizeEdges]="{bottom: true, right: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
  </div>
</div>

code that implements the resizing:

public onResizeEnd(event: ResizeEvent): void {
      this.style = {
      position: 'absolute',
      left: `${event.rectangle.left}px`,
      right: `${event.rectangle.right}px`,
      top: `${event.rectangle.top}px`,
      bottom: `${event.rectangle.bottom}px`,
      width: `${event.rectangle.width}px`,
      height: `${event.rectangle.height}px`
    };

so what i did was just a temporary box in the middle of the div and set some event listeners on it, mousedown, mousemove, mouseup. The checkBoundaries functions are just there to check that the drag does not exceed the parents DIV limitations:

checkBoundariesLeft(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > 0 && (styleAttr + tempMove) < (this.api.imageW - Number.parseInt(this.style.width))) {
      this.previousLeft = (styleAttr + tempMove);
      return this.previousLeft;
    }
    return this.previousLeft;
  }
  checkBoundariesRight(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > Number.parseInt(this.style.width) && (styleAttr + tempMove) < this.api.imageW) {
      this.previousRight = (styleAttr + tempMove);
      return this.previousRight;
    }
    return this.previousRight;
  }

  checkBoundariesTop(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > 0 && (styleAttr + tempMove) < (this.api.imageH - Number.parseInt(this.style.height))) {
      this.previousTop = (styleAttr + tempMove);
      return this.previousTop;
    }
    return this.previousTop;
  }

  checkBoundariesBottom(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > Number.parseInt(this.style.height) && (styleAttr + tempMove) < this.api.imageH) {
      this.previousBottom = (styleAttr + tempMove);
      return this.previousBottom;
    }
    return this.previousBottom;
  }

  public onMouseDown(event: MouseEvent): void {
    event.stopPropagation();
    this.moveElementInitiated = true;
    this.tempCoords = {
      left : event.offsetX,
      top : event.offsetY
    };
  }

  public onMove(event: MouseEvent): void {
    if (this.moveElementInitiated) {
      const tempLeft = (event.offsetX - this.tempCoords.left) / this.ratio;
      const tempTop = (event.offsetY - this.tempCoords.top) / this.ratio;
      this.style = {
        position: 'absolute',
        left: `${this.checkBoundariesLeft(Number.parseInt(this.style.left), tempLeft)}px`,
        right: `${this.checkBoundariesRight(Number.parseInt(this.style.right), tempLeft)}px`,
        top: `${this.checkBoundariesTop(Number.parseInt(this.style.top), tempTop)}px`,
        bottom: `${this.checkBoundariesBottom(Number.parseInt(this.style.bottom), tempTop)}px`,
        width: this.style.width,
        height: this.style.height
      };
    }
  }

  public finalPosition(event): void {
    this.moveElementInitiated = false;
  }

I should note that all functions Update the same style object within the component.

Arnaud P
  • 9,645
  • 3
  • 48
  • 57
jimas13
  • 106
  • 2
  • 10
  • 1
    FYI, your answer has been assigned to the 'low quality' review queue. I was going to recommend deletion since you don't actually know whether your answer works or not. But I changed my mind, and leave you a chance to update, since your seem to have a lead. Good luck. – Arnaud P Feb 23 '18 at 18:28
  • yeah sorry about that, i was in the middle of debugging my version, and it took me some time... – jimas13 Feb 28 '18 at 14:33
  • Ok thanks for sharing your solution. I've added a bit of [coloring](https://meta.stackoverflow.com/questions/274371/what-is-syntax-highlighting-and-how-does-it-work) as a bonus ;) – Arnaud P Mar 01 '18 at 09:44