Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popover close from within the element itself #1682

Closed
jdeblander opened this issue Feb 23, 2017 · 11 comments
Closed

Popover close from within the element itself #1682

jdeblander opened this issue Feb 23, 2017 · 11 comments

Comments

@jdeblander
Copy link

I want to create a popover with a template and within that template a button "close" wich closes this popover.
I have the following code:

<button type="button" class="btn btn-primary" [popover]="options" placement="bottom" container="body">
    TemplateRef binding
</button>

<template #options>
    Just another template
    <div class="popover-footer">
        <button type="button" class="btn btn-default" (click)="options.hide()">Close</button>
    </div>
</template>

This gives me following error:

self.parentView._TemplateRef_6_4.hide is not a function

So I guess the id options isn't on the correct element.
Can someone please explain how I can make this work?

@ruffiem
Copy link

ruffiem commented Feb 24, 2017

You got this error because you are trying to call a method that your component does not know. The binding is on the element that hold the popover directive and the template reference, not the template itself. I'm not sure you can do this with the current version.

@jdeblander
Copy link
Author

So there isn't any option I could add that "close" button to the popover at the moment?

@GuskiS
Copy link

GuskiS commented Feb 25, 2017

Create function for that click event and in component use @ViewChild.

@ruffiem
Copy link

ruffiem commented Feb 26, 2017

@GuskiS to hide a popover properly, you must use the hide function from the component loader class. Again, the binding is the element that hold the popover directive so is the hide function.

In order to have access to the component loader class, the template element needs to hold the popover directive, eg:

<template
  popoverTitle="Template ref content inside"
  popover=""
  #pop="bs-popover">
  Binding popover inside itself
  <button (click)="hide()">Hide</button>
</template>

with

@ViewChild('pop') pop: PopoverDirective;

...

public hide() {
   this.pop._popover.hide();
}

then you do have a access to the component loader API but for some reason you still don't have the component reference which is needed to close the popover as in

// component-loader.class.ts
  public hide(): ComponentLoader<T> {
    if (this._componentRef) {
      this.onBeforeHide.emit(this._componentRef.instance);
      this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._componentRef.hostView));
      this._componentRef = null;

      if (this._contentRef.viewRef) {
        this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._contentRef.viewRef));
        this._contentRef = null;
      }

      this._componentRef = null;
      this.onHidden.emit();
    }
    return this;
  }

@valorkin
Copy link
Member

valorkin commented Mar 1, 2017

should be as simple as

<button type="button" #pop="bs-popover" class="btn btn-primary" [popover]="options" placement="bottom" container="body">
    TemplateRef binding
</button>

<template #options>
    Just another template
    <div class="popover-footer">
        <button type="button" class="btn btn-default" (click)="pop.hide()">Close</button>
    </div>
</template>

@ruffiem
Copy link

ruffiem commented Mar 1, 2017

Funny I didn't try to recall #pop into the template but yeah, that should work 👍

@pgeyman
Copy link

pgeyman commented Mar 16, 2017

@valorkin How can I achieve the same as your example but where the template is defined in another component and passed as a TemplateRef via a service?

<button type="button" class="btn" [ngClass]="actionBarItem.additionalClasses"
        [popover]="actionBarItem.popoverContent" 
        [popoverTitle]="actionBarItem.popoverTitle" placement="bottom">
    {{actionBarItem.text}}
    <span class="caret"></span>
</button>
public popoverContent: TemplateRef<any>;

@hbweb
Copy link

hbweb commented May 11, 2017

@valorkin would it still be possible in your case if the trigger button actually live in anther child component

For example in the main template component, we have a presentational component for the button
<my-button [title]="Open "></my-button> which has this context

<button type="button" #pop="bs-popover" class="btn btn-primary" [popover]="options" placement="bottom" container="body">
    TemplateRef binding
</button>

Since the templateRef #options does not live on the same component so not sure how it can be linked and work together. Thanks

@harunurhan
Copy link
Contributor

harunurhan commented Aug 11, 2017

it should be possible to pass context that is going to used to render the template inside popover as [ngTemplateOutletContext]

I don't know how but the requested thing works versions before 2.0.0-beta.3.

harunurhan added a commit to harunurhan/ngx-bootstrap that referenced this issue Aug 16, 2017
* Fixes valor-software#1682 by adding a new @input for popover directive so that
context can be passed when content is TemplateRef.
valorkin pushed a commit that referenced this issue Aug 21, 2017
* Fixes #1682 by adding a new @input for popover directive so that
context can be passed when content is TemplateRef.
@hajimurtaza
Copy link

should be as simple as

<button type="button" #pop="bs-popover" class="btn btn-primary" [popover]="options" placement="bottom" container="body">
    TemplateRef binding
</button>

<template #options>
    Just another template
    <div class="popover-footer">
        <button type="button" class="btn btn-default" (click)="pop.hide()">Close</button>
    </div>
</template>

I am calling a component within the template , how can i close the popup from within?
navbar.component.html

<li class="d-flex  flex-column ">
<a href="javascript:void(0);" class="chat" id ="chat" aria-label="chat-label" role="button" 
tabindex="0" [popover]="mypopover" placement="bottom" [outsideClick]="false" label="Click">
</a>
</li>
<ng-template #mypopover>
                <app-mycomponent></app-mycomponent>    
            </ng-template>

@Haisamsohail
Copy link

Haisamsohail commented Feb 24, 2021

In Child or app-mycomponent
// HTML
<button type="button" class="btn btn-light" (click)="close_Popover()">Cancel
// TS
@output() onPopoverCancel = new EventEmitter();
close_Popover() {
this.onPopoverCancel.emit();
return false;
}

In Parent Component
// HTML
<a href="javascript:void(0);" class="chat" id ="chat" aria-label="chat-label" role="button"
tabindex="0" #pop="bs-popover" [popover]="mypopover" placement="bottom" [outsideClick]="false" label="Click">

<ng-template #mypopover>
<app-mycomponent (onPopoverCancel)="pop.hide()">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants