Mohammed Housseyn Taleb
Mohammed Housseyn Taleb

Reputation: 1828

How To show a modal dialog in angular, using w3.css as framework?

I have an angular NgFor that is creating a list of elements, I want to show a modal detail dialog about the clicked element, I m using w3.css as css framework, but I m not successfull

I tried to use the NgStyle with some input from parent to child, I strated using angular 4 days ago so I m not yet used to it logic, in the console logs I see that my click is firing but I dont know what is happening after

My code

List Component and Template

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { BreakPointService } from '../../providers/break-point.service';
import { ReactiveTwitterSpringService } from '../../reactive/reactive-twitter-spring.service';
import { ITweet } from '../../reactive/model/itweet';
import { Subscription, Subject } from 'rxjs';

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


    list_div_class;
    search_input_class;

    selectedTweet: ITweet;
    public search_results$ = new Subject<any>();
    search_results: ITweet[] = new Array();
    subscribe: Subscription = new Subscription();
    constructor(private tweetService: ReactiveTwitterSpringService, private cdr: ChangeDetectorRef) { }
    visible = 'none';

    search(tag) {

        this.search_results = new Array();
        this.subscribe.unsubscribe();
        this.subscribe = new Subscription();
        this.search_results$ = new Subject<any>();
        this.subscribe.add(this.tweetService.search(tag).subscribe(tweet => {
            this.search_results.push(tweet);
            this.search_results = this.search_results.slice();
            this.cdr.detectChanges();
            this.search_results$.next(this.search_results);
            console.log(tweet);
        }));
        console.log('array contains ' + this.search_results);

    }



    setSelected(tweet) {
        console.log('selecting and showing');
        this.selectedTweet = tweet;
        this.visible = 'block';
    }


    ngOnInit() {

        BreakPointService.current_css.subscribe(value => {
            console.log('value is ' + value);
            this.setupCss(JSON.parse(value));
        });


    }

    setupCss(value: any): any {
        this.list_div_class = value.list_div_class;
        this.search_input_class = value.search_input_class;
    }
}

template

<div class="{{list_div_class}}" style="max-height: 100vh;">
  <input type="text" class="{{search_input_class}}" (keyup.enter)="search(searchInput.value)" #searchInput>
  <ul class="w3-ul w3-hoverable" style="overflow-x:auto;max-height:70vh;">
    <li class="w3-bar w3-center" *ngFor="let tweet of search_results " (click)="setSelected(tweet)">
      <img src="{{tweet.userImage}}" class="w3-bar-item w3-circle" style="width:100px;">
      <div class="w3-bar-item">
        <span class="w3-large">{{tweet.id.name}}</span>
        <br>
        <span>#{{tweet.tag}}</span>
      </div>

    </li>
  </ul>
  <app-tweet-detail [detail]="selectedTweet" [visible]="visible"></app-tweet-detail>
</div>

My detail component and template

import { Component, OnInit, Input } from '@angular/core';
import { ITweet } from '../../../../reactive/model/itweet';

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


    @Input() detail: ITweet = new ITweet();
    @Input() visible = 'none';

    constructor() { }
    setInvisible() {
        console.log('hidding');
        this.visible = 'none';
    }

    ngOnInit() {
    }

}

template

<div id="modal" class="w3-modal" [ngStyle]="{display: visible}">
  <div class="w3-modal-content">
    <div class="w3-container" *ngIf="detail">
      <span (click)='setInvisible()' class="w3-button w3-display-topright">&times;</span>
      <img src='{{detail.userImage}}' style='width: 250px;' />
      <span class='w3-large'>{{detail.id.name}} {{detail.country}} {{detail.placeFullName}}</span>
      <p>{{detail.id.text}}</p>
    </div>
  </div>
</div>

What should I do?

NB

In the w3.css tutorial they use the get element by id to change the visibility to none or block.

Upvotes: 0

Views: 539

Answers (1)

ivanavitdev
ivanavitdev

Reputation: 2888

I guess what you need to do is have a two variables holding the listOfItems and a selectedItem where you will show on the modal. so for example

Component TS file

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

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

  listOfItems: any[];
  selectedItem: any;

  ngOnInit() {
    this.listOfItems = [
      {
        title: 'Title 1',
        content: 'this is my first item'
      },
      {
        title: 'Title 2',
        content: 'this is my second item'
      }
    ];
  }

  openModal( item ) {
    this.selectedItem = item;
  }

  closeModal() {
    this.selectedItem = undefined;
  }

}

so we have openModal which assigns an item on the selectedItem variable for us to display the specific item and let the modal show, closeModal to revoke the value and make our modal hide again. so implementing this on the html looks like this.

Component HTML

<button *ngFor="let item of listOfItems; let i = index" (click)="openModal(item)" class="w3-button">Open item #{{ i }}</button>

<div *ngIf="selectedItem" class="w3-modal" [style.display]="selectedItem ? 'block' : 'none'">
  <div class="w3-modal-content">
    <div class="w3-container">
      <span (click)="closeModal()" class="w3-button w3-display-topright">&times;</span>
      <h1>{{ selectedItem.title }}</h1>
      <p>{{ selectedItem.content }}</p>
    </div>
  </div>
</div>

So we have a button that loops thru the list of items and pass the item on the function so we could select which item to be shown. Then in the modal we try to check if selectedItem is defined, so if yes then the display will be visible and not otherwise.

Upvotes: 1

Related Questions