Angular 5 - Material Snackbar not work properly - css

SnackBar takes up the complete page height. I don't know what the problem is, see screenshot below.
And here is my code:
agentsmanagement.component.css
button {
margin: 2px;
}
.selected{
background:lightgray;
}
.example-sidenav {
padding: 20px;
}
.example-sidenav-content {
display: flex;
height: 100%;
width: 100%;
align-items: start;
justify-content: center;
}
.btn-list {
margin: 20px;
}
mat-header-cell {
background-color:#B31B1B;
color: white;
}
agentsmanagement.component.html
<standard-page>
<div>
<form>
<div fxLayout="row">
<div fxFlex>
<h1 mat-dialog-title color="primary" fxLayoutAlign="center">
Agent Management
</h1>
</div>
<div fxFlex="25" fxLayoutAlign="start">
<mat-form-field>
<input matInput placeholder="Search">
</mat-form-field>
</div>
</div>
</form>
</div>
<div mat-dialog-content>
<div class="properties">
<div fxFlex fxLayout="row" id="list-property" fxLayoutAlign="center">
<div fxFlex="95" fxLayout="column" fxLayoutAlign="none" class="mat-elevation-z8">
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="{{column.id}}" *ngFor="let column of columnNames">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{column.value}}
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element[column.id]}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="agentInfo"></mat-header-row>
<mat-row *matRowDef="let row; columns: agentInfo;" [ngClass]="{ 'selected': selection.isSelected(row)}"
(click)="selection.toggle(row)"></mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</div>
</div>
<div fxFlex="10" fxLayout="column" fxLayoutAlign="none" class="btn-action">
<div>
<button mat-mini-fab color="primary" class="mat-elevation-z4" (click)="showAddAgent()">
<mat-icon class="icon">add</mat-icon>
</button>
</div>
<div>
<button mat-mini-fab color="primary" class="mat-elevation-z4" (click)="showEditAgent()">
<mat-icon class="icon">create</mat-icon>
</button>
</div>
<div>
<button mat-mini-fab color="accent" class="mat-elevation-z4" (click)="showDeleteAgent()">
<mat-icon class="icon">delete</mat-icon>
</button>
</div>
</div>
</div>
</div>
</standard-page>
agentsmanagement.component.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import {
MatTableDataSource, MatSort,
MatDialog, MatDialogRef,
MatSnackBar, MatPaginator,
Sort
} from '#angular/material';
import { SelectionModel } from '#angular/cdk/collections';
import { PopupAgentComponent } from "../dialogs/popup-agent/popup-agent.component";
#Component({
selector: 'app-agentsmanagement',
templateUrl: './agentsmanagement.component.html',
styleUrls: ['./agentsmanagement.component.css']
})
export class AgentsmanagementComponent implements OnInit {
tableArr: Element[] = [{ Code: 123153325, AgentName: 'Jun Mar', AgentType: 'Individual', Contact: '09324383919', Address: 'Kasambagan, Cebu', Email: 'Jun#gmail.com' },
{ Code: 123153325, AgentName: 'Jay Jay', AgentType: 'Individual', Contact: '09324383919', Address: 'Kasambagan, Cebu', Email: 'Jun#gmail.com' },
{ Code: 123153325, AgentName: 'Paano Mo Nasabi', AgentType: 'Individual', Contact: '09324383919', Address: 'Kasambagan, Cebu', Email: '' },
{ Code: 123153325, AgentName: 'Walang Poreber', AgentType: 'Cooperate', Contact: '09324383919', Address: 'Kasambagan, Cebu', Email: 'Jun#gmail.com' },
{ Code: 123153325, AgentName: 'Polano Decaprio', AgentType: 'Individual', Contact: '09324383919', Address: 'Kasambagan, Cebu', Email: 'Jun#gmail.com' },
{ Code: 123153325, AgentName: 'Pedodido Tak', AgentType: 'Individual', Contact: '09324383919', Address: 'Kasambagan, Cebu', Email: 'Jun#gmail.com' }
];
#ViewChild(MatSort) sort: MatSort;
#ViewChild(MatPaginator) paginator: MatPaginator;
dialogRef: MatDialogRef<PopupAgentComponent>;
data = Object.assign(this.tableArr);
selection = new SelectionModel<Element>(false, null);
agentInfo = [];
dataSource = new MatTableDataSource<Element>(this.tableArr);
columnNames = [{
id: "Code",
value: "Code"
}, {
id: "AgentName",
value: "Agent Name"
},
{
id: "AgentType",
value: "Agent Type"
},
{
id: "Contact",
value: "Contact"
},
{
id: "Address",
value: "Address"
},
{
id: "Email",
value: "Email"
}];
constructor(
public dialog: MatDialog,
public snackBar: MatSnackBar,
) {
}
ngOnInit() {
this.agentInfo = this.columnNames.map(x => x.id);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
}
openSnackBar(message: string, action: string) {
this.snackBar.open(message, action, {
duration: 2000,
});
}
showAddAgent() {
this.dialogRef = this.dialog.open(PopupAgentComponent, {
disableClose: true,
width: '680px',
height: '580px'
});
}
showEditAgent() {
if (this.selection.isEmpty()) {
this.openSnackBar("Please select one Agent to Update", "");
} else
this.dialogRef = this.dialog.open(PopupAgentComponent, {
disableClose: true,
width: '680px',
height: '580px'
});
}
showDeleteAgent() {
if (this.selection.isEmpty()) {
this.openSnackBar("Please select one Agent to Delete", "");
} else {
this.selection.selected.forEach(item => {
let index: number = this.data.findIndex(d => d === item);
this.dataSource.data.splice(index, 1);
this.dataSource = new MatTableDataSource<Element>(this.dataSource.data);
});
this.selection = new SelectionModel<Element>(true, []);
}
}
}
export interface Element {
Code: number,
AgentName: string,
AgentType: string,
Contact: string,
Address: string,
Email: string
}
What is the problem of with my SnackBar?. I've tried to fix it but it didn't work. I've tried to look at the console but it has no error.
I want it to look like the example from the Angular Material documentation:
SnackBar with proper height

