2

I have implemented drag and drop feature referring to a youtube tutorial

I have *ngFor which will generate divs from existing roomsFloorZone array, now my objective is to generate divs using style attribute and value received from backend response provided to the same *ngFor, as all the divs from existing roomsFloorZone or from backend response needs to be under same parent div

I have tried with already existing elements present in roomsFloorZone

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


@Component({
  selector: 'floor-zone',
  templateUrl: './floorzone.component.html',
  styleUrls: ['./floorzone.component.scss']
 })

export class FloorZoneComponent{

   urlFloorZoneIn: any;
   roomsFloorZoneIn: any;
   @Input() urlFloorZone;
   @Input() roomsFloorZone;
   @Input() currentBoxFloorZone;


 ngOnChanges(changes: SimpleChanges) {
    if (changes.urlFloorZone && changes.urlFloorZone.currentValue) {
        this.urlFloorZoneIn = changes.urlFloorZone.currentValue;
    }
    if (changes.roomsFloorZone && changes.roomsFloorZone.currentValue) {
        this.roomsFloorZoneIn = changes.roomsFloorZone.currentValue
    }
  }

  dropzone1 = [];

  currentBox?: string = this.currentBoxFloorZone;

  move(box: string, toList: string[]): void {
    box = this.currentBoxFloorZone;
        this.removeBox(box, this.roomsFloorZoneIn);
        this.removeBox(box, this.dropzone1);
        toList.push(box);

   }

   removeBox(item: string, list) { 
        if (list.indexOf(item) !== -1) {
            list.splice(list.indexOf(item), 1);
            }
    }
    }

I have an array existing roomsFloorZoneIn , from which I drag and drop the elements in the below html and the *ngfor works for that

html

  <div id="toget" class="dropzone" [ngStyle]="{'width':'100%','background- 
     image': 'url('+urlFloorZoneIn+')','background-repeat': 'no-repeat',
     'background-position': 'center', 'background-size': '100% 100%', 
     'border':'1px solid black', 'height':'340px'}" appMovableArea 
     appDropzone (drop)="move(currentBox, dropzone1)">

       <div class="box" *ngFor="let box of dropzone1" appDroppable 
         (dragStart)="currentBox = box" appMovable>
        {{ box.dis }}
       </div>

   </div>

My objective is to provide style(transform attribute) and (abc or def) for {{box.dis}} taken from below snippet [I have style and node values handy] to *ngFor for placing the divs

 `<div xmlns="http://www.w3.org/1999/xhtml">
   <!--bindings={
   "ng-reflect-ng-for-of": ""
    }-->

    <div _ngcontent-c5="" appdroppable="" appmovable=""
      class="box draggable movable ng-star-inserted" touch-action="none"
      style="transform: translateX(183.2%) translateY(56%);"> abc 
      <span _ngcontent-c5="">X</span>
     </div>

    <div _ngcontent-c5="" appdroppable="" appmovable=""
      class="box draggable movable ng-star-inserted" touch-action="none"
      style="transform: translateX(183.2%) translateY(56%);"> def 
      <span _ngcontent-c5="">X</span>
    </div>

   </div>`

So this *ngFor for should work for existing elements(roomsFloorZoneIn) as well as I should be able to insert some elements received from backend(using their style attribute and node value) Note: I already have the style and node value handy

Enthu
  • 512
  • 2
  • 13
  • 38
  • I'm not entirely sure what you're asking here. Do you want to apply certain styles to some of the elements in the `*ngFor` loop, and other styles to others? – Will Alexander Aug 10 '19 at 18:00
  • @WillAlexander, no what I meant is there will be some elements in the array called roomsFloorZoneIn from which I'll drag and drop on div with class dropzone and *ngFor will generate the divs for this operation , uptill here everything works fine , now I also receive some elements from backend response from which I'll strip out Style property and value(abc or def) and want to pass it on to same *ngFor for generating new divs(how this can be done), hope now I am clear – Enthu Aug 10 '19 at 18:04
  • OK so I'm afraid it's still not very clear. `*ngFor` works with an iterable and creates one element for each element in said iterable. If you want to pass style or value attributes to the child elements, you need to create `@Input`s on them. Is that what you mean? – Will Alexander Aug 10 '19 at 18:08
  • Yeah but not for elements coming in from roomsFloorZoneIn array (divs for this will be created without any change), I only want the styles and value from the backend response and generate additional new divs apart from the divs generated from roomsFloorZoneIn array. – Enthu Aug 10 '19 at 18:11
  • I still don't really understand the end goal. `*ngFor` accepts only one iterable. If you want to use a new Array (and not add to the current one), you need a new `*ngFor` element. – Will Alexander Aug 10 '19 at 18:14
  • *ngFor will create new divs from roomsFloorZoneIn array + different new divs(using the style and value(abc or def) from the backend response) – Enthu Aug 10 '19 at 18:14
  • ok then what approach should I follow as I want to place both the divs whether coming in from roomsFloorZoneIn array or backend response(containing the style) under the same parent div(class="dropzone" id='toget') – Enthu Aug 10 '19 at 18:16
  • If having one list and then the other works, then you simply add a second `*ngFor`. If not, you need to figure out the logic necessary to create a single array in order to use one single `*ngFor`. – Will Alexander Aug 10 '19 at 18:21
  • Yeah the first option would also work , could you please give an example , as firstly I have to generate divs for backend response , after that only once user starts interaction then I have to generate divs from roomsFloorZoneIn array. – Enthu Aug 10 '19 at 18:25
  • I think you're already describing the solution. Give it a try, thinking from that perspective. If it doesn't work out, maybe close this question and open a new one with the new issue. – Will Alexander Aug 10 '19 at 18:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/197777/discussion-between-enthu-and-will-alexander). – Enthu Aug 10 '19 at 18:27
  • @WillAlexander , the first approach works taking two *ngFor, I haven't tried merging both the arrays for one ngFor , Thanks!, if you can post the solution I can accept else I can also post, as it might help someone. – Enthu Aug 11 '19 at 08:27

1 Answers1

1

If the two lists can come one after the other, you can use two separate <div>'s, both with *ngFor's using the two Arrays:

<div class="myEnclosingDiv">
  <div class="firstList" *ngFor="let element of firstArray">
    {{ element.stuff }}
  </div>
  <div class="secondList" *ngFor="let element of secondArray">
    {{ element.otherStuff }}
  </div>
</div>

On the other hand, if the two lists need to be mixed somehow, you simply create a new Array in your TypeScript code and use a single *ngFor.

Will Alexander
  • 3,425
  • 1
  • 10
  • 17
  • I have a different issue , I have already posted, it would be great if you could suggest https://stackoverflow.com/questions/57449147/to-translatemaintain-the-positions-of-child-divs-wrt-to-the-size-of-the-parent – Enthu Aug 11 '19 at 14:07