valor-software / ngx-bootstrap

Fast and reliable Bootstrap widgets in Angular (supports Ivy engine)
https://valor-software.com/ngx-bootstrap
MIT License
5.53k stars 1.69k forks source link

feat(modal): Implement modal component #29

Closed ryzy closed 8 years ago

ryzy commented 8 years ago

Hi,

The README says Modal (in progress...). Is it true, is sb working on that? Can we share some progress here (in a separate branch presumably)? I'd consider contributing as I need it for my project...

Thanks for providing more info. Marcin

valorkin commented 8 years ago

Hey, approach to modals implementation was more conceptual next week I get back to ng2-bootstrap activity and modal will be component oriented like routing

jgodi commented 8 years ago

Any update on the Modal component?

valorkin commented 8 years ago

in progress, stay tunned

bertvh commented 8 years ago

+1 . No pressure though. Great work on the other components!

I'm currently on the verge of writing a modal component myself. If you're planning to release soon, that would be great to know (than I'll postpone my work a bit) ;)

asafyish commented 8 years ago

+1 That's the only important piece that is missing.

louisscruz commented 8 years ago

+1

koodikindral commented 8 years ago

+1

valorkin commented 8 years ago

Okay! :)

n-lavrenko commented 8 years ago

+1 :)

eoodin commented 8 years ago

+1

AndreyKotofotoff commented 8 years ago

+2 )

otabekgb commented 8 years ago

+1

frankbenoit commented 8 years ago

Perhaps something from here can be used? https://github.com/shlomiassaf/angular2-modal

bertvh commented 8 years ago

I already had a brief look at the code. It's not that easy to understand, especially since the Angular API has changed so much since alpha 26 (and the DomRenderer can't do enough anymore).

I settled for a straightforward component that encapsulates a Modal, which I can show/hide at will. Disadvantage is that I need to insert this component in each template I need it (meaning there are multiple - hidden - dialogs all the time) and I'll probably have issues with the backdrop in some cases. But for now it's very uncomplicated and it works.

I can share the code If you like.

frankbenoit commented 8 years ago

yes, please :-)

bertvh commented 8 years ago

Here you go (very unpolished code):

The component:

import {Component, View, Input, Output, EventEmitter, OnInit} from 'angular2/angular2';

/**
 * Shows a bootstrap modal dialog.
 * Set the body of the dialog by adding content to the modal tag: <modal>content here</modal>.
 */
@Component({
  selector: 'modal'
})
@View({
  templateUrl: './components/modal/modal.html'
})
export class Modal implements OnInit {

  @Input('title') title: string;
  @Input('cancel-label') cancelLabel: string = 'Cancel';
  @Input('positive-label') positiveLabel: string = 'OK';

  /**
   * Fires an event when the modal is closed. The argument indicated how it was closed.
   * @type {EventEmitter<ModalResult>}
   */
  @Output('closed') closeEmitter: EventEmitter<ModalResult> = new EventEmitter<ModalResult>();
  /**
   * Fires an event when the modal is ready with a pointer to the modal.
   * @type {EventEmitter<Modal>}
   */
  @Output('loaded') loadedEmitter: EventEmitter<Modal> = new EventEmitter<Modal>();

  showModal: boolean = false;

  constructor() {
    console.log('showModal = ' + this.showModal);
  }

  onInit() {
    this.loadedEmitter.next(this);
    console.log('modal inited');
  }

  /**
   * Shows the modal. There is no method for hiding. This is done using actions of the modal itself.
   */
  show() {
    this.showModal = true;
  }

  positiveAction() {
    this.showModal = false;
    this.closeEmitter.next({
      action: ModalAction.POSITIVE
    });
    return false;
  }

  cancelAction() {
    console.log('sending close event');
    this.showModal = false;
    this.closeEmitter.next({
      action: ModalAction.CANCEL
    });
    return false;
  }
}

/**
 * The possible reasons a modal has been closed.
 */
export enum ModalAction { POSITIVE, CANCEL }
/**
 * Models the result of closing a modal dialog.
 */
export interface ModalResult {
  action: ModalAction;
}

The template:

<div class="modal-backdrop fade in"
     [style.display]="showModal ? 'block' : 'none'"></div>
<div class="modal"
     tabindex="-1"
     role="dialog"
     style="display: block"
     [style.display]="showModal ? 'block' : 'none'">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <!--
        <button type="button"
                class="close"
                aria-label="Close"
                (click)="cancelAction()">
          <span aria-hidden="true">&times;</span>
        </button>
        -->
        <h4 class="modal-title">
          {{title}}
        </h4>
      </div>
      <div class="modal-body">
        <ng-content></ng-content>
      </div>
      <div class="modal-footer">
        <button type="button"
                class="btn btn-default btn-sm"
                (click)="cancelAction()">
          {{cancelLabel}}
        </button>
        <button type="button"
                class="btn btn-primary btn-sm"
                (click)="positiveAction()">
          {{positiveLabel}}
        </button>
      </div>
    </div>
  </div>