Related

Vue.3 does not render Vuetify components when using at tag attribute in transition-group

I want to animate some cards using gsap for the following components in Vue.js 3.
<script setup lang="ts">
import gsap from 'gsap'
import { useTranslate } from '#/#core/composable/useTranslate'
import TimeLineItem from './TimeLineItem.vue'
interface ITimeLine {
icon: string
title: string
description: string
color: string
}
const timeLines = ref<ITimeLine[]>([
{
title: 'PadvishInstall',
description: 'timeline-welcome',
icon: 'material-symbols:looks-one-outline',
color: 'warning',
},
{
title: 'InsertingToken',
description: 'timeline-step1',
icon: 'ic:outline-looks-two',
color: 'error',
},
{
title: 'ContactInfo',
description: 'timeline-step2',
icon: 'ph:number-square-three-bold',
color: 'info',
},
])
const { translate } = useTranslate()
/**
* Functions
*/
const beforeEnter = (el: Element) => {
const he = el as HTMLElement
he.style.opacity = '0'
he.style.transform = 'translateX(100px)'
}
const enter = (el: Element, done: () => void) => {
const he = el as HTMLElement
gsap.to(el, {
opacity: 1,
x: 0,
duration: 0.8,
onComplete: done,
delay: Number((el as HTMLElement).dataset.index) * 0.5,
})
}
</script>
<template>
<VCard class="text-center" variant="text" title="card title">
<VCardText>
<transition-group
align="start"
justify="center"
truncate-line="both"
:density="$vuetify.display.smAndDown ? 'compact' : 'default'"
appears
#before-enter="beforeEnter"
#enter="enter"
tag="v-timeline"
>
<TimeLineItem
v-for="(item, index) in timeLines"
:key="index"
:data-index="index"
:title="translate(item.title)"
:description="translate(item.description)"
:icon="item.icon"
:color="item.color"
/>
</transition-group>
</VCardText>
</VCard>
</template>
TimeLineItem component :
<script setup lang="ts">
interface Props {
icon: string
title: string
description: string
color: string
}
const props = defineProps<Props>()
</script>
<template>
<VTimelineItem size="x-small" fill-dot>
<template #icon>
<div class="v-timeline-avatar-wrapper rounded-circle">
<VAvatar size="small">
<VIcon size="100" :icon="icon" :color="color" />
</VAvatar>
</div>
</template>
<VCard>
<VCardText>
<!-- 👉 Header -->
<div class="d-flex justify-space-between">
<h6 class="text-base font-weight-semibold mb-1 me-3">
{{ title }}
</h6>
</div>
<!-- 👉 Content -->
<p class="mb-1">
{{ description }}
</p>
</VCardText>
</VCard>
</VTimelineItem>
</template>
<style lang="scss" scoped>
.v-timeline-avatar-wrapper {
background-color: rgb(var(--v-theme-background));
}
</style>
For animating each element of v-timeline, I used transition-group and set the value of tag to v-timeline. But, when using transition-group, the Vue does not recognize the 'v-timeline' is a vuetify component and must render a component!.
This is a limitation of transition-group or can be considered as a bug in Vue.3?

