Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use ng2-dragula and angular element resizer

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?

like image 331
RubyDigger19 Avatar asked Nov 07 '22 21:11

RubyDigger19


1 Answers

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.

like image 91
jimas13 Avatar answered Nov 15 '22 11:11

jimas13