</div>

Use in your own templates:

The trick here is the (loaded) event. This allows the parent component to get a direct reference to the modal.

<modal id="cancelConfirmation"
       [title]="'Are you sure?'"
       [cancel-label]="'cancel'"
       [positive-label]="'OK'"
       (loaded)="cancelConfirmationModalLoaded($event)"
       (closed)="onCancelConfirmation($event)">
  The body of your modal
</modal>
// inside your component:
cancelConfirmationModalLoaded(modal: Modal) {
    this.cancelConfirmationModal = modal; // Here you get a reference to the modal so you can control it programmatically
  }
frankbenoit commented 8 years ago

This seems to work for me. @bertvh thank you!

koodikindral commented 8 years ago

Merge it with main branch :+1:

bertvh commented 8 years ago

@koodikindral Not ready for that. I see a few problems:

But hey, if everyone likes it, I can clean it up and do a pull request. Just need some more supporters ;)

jhiemer commented 8 years ago

+1

valorkin commented 8 years ago

status update: have a working prototype, to represent bs4 logic and classes debugging, planning to land it this week

NathanWalker commented 8 years ago

+1 Very much looking forward to this landing. I'll be able to use ng2-bootstrap in my company's app once it does! :)

zarkosusnjar commented 8 years ago

+1, also, when this lands with a little bit of tweaking I'll stop copy pasting components and actually install a package into a project.

shlomiassaf commented 8 years ago

Hi Guys,

Just found this repo, nice work.

You can take a look at my repo where I implemented a Modal window for bootstrap. It was mentioned here before: https://github.com/shlomiassaf/angular2-modal

I updated it to work with ng2 beta, it also has a working npm package since some developers wanted it... tough I dont think its good 2 have 2 versions...

The main idea is to allow a modal to be any component which makes it completely customizable. Of course, I supply some basic "Modal" components but the user can also add his own.

Personally, in the spirit of web components, I believe a complete solution for bootstrap is not the right approach, rather a set of separate components with a possible 1 light wight package for shared services... if needed, not sure.

This also complies with bootstrap builders where one can select the specific components (CSS/JS) he wants an omit the ones not in use...

valorkin commented 8 years ago

Great, I will check tomorrow! @shlomiassaf

jayhahn commented 8 years ago

Just need this to start using ng2-bootstrap for my company's new project as well! Eagerly waiting for this to be implemented! Thanks

eliezerreis commented 8 years ago

+1 Any news?

zarkosusnjar commented 8 years ago

While we are drooling for this, I can confirm that https://github.com/shlomiassaf/angular2-modal works great so far in my app. It's a little bit hard to wrap your head around it, but it works. Still hoping @valorkin and other will find time to implement it here.

valorkin commented 8 years ago

yeap, actually we almost here I have added several things guys was pushing me too like, systemjs bundles and cdn stuff for plunkr you can see here https://twitter.com/valorkin/status/692037650061115394

dougludlow commented 8 years ago

FWIW, I've got a simple version of a modal available at https://github.com/dougludlow/ng2-bs3-modal. I needed it for a project I was working on.

project707 commented 8 years ago

+1 I'd even love to know which branch this feature is semi-functional in.

hongbo-miao commented 8 years ago

+1

Ovidiu-S commented 8 years ago

+1

bourdeau commented 8 years ago

+1

tlorenzetti commented 8 years ago

+1

louisscruz commented 8 years ago

Any progress?

careLearning commented 8 years ago

+1

iazarny commented 8 years ago

+1

Iverson commented 8 years ago

@bertvh Why we need use loaded event for binding modal? How about local variable binding in template?

<modal #myModal
       [title]="'Are you sure?'"
       [cancel-label]="'cancel'"
       [positive-label]="'OK'"
       (closed)="onCancelConfirmation($event)">
  The body of your modal
</modal>

and then

<button (click)="showModal(myModal)">Show modal</button>
bertvh commented 8 years ago

@Iverson I do like that better. Simply didn't think of that. Still finding my way in Angular 2 ;)

bourdeau commented 8 years ago

I did implement part of @bertvh code, but style.display is pure CSS so no smooth effect on show or close :cry: (except that it works great :+1: )

sqwk commented 8 years ago

+1

johnwheeler commented 8 years ago

+1

cquillen2003 commented 8 years ago

+1

sqwk commented 8 years ago

Is there any code for this component already that could be committed into a separate branch? More than willing to help, but there's no need for multiple people to do the work twice …

nickthakkar commented 8 years ago

@dougludlow ,Its working perfect for the project i am working on !! Thanks a lot!!

Toktik commented 8 years ago

+1

dougludlow commented 8 years ago

@Nick-Thakkar :thumbsup:

WolvenOne27 commented 8 years ago

+1

hhsadiq commented 8 years ago

+1