Vuedraggable how to swap item between 2 draggable

Hi all, i have a problem in vuedraggable. When i drag "item 2" to "item 3" => I want "item 3" will swap with "item 2".
Please help me.
Assuming you have multiple lists and each list has its own <draggable> element, then you will need to assign a new method handleMove(event) to your <draggable> elements. The event parameter is important because event.draggedContext contains the index of the item that you are trying to move (index) and also the index of the other item which is currently overlapping with your grabbed item (futureIndex). It also contains information from which list is your grabbed item (event.from) and where you want to drop it (event.to). Store these 4 variables somewhere and use them when you are done dragging (function handleDragEnd()).
Inside handleDragEnd() simply swap those 2 items and Vue will update the HTML template.
LIVE DEMO HERE
<template>
<div class="row">
<div class="col-3">
<h3>My LEGO Bionicles</h3>
<draggable
class="list-group"
data-list="list1"
:list="list1"
group="bionicles"
#change="log"
itemKey="id"
:move="handleMoveItem"
#end="handleDragEndItem"
:options="{ animation: 500 }"
>
<template #item="{ element, index }">
<div class="list-group-item" :style="element.style">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="col-3">
<h3>Favourite LEGO Bionicle</h3>
<draggable
class="list-group"
data-list="list2"
:list="list2"
group="bionicles"
#change="log"
itemKey="id"
:move="handleMoveItem"
#end="handleDragEndItem"
:options="{ animation: 500 }"
>
<template #item="{ element, index }">
<div class="list-group-item" :style="element.style">
{{ element.name }}
</div>
</template>
</draggable>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable';
export default {
name: 'two-lists-swap',
display: 'Swapping between 2 lists',
order: 1,
components: {
draggable,
},
data() {
return {
list1: [
{ name: 'TOA Mata Nui', id: 1, style: { background: 'gold' } },
{
name: 'TOA Tahu',
id: 2,
style: { background: 'red', color: 'yellow' },
},
{ name: 'TOA Kopaka', id: 3, style: { background: 'white' } },
{
name: 'TOA Anakin',
id: 4,
style: { background: 'black', color: 'yellow' },
},
],
list2: [
{
name: 'TOA Gali',
id: 5,
style: { background: 'blue', color: 'yellow' },
},
{
name: 'TOA Lewa',
id: 6,
style: { background: 'green', color: 'yellow' },
},
{
name: 'TOA Pohatu',
id: 7,
style: { background: 'brown', color: 'white' },
},
],
};
},
methods: {
handleDragEndItem() {
if (this.originalList === this.futureList) {
this.movingItem = this[this.futureList][this.originalIndex];
this.futureItem = this[this.futureList][this.futureIndex];
if (this.movingItem && this.futureItem) {
let _list = Object.assign([], this[this.futureList]);
_list[this.futureIndex] = this.movingItem;
_list[this.originalIndex] = this.futureItem;
this[this.futureList] = _list;
}
} else {
this.movingItem = this[this.originalList][this.originalIndex];
this.futureItem = this[this.futureList][this.futureIndex];
if (this.movingItem && this.futureItem) {
let _listFrom = Object.assign([], this[this.originalList]);
let _listTo = Object.assign([], this[this.futureList]);
_listTo[this.futureIndex] = this.movingItem;
_listFrom[this.originalIndex] = this.futureItem;
this[this.originalList] = _listFrom;
this[this.futureList] = _listTo;
}
}
document
.querySelectorAll('.list-group-item')
.forEach((el) => (el.style.border = 'none'));
this.$toast.show('dragEnd');
},
handleMoveItem(event) {
document
.querySelectorAll('.list-group-item')
.forEach((el) => (el.style.border = 'none'));
const { index, futureIndex } = event.draggedContext;
this.originalIndex = index;
this.futureIndex = futureIndex;
this.originalList = event.from.getAttribute('data-list');
this.futureList = event.to.getAttribute('data-list');
if (this[this.futureList][this.futureIndex]) {
event.to.children[this.futureIndex].style.border = '2px solid orange';
}
return false; // disable sort
},
},
};
</script>
<style>
.list-group-item {
padding: 5px 10px;
cursor: grab;
}
</style>

