swiety85 / angular2gridster

Angular implementation of well known Gridster (no jQuery, no external libraries, only Angular and Rx.js).
https://swiety85.github.io/angular2gridster/
MIT License
203 stars 75 forks source link

Is this the correct way to implement my own component into this grid? #316

Open C-odes opened 5 years ago

C-odes commented 5 years ago

Hi, I read that you need to put your components within a div as the component will be the content and should not have anything to do with the gridster item sizing and placement on the grid.

So it made me wonder if my way of doing it is good practice or bad. First of all I found this in the source code and used it: gridsterDraggableOptions: IGridsterDraggableOptions = { handlerClass: 'panel-heading' }; So the components need to implement panel-heading and that html will be draggable. I have components that are Cards (bootstrap 4) and the card-header is supposed to be draggable.

when I placed my component inside the sourcecode widget div, I got 2 headings. I wanted the heading of my own component. This is how it looked like:

  <ngx-gridster-item *ngFor="let widget of widgets; let indx = index" #itemComp
                 [options]="itemOptions"
                 [dragAndDrop]="widget.dragAndDrop" [resizable]="widget.resizable"
                 [(x)]="widget.x" [(y)]="widget.y"
                 [(xSm)]="widget.xSm" [(ySm)]="widget.ySm"
                 [(xMd)]="widget.xMd" [(yMd)]="widget.yMd"
                 [(xLg)]="widget.xLg" [(yLg)]="widget.yLg"
                 [(xXl)]="widget.xXl" [(yXl)]="widget.yXl"
                 [(w)]="widget.w" [(h)]="widget.h"
                 [(wSm)]="widget.wSm" [(hSm)]="widget.hSm"
                 [(wMd)]="widget.wMd" [(hMd)]="widget.hMd"
                 [(wLg)]="widget.wLg" [(hLg)]="widget.hLg"
                 [(wXl)]="widget.wXl" [(hXl)]="widget.hXl"
                 (change)="itemChange($event, gridster1)">

      <div class="panel-heading">
          <h5 class="panel-title">{{ widget.title }}</h5>
      </div>

      <div class="panel-body">
          <p>
            Position: {{itemComp?.item?.x}} x {{itemComp?.item?.y}}<br>
            Size: {{itemComp?.item?.w}} x {{itemComp?.item?.h}}<br>
          </p>
          <p>
              <label>
                  <input type="checkbox" [(ngModel)]="widget.dragAndDrop" value="true"> Draggable
              </label>
              <label>
                  <input type="checkbox" [(ngModel)]="widget.resizable" value="true"> Resizable
              </label>
              <button (click)="setWidth(widget, widget.w+1, $event, gridster1)">width +</button>
              <button (click)="setWidth(widget, widget.w-1, $event, gridster1)">width -</button>
              <button (click)="setHeight(widget, widget.h+1, $event, gridster1)">height +</button>
              <button (click)="setHeight(widget, widget.h-1, $event, gridster1)">height -</button>
          </p>
          <p>
              <button (click)="remove($event, indx,gridster1)">remove</button>
          </p>

          <pre>{{ widget | json }}</pre>

      </div>

  </ngx-gridster-item>

I removed it and added my component:

So in the dashboard (component where the grid will be) html, I have the following:

<ngx-gridster [options]="gridsterOptions" [draggableOptions]="gridsterDraggableOptions" (reflow)="onReflow($event)" (optionsChange)="optionsChange($event)" #gridster1 class="dashboard">

<ngx-gridster-item *ngFor="let widget of widgets; let indx = index" #itemComp
                  [options]="itemOptions"
                  [dragAndDrop]="widget.dragAndDrop" [resizable]="widget.resizable"
                  [(x)]="widget.x" [(y)]="widget.y"
                  [(xSm)]="widget.xSm" [(ySm)]="widget.ySm"
                  [(xMd)]="widget.xMd" [(yMd)]="widget.yMd"
                  [(xLg)]="widget.xLg" [(yLg)]="widget.yLg"
                  [(xXl)]="widget.xXl" [(yXl)]="widget.yXl"
                  [(w)]="widget.w" [(h)]="widget.h"
                  [(wSm)]="widget.wSm" [(hSm)]="widget.hSm"
                  [(wMd)]="widget.wMd" [(hMd)]="widget.hMd"
                  [(wLg)]="widget.wLg" [(hLg)]="widget.hLg"
                  [(wXl)]="widget.wXl" [(hXl)]="widget.hXl"
                  (change)="itemChange($event, gridster1)">
  <app-myComponent  headerCssClassEnablingDraggableName="panel-heading" *ngIf="indx==0"></app-myComponent> 

Within myComponent I have the following @input : @Input() headerCssClassEnablingDraggableName: string;

And the CSS in the MyComponent has the dashboard css imported. @import "../dashboard.component.css";

because I need all components to implement the following class in the dashbaord css:

.panel-heading { border-bottom: 1px solid #F0F0F0; display: inline-block; position: relative; width: 100%; top: 0; }

Now my component is shown as a gridster item and I can resize it, and drag it. Only issues is that I have to make sure the content of my component scales well with the resizing.

Other than that I dont see any issue. But in case you guys see a mistake here or problems the way I have done it may bring later on please lemme know!

swiety85 commented 5 years ago

If you want that card-header will be the drag handler then just set gridsterDraggableOptions. handlerClass to card-header.

C-odes commented 5 years ago

@swiety85 In order for it to see that has a css class "card-header" I still need to implement @input as shown tho. No? Otherwise do you see anything else that should be done better?