ngx-drag-and-drop-lists icon indicating copy to clipboard operation
ngx-drag-and-drop-lists copied to clipboard

placeholder is undefined & missing container styling

Open b0wter opened this issue 6 years ago • 0 comments

I have some trouble getting the nested list example to work. I've copied it from the demo section but whenever I try to run the sample I get the error:

    placeholder is undefined

The error referes to the first line of the following block:

<div [dndList]="{
  allowedTypes: ['item','container']}"
  [dndModel]="dropzone"
  [dndPlaceholder]="placeholder" 
  class="col-md-12">
  <div *ngFor="let item of dropzone">
    <container *ngIf="item.type === 'container'"
      [list]="dropzone"
      [model]="item"></container>
    <div *ngIf="item.type === 'item'"
      [dndType]="item.type"
      [dndDraggable]
      (dndMoved)="removeItem(item, dropzone)"
      [dndObject]="item"
      class="col-md-12">{{item.type}} {{item.id}}</div>
  </div>
</div>

The lists appear empty at first, but when I add a new element (the same way as in the sample, using the "new items" on the left side) the whole lists appear. The lists also appear instantly if I remove the

 [dndPlaceholder]="placeholder"

line. Unfortunately there is also a problem with the styling of the container elements. They (and their children) dont have any styles despite copying from the sample file.

See a picture here: https://ibb.co/mqCnYy

Rest of the code This is the whole code of the container component:

import { Component, OnInit, Input } from '@angular/core';

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'container',
  template: `
  <div class="panel panel-default" [dndType]="model.type"
  [dndDraggable]
  (dndMoved)="removeItem(model, list)"
  [dndObject]="model">
  <div class="panel-heading">
    {{model.type}} {{model.id}}
  </div>
  <div class="panel-body" [dndList]="{
      allowedTypes: ['container','item']}"
      [dndModel]="model.columns"
      [dndPlaceholder]="placeholder">
    <ng-container *ngFor="let item of model.columns">
    <ng-container *ngIf="isArray(item)">
      <ng-container *ngFor="let subItem of item">
      <container *ngIf="subItem.type === 'container'"
      [list]="item"
      [model]="subItem"></container>
      <div *ngIf="subItem.type === 'item'" [dndType]="subItem.type"
      [dndDraggable]="{draggable:true, effectAllowed:'move'}"
      (dndMoved)="removeItem(subItem, item)"
      [dndObject]="subItem" class="col-md-12">{{subItem.type}} {{subItem.id}}</div>
      </ng-container>
    </ng-container>
    <ng-container *ngIf="!isArray(item)">
      <container *ngIf="item.type === 'container'" [list]="model.columns"
        [model]="item"></container>
        <div *ngIf="item.type === 'item'" [dndType]="item.type"
        [dndDraggable]="{draggable:true, effectAllowed:'move'}"
        (dndMoved)="removeItem(item, model.columns)"
        [dndObject]="item" class="col-md-12">{{item.type}} {{item.id}}</div>
        </ng-container>
    </ng-container>
  </div>
</div>
<div class="dndPlaceholder col-md-12" #placeholder></div>
  `
})
export class ContainerComponent implements OnInit {
  @Input() model: { type: string, id: number, columns };
  @Input() list: any[];

  constructor() { }

  ngOnInit() {
  }

  public isArray(object): boolean {
    return Array.isArray(object);
  }

  public removeItem(item: any, list: any[]): void {
    list.splice(list.indexOf(item), 1);
  }
}

And this is the component in which I want to use the container:

<div class="container topContainer">
  <div class="row">
      <div class="col-md-3">
        <div class="panel">
          <div class="panel-heading">
            New Items
          </div>
          <div class="panel-body">
            <li type="button"
              *ngFor="let template of nestedList.templates"
              [dndType]="template.type"
              [dndDraggable]="{effectAllowed:'copy'}"
              [dndObject]="template"
              (dndCopied)="template.id = template.id + 1"
              class="btn btn-default btn-lg col-md-12">
              {{template.type}}
            </li>
          </div>
        </div>
      </div>
      <div class="col-md-9">
        <div class="row">
          <div *ngFor="let dropzone of nestedList.dropzones;let i = index"
            class="col-md-6">
            <div class="dropzone box box-yellow">
              <!-- The dropzone also uses the list template -->
              <h3>Dropzone {{i + 1}}</h3>
              <div [dndList]="{
                allowedTypes: ['item','container']}"
                [dndModel]="dropzone"
                [dndPlaceholder]="placeholder" 
                class="col-md-12">
                <div *ngFor="let item of dropzone">
                  <container *ngIf="item.type === 'container'"
                    [list]="dropzone"
                    [model]="item"></container>
                  <div *ngIf="item.type === 'item'"
                    [dndType]="item.type"
                    [dndDraggable]
                    (dndMoved)="removeItem(item, dropzone)"
                    [dndObject]="item"
                    class="col-md-12">{{item.type}} {{item.id}}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
  </div>
</div>
import { Component, OnInit } from '@angular/core';

import { MessageService } from '../services/message.service';

@Component({
  selector: 'app-mappings',
  templateUrl: './mappings.component.html',
  styleUrls: ['./mappings.component.css']
})
export class MappingsComponent implements OnInit {

  public nestedList = {
    selected: null,
    templates: [
      { type: 'item', id: 2 },
      { type: 'container', id: 1, columns: [[], []] }
    ],
    dropzones: [[
      {
        'type': 'container',
        'id': 1,
        'columns': [
          [
            {
              'type': 'item',
              'id': '1'
            },
            {
              'type': 'item',
              'id': '2'
            }
          ],
          [
            {
              'type': 'item',
              'id': '3'
            }
          ]
        ]
      },
      {
        'type': 'item',
        'id': '4'
      },
      {
        'type': 'item',
        'id': '5'
      },
      {
        'type': 'item',
        'id': '6'
      }
    ],
    [
      {
        'type': 'item',
        'id': 7
      },
      {
        'type': 'item',
        'id': '8'
      },
      {
        'type': 'container',
        'id': '2',
        'columns': [
          [
            {
              'type': 'item',
              'id': '9'
            },
            {
              'type': 'item',
              'id': '10'
            },
            {
              'type': 'item',
              'id': '11'
            }
          ],
          [
            {
              'type': 'item',
              'id': '12'
            },
            {
              'type': 'container',
              'id': '3',
              'columns': [
                [
                  {
                    'type': 'item',
                    'id': '13'
                  }
                ],
                [
                  {
                    'type': 'item',
                    'id': '14'
                  }
                ]
              ]
            },
            {
              'type': 'item',
              'id': '15'
            },
            {
              'type': 'item',
              'id': '16'
            }
          ]
        ]
      },
      {
        'type': 'item',
        'id': 16
      }
    ]]
};

  constructor(private messageService: MessageService) { }

  ngOnInit() {
  }

  public removeItem(item: any, list: any[]): void {
    list.splice(list.indexOf(item), 1);
  }
}

b0wter avatar May 16 '18 19:05 b0wter