Action button not working using vuetify and vuex

Here, I have setup laravel 6 project with vue and vuetify. I am trying to create crud table where I am trying to fetch data from vuex store but for some I am not able to see my action button. I can see my table with data but action coulmn is empty. I have created store folder and inside my store folder I have Store.js file.
Stage.vue
<template>
<div>
<h1 class="text-xs-center info--text mb-2">{{ message }}</h1>
<v-data-table
:headers="headers"
:items="items"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.code }}</td>
<td class="text-xs-right">{{ props.item.name }}</td>
<td class="text-xs-right">{{ props.item.description }}</td>
<td class="justify-center layout px-0">
<v-btn icon class="mx-0" #click="editItem(props.item)">
<v-icon color="teal">edit</v-icon>
</v-btn>
<v-btn icon class="mx-0" #click="deleteItem(props.item)">
<v-icon color="pink">delete</v-icon>
</v-btn>
</td>
</template>
<template slot="no-data">
<v-alert :value="true" color="error" icon="warning">
Sorry, nothing to display here :(
</v-alert>
</template>
</v-data-table>
<v-dialog v-model="dialog" max-width="500px">
<template v-slot:activator="{ on }">
<v-btn color="error" dark class="mb-2" v-on="on">Add New Stage</v-btn>
</template>
<v-card>
<v-card-title>
<span>{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field label="Code" v-model="editedItem.code"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field label="Name" v-model="editedItem.name"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field label="Description" v-model="editedItem.description"></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click.native="close">Cancel</v-btn>
<v-btn color="blue darken-1" text #click.native="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
name: 'Stage',
props: {
},
data: () => ({
dialog: false,
editedIndex: -1,
editedItem: {
code: '',
name: '',
description: ''
},
defaultItem: {
code: '',
name: '',
description: ''
}
}),
computed: {
message () {
return this.$store.getters.getMessage
},
headers () {
return this.$store.getters.getHeaders
},
items () {
return this.$store.getters.getItems
},
formTitle () {
return this.editedIndex === -1 ? 'New Stage' : 'Edit Stage'
}
},
watch: {
dialog (val) {
val || this.close()
}
},
methods: {
editItem (item) {
this.editedIndex = this.items.indexOf(item)
this.editedItem = Object.assign({}, item)
this.dialog = true
},
deleteItem (item) {
const index = this.items.indexOf(item)
confirm('Are you sure you want to delete this item?') && this.$store.commit('deleteItem', index)
// Todo: Make this delete item from store
},
close () {
this.dialog = false
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
}, 300)
},
save () {
if (this.editedIndex > -1) {
Object.assign(this.items[this.editedIndex], this.editedItem)
// TODO: Edit item in the store.
this.$store.commit('updateItem', this.editedItem, this.editedIndex)
} else {
this.$store.commit('newItem', this.editedItem)
}
this.close()
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
msg: 'Vuetify table of Vuex state items.',
headers: [
{
text: 'Code',
align: 'left',
sortable: true,
value: 'code'
},
{ text: 'Name', value: 'name' },
{ text: 'Description', value: 'description' },
{ text: 'Actions', value: 'description', sortable: false }
],
items: [
{
value: 'false',
code: 23,
name: 'dsvdf',
description: 'Le Manns'
},
{
value: 'false',
code: 1,
name: 'ddd',
description: 'Le Manns'
}
]
},
mutations: {
newItem (state, payload) {
state.items.push(payload)
},
deleteItem (state, payload) {
state.items.splice(payload, 1)
},
updateItem (state, payload, index) {
state.items[index] = payload
}
},
actions: {
},
getters: {
getMessage (state) {
return state.msg
},
getHeaders (state) {
return state.headers
},
getItems (state) {
return state.items
}
}
})
In the state.headers property of your store, you have:
{ text: 'Actions', value: 'name', sortable: false }
This should be:
{ text: 'Actions', value: 'action', sortable: false }
The value property has the wrong value. Also, you have not assigned the imported headers and items to the v-data-table element. It should be:
<v-data-table
:headers="headers"
:items="items"
>
<!-- ... the rest of your code ... -->
Here is a working codepen.

