I have a button that shows up on the right corner when I make the first scroll down move. I want to make my button disappear after I scroll up on the page.
How can I do this?
So far, my typescript function track($event:any){} looks like this:
import { Component } from '#angular/core';
#Component({
host: {'(window:scroll)': 'track($event)'}
})
export class DirectSearchComponent{
showScrollButton:boolean=false;
beginY: any;
constructor() {}
track($event:any) {
console.debug("Scroll Event", $event);
if (this.beginY == undefined || this.beginY != null) {
if (this.beginY > $event.scrollY) {
this.showScrollButton = false;
}
else {
this.showScrollButton = true;
}
}
else {
this.beginY = $event.scrollY;
this.showScrollButton = true;
}
}
}
And my html code for the button looks like this:
<a href="#" class="scrollup">
<button *ngIf="showScrollButton"
type="button" class="btn btn-primary btn-block pull-right"
style="position: fixed; bottom: 10px; right: 51px;
width:3%; overflow:auto;">
<i class="glyphicon glyphicon-chevron-up" ></i>
</button>
</a>
Thanks in advance!
Looks like this.beginY is not being initialized properly.
Import NgOnInit and in the NgOnInit method, set...
this.beginY = document.documentElement.scrollTop || document.body.scrollTop;
This should properly initialize your variable to the initial page scroll value.
Related
i have a navbar and i want to scroll it horizontally. I use "Tab" and "Tabs" from react-bootstrap. I couldn't figure out how to do this. ( I tried to wrap nav with div, but it didn't work because every tab has its own items )
I tried this:
const outsider = document.getElementsByClassName('products-tabs sub-tabs nav nav-tabs');
const distance = 200;
const scrollLft = () => {
outsider.scrollLeft -= 900;
console.log(outsider);
};
<Tab
className="products-tab"
id="products-tab"
eventKey={index}
title={subcategories.categoryName}
key={`${index + 1}_tab`}
>
{subcategories?.subcategories?.length > 1 ? (
<>
<Button onPress={scrollLft} className="brand-arrow-button">
<i className="icon-Arrow_Simple_left" align="left" />
</Button>
<Button
onPress={() => onClickLeft()}
className="brand-arrow-button-right"
>
<i className="icon-Arrow_simple_rightt" align="left" />
</Button>
<div id="menum">
<Tabs
className="products-tabs sub-tabs"
defaultActiveKey="sub-0"
id="menu-subcategories"
onSelect={e => {
const selectedTabIndex = parseInt(e.split('-')[1], 10);
setActiveSubcategory(selectedTabIndex);
}}
>
{subcategories?.subcategories
?.concat(subcategories?.subcategories)
.map((subcategoryItem, subIndex) => (
<Tab
eventKey={'sub-' + subIndex}
title={subcategoryItem?.name}
key={`${subIndex + 1}_subTab`}
>
**Items
</Tab>
))}
</Tabs>
And this is my css:
&.sub-tabs {
border-radius: 15px;
margin-left: -1px;
margin-right: -16px;
padding-bottom: 1px;
margin-top: 10px;
flex: none;
overflow-x: scroll;
white-space: nowrap !important;
When i click to the button, nothing happens.
This is the console output:
enter image description here
In React, you can use the useRef() Hook to get the reference of a component (similar to document.getElementsByClassName()). Then, you can apply horizontal scrolling using element.current.scrollLeft.
Example:
import { useRef } from 'react'
const App = () => {
const scrollElement = useRef(null)
const scrollLeft = () => {
scrollElement.current.scrollLeft = 50
}
return (
<div className = 'App'>
<div className = 'ScrollMenu' ref = {scrollElement}>
<a href = '#home'>Home</a>
<a href = '#news'>News</a>
<a href = '#contact'>Contact</a>
<a href = '#about'>About</a>
</div>
<button onClick = {scrollLeft}>Click me</button>
</div>
)
}
Here is a live example.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-documents',
templateUrl: './documents.component.html',
styleUrls: ['./documents.component.less']
})
export class DocumentsComponent implements OnInit {
pdfSrc: string = '';
pdfZoom:number = 1;
constructor() { }
ngOnInit() {
this.pdfSrc = '/assets/demo.pdf';
}
public zoomIn()
{
this.pdfZoom += 0.25;
}
public zoomOut()
{
if (this.pdfZoom > 1) {
this.pdfZoom -= 0.25;
}
}
}
<div class="m-portlet m-portlet--mobile">
<div class=modal-body align="center">
<span class="input-group-btn">
<button class="btn" name="zoomout" (click)="zoomOut()"><i class="fa fa-search-minus"> </i></button>
<button class="btn" name="zoomin" (click)="zoomIn()"><i class="fa fa-search-plus"> </i></button>
</span>
</div><br>
<div class="m-portlet__body" style="overflow-x:scroll; overflow-y: scroll;max-height:75vh;">
<pdf-viewer [src]="pdfSrc" [render-text]="true" [original-size]="false" [zoom]="pdfZoom" [page]="page"
[show-all]="true" [autoresize]="true" style="display: block;">
</pdf-viewer>
</div>
</div>
<!--<img src="assets/common/images/sampleProfilePics/a.jpg" height="432" width="405" />-->
I created a layout. On that I'm using ng2-pdfviewer package to add pdf documents on layout page,and with that created zoomin and zoom out button,and overflow-x and overflow-y scrollbars.but overflow-y scrollbar only working but overflow-x is not working why because horizontal scroll bar is coming with pdf itself.
So,I want to remove that predifined horizontal scroll bar.
I have created an OverlayPanel like component so there I can put more clicks or something else.
But when I click outside the overlay or in the overlay this does not exit stays always there, it is dissapear only when I click in button what I have writed.
Here is the link of the StackBlitz
I have like this the overlaPanel created.
<div class="dropdown">
<div (click)="toggle()" class="body">
<ng-content select="[body]"></ng-content>
</div>
<div *ngIf="active" class="popup" >
<ng-content select="[popup]"></ng-content>
</div>
</div>
.dropdown {
position: relative;
display: inline-block;
}
.popup {
display: block;
position: absolute;
z-index: 1000;
}
export class OverlaypanelComponent implements OnInit {
active = false;
constructor() {
}
offClickHandler(event: any) {
if (event['.body'] && event['.popup'] === true) {
this.active = false;
}
}
ngOnInit(): void {
}
toggle() {
this.active = !this.active;
}
close() {
this.active = !this.active;
}
}
And this is when I call this component
<app-overlaypanel>
<div body [ngClass]="[getBackgroundColorClass(),clazz]" class="fa fa-pencil-square-o edit-block"></div>
<div class="overlayPopup" popup>
<div class="dropdown-menu-item" (click)="openTechnicalEditDialog({cluster: cluster, type: clazz})">Edit</div>
<div class="dropdown-menu-item" (click)="delete()">Delete</div>
<div class="dropdown-menu-item" (click)="openTechnicalEditDialog({appendToParentId: cluster.id})" *ngIf="cluster.level <= 9">Append</div>
<div
class="dropdown-menu-item" (click)="clicked.emit()">Assign</div>
</div>
</app-overlaypanel>
If you want to close the drop down when you click outside of your menu you can use host listener to know whether you clicked outside or not
#HostListener('document:click', ['$event']) clickedOutside($event){
this.active=false;
}
I have attached the example check this out: https://stackblitz.com/edit/angular-5p5d1b
You can use ng-click-outside module as described here https://www.npmjs.com/package/ng-click-outside
working with me fine in angular 8
I know the question says Angular 4 but incase if someone is wondering how can we do the same with latest version of angular.
Now Anglar Material overlay comes with such directive and event listener.
<ng-template
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="trigger"
[cdkConnectedOverlayOpen]="isOpen"
[cdkConnectedOverlayHasBackdrop]="isOpen"
[cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop-cs'"
(backdropClick)="isOpen = !isOpen"
>
content to be shown on overlay
</ng-template>
Let's assume that I have Angular 5 project with routings. For instance /home, /landing-page, etc. Moreover, let's assume that in my landing page with url - localhost:4200. I want to create login panel. I have two fields - username and password, one button sign in and two other buttons forgot password? and Don't have an account?. My problem is that when user will click Forgot password? or Don't have an account? he will not be routed to another page with url like localhost:4200/sign-up but he will stay at the same page with url localhost:4200 and fields username, password, sign in, forgot password? and Don't have an account? will disappear and in their place will be displayed fields associated with registration. I am not sure whether you know what I mean. The good example what I wanna to achieve is https://www.instagram.com. No matter whether you click Sign up or Log in you are still on the same url and only one component changes. Do you know how can I achieve this? I am not sure whether I should use routes or maybe another way is more optimal to do this? Thanks in advance.
My code looks in this way. I added only the most important code from selected files.
index.html:
</head>
<body>
<app-root></app-root>
</body>
</html>
app.component.html:
<app-navbar></app-navbar>
<router-outlet></router-outlet>
<app-footer *ngIf="removeFooter()"></app-footer>
At the moment my home.component looks in this way:
home.component.html:
<div *ngIf="isSignIn()">
<app-sign-in></app-sign-in>
</div>
<div *ngIf="isSignUp()">
<app-sign-up></app-sign-up>
</div>
<div *ngIf="isForgotPassword()">
<app-forgot-password></app-forgot-password>
</div>
home.component.ts:
constructor() {
this.signin = true;
this.signup = false;
this.forgot = false;
}
isSignUp() {
if (this.signup === true) {
return true;
}
else {
return false;
}
}
isSignIn() {
if (this.signin === true) {
return true;
}
else {
return false;
}
}
isForgotPassword() {
if (this.forgot === true) {
return true;
}
else {
return false;
}
}
sign-in.component.html:
<div class="content-center">
<div class="container">
<div class="title-brand">
<div align="center">
<input style="background-color: black; border-color: white; color:white; width: 270px" type="text" value="" class="form-control" placeholder="USERNAME">
<br>
<input style="background-color: black; border-color: white; color:white; width: 270px" type="text" value="" class="form-control" placeholder="PASSWORD">
<div class="row">
<div class="col-md-8">
<br>
<button style="background-color: black; border-color: white; color:white; width: 270px" type="button" class="btn btn-danger">Log in</button>
</div>
</div>
<br>
<h6 style = "color: white" [routerLink]="['/main']" skipLocationChange class=pointer>Forgot Password?</h6>
<h6 style="color: white" [routerLink]="['/sign-up']" class=pointer>Don't have an account?</h6>
</div>
</div>
</div>
</div>
UPDATE
I added source code of sign-in.component.html to the question. Can you show me how I can switch the component sign-in.component.html after clicking Forgot Password? or Do not have an account? to the component forgot.component.html or sign-up.component.html
Use skipLocationChange from the route NavigationExtras. E.g.
<h6 style = "color: white" [routerLink]="['/main']" skipLocationChange>Forgot Password?</h6>
<h6 style="color: white" [routerLink]="['/sign-up']" skipLocationChange>Don't have an account?</h6>
Here is an example of using a boolean and buttons to allow you to switch between different components on a single page:
stackblitz example
This example could be improved but I hope it shows you how to easily swap the visible component.
You can view the code at this link
EDIT
You need to remove the responsibility of what component to show to a container component (i.e. a parent component). In the updated stackblitz example I've made the HomeComponent responsible for showing the correct component. This means the SignUp/SignIn/ForgotPassword components have no responsibility for switching between each other - that is the job for the HomeComponent (or whichever component you want to use for that job).
Hope that helps
home.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-home',
template:
`<div *ngIf="signin">
<app-sign-in></app-sign-in>
<button (click)="showSignUp()">Sign up</button>
<button (click)="showForgot()">Forgot password</button>
</div>
<div *ngIf="signup">
<app-sign-up></app-sign-up>
<button (click)="showSignIn()">Sign in</button>
<button (click)="showForgot()">Forgot password</button>
</div>
<div *ngIf="forgot">
<app-forgot-password></app-forgot-password>
<button (click)="showSignUp()">Sign up</button>
<button (click)="showSignIn()">Sign in</button>
</div>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HomeComponent {
public signup: boolean = true;
public signin: boolean = false;
public forgot: boolean = false;
constructor() {}
public showSignIn() {
this.signin = true;
this.signup = this.forgot = false;
}
public showSignUp() {
this.signup = true;
this.signin = this.forgot = false;
}
public showForgot() {
this.forgot = true;
this.signin = this.signup = false;
}
}
I am trying to get something like x-editable inline edit in reactjs. I am able to get the HTML form/control inside the bootstrap tooltip, however, not able to set or change value on the input control on the popover. Below is the code.
class Inline extends React.Component {
constructor(props, context) {
super(props, context);
this.state= {
displayText: props.displayText,
valueText : props.valueText
}
}
componentDidMount() {
$("[data-toggle=popover]").popover({
html: true,
content: function() {
return $('#popover-content').html();
}
});
$(document).on("click", ".popover .close" , function(){
$(this).parents(".popover").popover('hide');
});
}
onChange(e) {
console.log('on change : ' + e.target.value)
this.setState({ displayText: e.target.value });
}
handleClick (e) {
e.preventDefault();
console.log('The link was clicked.');
}
render(){
return (
<div className="container">
<ul className="list-unstyled inline-edit">
<li><a data-placement="bottom" data-toggle="popover" data-title="Inline Edit <a href='#' class='close' data-dismiss='alert'>×</a>" data-container="body" type="button" data-html="true" href="#" >{this.state.displayText}</a></li>
<div id="popover-content" className="hide">
<div className="form-group">
<span>{this.state.displayText}</span>
<input type="text" placeholder="Name" className="form-control"
value={this.state.displayText}
onChange={this.onChange}
></input>
<div className="form-group edit-control">
<a href="#" role="button" onClick={this.handleClick}><i className="fa fa-check-circle fa-2x green"/></a>
<a href="#" role="button" ><i className="fa fa-times-circle fa-2x red leftpad"/></a>
</div>
</div>
</div>
</ul>
</div>
);
}
};
Inline.propTypes = {
displayText: PropTypes.string.isRequired,
valueText: PropTypes.string.isRequired
};
export default Inline;
Screen shot
The issue is in the way your popover is created:
componentDidMount() {
$("[data-toggle=popover]").popover({
html: true,
content: function () {
return $('#popover-content').html();
}
});
}
You are using jquery html() function to duplicate a Html DOM element in the bootstrap popover. When duplicating an html element this way, the JavaScript React logic is not attached to the duplicated html code.
You can't only use the bootstrap tool tip to created the popover. You have to:
Either manually instantiate a react component in the popover (using the ReactDom render function).
Or (the better solution I think) use the dedicated react bootstrap lib that provide the popover bootstrapreact component