How to change the label color of Material-UI <TextField/>

How can I change the color from "email" label and make it the same as the border line?
Here's my code:
import React, { Component } from "react";
import { Icon } from "semantic-ui-react";
import { Divider } from "semantic-ui-react";
import { TextField, Button, Grid } from "#material-ui/core";
import PropTypes from "prop-types";
import classNames from "classnames";
import { withStyles } from "#material-ui/core/styles";
let self;
const styles = theme => ({
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing.unit,
marginRight: theme.spacing.unit,
width: 280
},
cssLabel: {
color: "#d3d3d3"
},
cssOutlinedInput: {
"&:not(hover):not($disabled):not($cssFocused):not($error) $notchedOutline": {
borderColor: "#d3d3d3" //default
},
"&:hover:not($disabled):not($cssFocused):not($error) $notchedOutline": {
borderColor: "#d3d3d3" //hovered #DCDCDC
},
"&$cssFocused $notchedOutline": {
borderColor: "#23A5EB" //focused
}
},
cssInputLabel: {
color: "#d3d3d3"
},
notchedOutline: {},
cssFocused: {},
error: {},
disabled: {}
});
class NewLoginComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loggedIn: false,
user: "",
errorMsg: "",
errorMsgLength: "",
loginErrorMsg: "",
flag: false,
password: "",
hidden: true,
valuePassText: "SHOW"
};
self = this;
}
componentDidMount() {
this._isMounted = true;
if (this.props.password) {
this.setState({ password: this.props.password });
}
}
componentDidUpdate(prevProps) {}
render() {
const { classes } = this.props;
let username = "";
let password = "";
return (
<div className="container-fluid backround">
<div className="container" id="loginform">
<div className="form-group">
<div>
<div className="emailInput">
<TextField
className={classes.textField}
id="email-txt-input"
label="Email"
variant="outlined"
inputRef={node => (username = node)}
InputLabelProps={{
classes: {
root: classes.cssLabel,
focused: classes.cssFocused
}
}}
InputProps={{
classes: {
root: classes.cssOutlinedInput,
focused: classes.cssFocused,
notchedOutline: classes.notchedOutline
},
inputMode: "numeric"
}}
/>
</div>
<div className="passwordInput">
<TextField
className={classes.textField}
id="password-txt-input"
label="Password"
variant="outlined"
inputRef={node => (password = node)}
type={this.state.hidden ? "password" : "text"}
value={this.state.password}
onChange={this.handlePasswordChange}
InputLabelProps={{
classes: {
root: classes.cssLabel,
focused: classes.cssFocused
}
}}
InputProps={{
classes: {
root: classes.cssOutlinedInput,
focused: classes.cssFocused,
notchedOutline: classes.notchedOutline
},
inputMode: "numeric"
}}
/>
</div>
</div>
<div className="form-group form">
<Button
variant="contained"
id="normal-signin-Btn"
type={"submit"}
className={"btn btn-primary loginButton"}
>
LogIn
</Button>
</div>
</div>
</div>
</div>
);
}
}
NewLoginComponent.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(NewLoginComponent);
Below is one way to control the focused color of the input label to be the same as the focused color of the border:
cssLabel: {
color: "#d3d3d3",
"&.Mui-focused": {
color: "#23A5EB"
}
},
You can simply use the InputLabelProps in your TextField component , for exemple :
<TextField InputLabelProps={{style : {color : 'green'} }}></TextField>
Try using this CSS code in your CSS file to change its border color:
.css-1d3z3hw-MuiOutlinedInput-notchedOutline{
color: yellow !important;
border: 2px solid yellow !important;
}
and to change its label you can use the following inline style in your <TextField/> :
InputLabelProps={{style : {color : 'yellow'} }}
This method should work if you still can't change it, You can also try changing its color by inspecting it from the browser.
try this: put in the TextField
sx={{
"& label": {
"&.Mui-focused": {
color: 'your color*'
}
}
}}

How to implement Load More Button in angular 2

I want to add load more button in my project.I want to call an api on load more button and display the result.How i will implement this, in my case i am getting 200 result at a time because i have set limit 200 but i want a load more button in my code so that i can lazy load.i want to call api on button click.
Html
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="margin-20">
</div>
<form [formGroup]="transactionForm" (ngSubmit)="searchTransaction(transactionForm.value)" >
<div class="form-group col-xs-2">
<label>Workshop</label>
<select class="form-control" [(ngModel)]="selectedWorkShop" formControlName="workshops">
<option value="" selected>--select--</option>
<option *ngFor="let workshop of workshops" value= {{workshop.id}}>{{workshop.name}}</option>
</select>
<small *ngIf="!transactionForm.controls.workshops.valid" class="text-danger">Required</small>
</div>
<div class="form-group col-xs-2">
<label>Start Date</label>
<input class="form-control" placeholder="Choose Date" [ngModel]="startDate" formControlName="startDate" (focus)="toggleDatePicker1(true)"
readonly />
<date-picker *ngIf="showTimePicker1" [initDate]="startDate" (onDatePickerCancel)="toggleDatePicker1($event)" (onSelectDate)="setStartDate($event)"></date-picker>
<small *ngIf="!transactionForm.controls.startDate.valid" class="text-danger">Required</small>
</div>
<div class="form-group col-xs-2">
<label>End Date</label>
<input class="form-control" placeholder="Choose Date" [ngModel]="endDate" formControlName="endDate" (focus)="toggleDatePicker2(true)"
readonly />
<date-picker *ngIf="showTimePicker2" [initDate]="endDate" (onDatePickerCancel)="toggleDatePicker2($event)" (onSelectDate)="setEndDate($event)"></date-picker>
<small *ngIf="!transactionForm.controls.endDate.valid" class="text-danger">Required</small>
</div>
<!--<div class="form-group col-xs-2">
<label>From Date</label>
<input class="form-control" placeholder="Choose Date" [ngModel]="date" formControlName="date" (focus)="toggleDatePicker(true)"
readonly />
<date-picker *ngIf="showTimePicker" [initDate]="date" (onDatePickerCancel)="toggleDatePicker($event)" (onSelectDate)="setDate($event)"></date-picker>
</div>-->
<div class="margin-20 col-xs-12">
<button type="submit" class="btn btn-primary" [disabled]="!transactionForm.valid">Search</button>
<img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA=="
/>
</div>
</form>
</div>
</div>
</div>
<br><br>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p *ngIf="isNoresult"><em>No Result Found</em></p>
<table class='table table-hover' *ngIf="transactions">
<thead>
<tr>
<th>User ID</th>
<th>Txn ID</th>
<th>Order Id</th>
<th>Mode</th>
<th>Transaction Type</th>
<th>Amount</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let transaction of transactions ">
<td>{{ transaction.user_id }}</td>
<td>{{ transaction.txn_id }}</td>
<td>{{ transaction.order_id }}</td>
<td>{{ transaction.mode }}</td>
<td>{{ transaction.transaction_type }}</td>
<td>{{ transaction.amount | number : '1.2-2' }}</td>
<td>{{ transaction.date * 1000 | date:'dd-MM-yyyy' }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Component
import { Component, OnInit } from '#angular/core';
import { FormGroup, AbstractControl, FormBuilder, Validators } from '#angular/forms';
import { Router } from '#angular/router';
import{DatePipe} from '#angular/common';
import { AlertService } from '../../../_services/index'
import { TransactionDetailsServices } from './transactionDetails.service';
// import { CustomerFilter, Customer } from '../models/index';
#Component({
selector: 'transactionDetails',
templateUrl: './transactionDetails.html'
})
export class TransactionDetails implements OnInit {
public transactionForm :FormGroup;
public workshops:any="";
public selectedWorkShop="";
public showTimePicker1:boolean;
public showTimePicker2:boolean;
public startDate=new Date();
public endDate=new Date();
public transactions:any;
public loading:boolean;
public isNoresult:boolean;
public offset:number=0;
constructor(
private fb:FormBuilder,
private alertService: AlertService,
private transactionDetailsService: TransactionDetailsServices,
private datePipe:DatePipe
) {
}
public phone: any;
ngOnInit() {
// const phoneRegex = `^[2-9]{2}[0-9]{8}$`;
// this.searchCustomerForm = this.fb.group({
// phone: ['', [Validators.required, Validators.pattern(phoneRegex)]],
// phoneCC: [{value:'',disabled:true}]
// });
// this.orderForm = this.fb.group({
// categories: this.listCategory()
// });
this.transactionForm=this.fb.group({
workshops:[this.listWorkshop(),Validators.required],
startDate:['',Validators.required],
endDate:['',Validators.required]
})
}
listWorkshop() {
this.weDoShoesCMSService.listWorkshop().subscribe(res => {
this.workshops = res;
this.selectedWorkShop="";
console.log(res);
},
err => {
this.alertService.error(err);
});
}
toggleDatePicker1(status: boolean): void {
this.showTimePicker1 = status;
}
toggleDatePicker2(status: boolean): void {
this.showTimePicker2 = status;
}
setStartDate(date: any): void {
this.startDate = date;
console.log(this.startDate);
}
setEndDate(date: any): void {
this.endDate = date;
console.log(this.endDate);
}
searchTransaction(model:any){
this.loading=true;
console.log(model);
model.startDate=this.filterDate(model.startDate);
model.endDate=this.filterDate(model.endDate);
console.log(model.startDate);
console.log(model.endDate);
this.transactionDetailsService.searchTransaction(model).subscribe(res=>{
this.transactions=res;
if(res==null){
this.isNoresult=true;
this.loading=false;
}
else{
this.isNoresult=false;
console.log(res);
this.loading=false;
}
},
error=>{
this.alertService.error(error);
this.loading=false;
});
}
filterDate(date){
return Date.parse(this.datePipe.transform(date, 'yyyy-MM-dd'))/1000;
}
convertDate(date){
return Date.parse(this.datePipe.transform(date,''))
}
}
Service
import {Component} from '#angular/core'
import { Injectable } from '#angular/core';
import { Http, Headers, Response, RequestOptions } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Networks } from '../../networks/wedoshoes.networks';
#Injectable()
export class TransactionDetailsServices{
constructor(private http:Http) {
}
searchTransaction(model:any){
let requestUrl=this.generateUrl(model);
let headers = this.httpHelper(true);
let options = new RequestOptions({ headers: headers });
return this.http.get(requestUrl, options)
.map((response: Response) => response.json())
.catch((error: any) => Observable.throw(error || JSON.parse(error._body)));
}
generateUrl(model:any):any{
let requestUrl=Networks.OMS_BASE_URL+"/workshops/"+model.workshops+"/orders/payments?"+
"start_date="+model.startDate+"&end_date="+model.endDate+"&offset=0&"+"limit=200";
console.log(requestUrl);
return requestUrl;
}
httpHelper(isSecure: boolean) {
let headers = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/json' });
if (isSecure) {
headers.append("Authorization", localStorage.getItem('token'));
headers.append("X-UserID", localStorage.getItem('userId'));
}
return headers;
}
}
LoadMoreElement(){
this.loadResult=true;
console.log(this.loadResult);
this.calculateOffset();
this.findMoreTransaction(this.formOutput);
}
calculateOffset(){
this.offset=this.offset+this.limit;
}
findMoreTransaction(model:any){
this.transactionDetailsService.searchTransaction(model,this.offset,this.limit).subscribe(res=>{
console.log(res);
if(res==null){
this.alertService.success("No Record Found");
this.loading=false;
this.loadResult=false;
}
else{
if(this.transactions==null){
this.transactions=[];
this.loading=false;
}
else{
this.loadResult=false;
}
this.transactions=this.transactions.concat(res);
// this.fillTransaction();
console.log(this.transactions);
}
},
error=>{
this.alertService.error(error);
this.loading=false;
});
}
}

Resources