I would like to show the preview of the selected image busing Angular, as of now if we click all images are selected, can any one suggest me how to show preview of the selected one and if we select another image previously selected image should be unselect and display new image.
public images: Array<object> = [
{
src: 'https://picsum.photos/250/250/?image=110',
description: 'Notte in hotel di lusso',
price: 250
},
{
src: 'https://picsum.photos/250/250/?image=58',
description: 'Escursione alla scoperta degli animali dell\'isola',
price: 160
}
];
HTML:
<div class="image__container" [ngClass]="{ 'selected': selected }">
<img class="image" [src]="item.src">
<div
class="image__description"
(click)="selected = !selected"
>
<div class="image__description--content">
<div class="image__description--price">
{{ item.price }}
</div>
</div>
</div>
Stackblitz
Thanks for the detailed question, You can check the below stackblitz, I needed to just add a parent property that tracks the currently selected row, then emit an event from the child which updates the latest value from the child. Then if the changes do not show up, we can call this.cdr.detectChanges() to trigger change detection manually. Please check the below code and let me know if any questions.
import {
Component,
ChangeDetectionStrategy,
ChangeDetectorRef,
ViewChildren,
QueryList,
} from '#angular/core';
import { GridItemComponent } from '../grid-item/grid-item.component';
#Component({
selector: 'aer-grid',
templateUrl: './grid.component.html',
styleUrls: ['./grid.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GridComponent {
currentlySelected;
#ViewChildren('gridItem') gridItems: QueryList<GridItemComponent>;
public images: Array<object> = [
{
src: 'https://picsum.photos/250/250/?image=110',
description: 'Notte in hotel di lusso',
price: 250,
},
{
src: 'https://picsum.photos/250/250/?image=58',
description: "Escursione alla scoperta degli animali dell'isola",
price: 160,
},
{
src: 'https://picsum.photos/250/250/?image=76',
description: 'Gita in bicicletta',
price: 50,
},
{
src: 'https://picsum.photos/250/250/?image=61',
description: "Visita di una delle cittadine dell'isola",
price: 25,
},
{
src: 'https://picsum.photos/250/250/?image=64',
description: 'Gita in motoscafo',
price: 85,
},
{
src: 'https://picsum.photos/250/250/?image=71',
description: 'Biglietto aereo',
price: 500,
},
{
src: 'https://picsum.photos/250/250/?image=65',
description: 'Cocktail sulla spiaggia',
price: 5,
},
];
constructor(private cdr: ChangeDetectorRef) {}
updateCurrentlySelected(value: number) {
this.currentlySelected = value;
this.cdr.markForCheck();
// not needed below line
// this.gridItems.forEach((item) => item.detectChanges());
}
}
html
<section class="grid-container">
<ng-container *ngFor="let image of images; let index = index">
<aer-grid-item
#gridItem
[item]="image"
[index]="index"
[currentlySelected]="currentlySelected"
(emitChange)="updateCurrentlySelected($event)"
></aer-grid-item>
</ng-container>
</section>
<!-- Preview of the selected image-->
<br />
<br />
<section>
*ngIf="images && images[currentlySelected] && images[currentlySelected].src"
Preview:
<img [src]="images[currentlySelected].src" />
stackblitz
Related
I have ng-select wrapped inside mat-expansion-panel. I would like to be able to increase the height of the dropdown list to go beyond the height of mat-expansion-panel but I cannot get that effect. I have tried to play around with z-index but still not working.
Stackblitz Example here for list of countries
My code:
HTML
<mat-accordion>
<mat-expansion-panel class="shadow">
<mat-expansion-panel-header>
<mat-panel-title>
<b>Location</b>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="location">
Country
<ng-select class="m-t-10" [(ngModel)]="selectedCountry">
<ng-option *ngFor="let country of countries" value="country.value">
<div class="famfamfam-flags {{country?.value.toLowerCase()}}"></div>
{{country?.label}}
</ng-option>
</ng-select>
</div>
<mat-divider></mat-divider>
<div class="location">
Province
<ng-select class="m-t-10" [(ngModel)]="selectedProvince">
<ng-option *ngFor="let province of provinces" value="country.value">
{{province?.label}}
</ng-option>
</ng-select>
</div>
<mat-divider></mat-divider>
<div class="location">
District
<ng-select class="m-t-10" [(ngModel)]="selectedDistrict">
<ng-option *ngFor="let district of districts" value="district.value">
{{district?.label}}
</ng-option>
</ng-select>
</div>
</mat-expansion-panel>
</mat-accordion>
import { Component,ViewEncapsulation} from "#angular/core";
import { CountryListService } from "./../country.service";
#Component({
selector: "app-location",
templateUrl: "./location.component.html",
styleUrls: ["./location.component.css"],
encapsulation: ViewEncapsulation.None,
providers: [CountryListService]
})
export class LocationComponent {
constructor(private countryList: CountryListService) {}
selectedCountry = "Select";
selectedProvince = "Select";
selectedDistrict = "Select";
countries = this.countryList.getCountries();
provinces = [{ label: "province1", value: "province1" }];
districts = [{ label: "Dist1", value: "District1" }];
}
Countries Service
import {Injectable} from '#angular/core';
#Injectable()
export class CountryListService{
constructor(){}
getCountries(){
return CountryListService.COUNTRIES;
}
private static readonly COUNTRIES = [
{value: 'AF', label: 'Afghanistan'},
{value: 'AX', label: 'Ă…land Islands'},
{value: 'AL', label: 'Albania'},
{value: 'DZ', label: 'Algeria'},
{value: 'AS', label: 'American Samoa'},
{value: 'AD', label: 'Andorra'},
{value: 'AO', label: 'Angola'},
{value: 'AI', label: 'Anguilla'},
{value: 'AQ', label: 'Antarctica'},
{value: 'AG', label: 'Antigua and Barbuda'},
{value: 'AR', label: 'Argentina'}
];
}
I'm not sure about what your are trying to do but I think what you are looking for is :
.ng-dropdown-panel {
position: relative !important;
}
To expand the height of the mat-expansion-panel when you display the dropdown list options.
Hello is there a way to set a custom width in my react select button?
I would like it if I can use bootstrap to do that so it can be responsive but if not its okay.
Here is my code:
import Select, { components } from 'react-select';
export default class AccomodationType extends Component {
render() {
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
return(
<div>
<Select
options= {options}
isClearable
isSearchable
name="color"
/>
</div>
)
}
}
I just used bootstrap sizing for it!
Here is what I added:
<Select
className="w-25 p-3"
options= {options}
isClearable
isSearchable
name="color"
/>
I'm sure there's a really simple solution to this but I can't seem to find it, and I haven't found the question asked here already.
I'm trying to align a layout widget (area) so that when another widget is added it appears to the right of the first widget and not below.
I was hoping i could sort this with flexbox and the artistContainer class but it doesn't seem to be possible.
Dev tools and desired outcome
home.html
<section class="bodysect--dark" id="artists">
<h2 class="body__heading">Artists</h2>
<div class="artistContainer">
{{
apos.area(data.page, 'artist', {
widgets: {
artist: {}
}
})
}}
</div>
</section>
Widget.html
<div class="artist">
<div class="artistImage">
{{ apos.singleton(data.widget, 'areaImage', 'apostrophe-images', {
widgets: {
'apostrophe-images': {}
}
}) }}
</div>
<div class="artistName">
{{ apos.singleton(data.widget, 'singletonName', 'apostrophe-rich-text', {
widgets: {
'apostrophe-rich-text': {}
}
}) }}
</div>
<div class="artistBio">
{{ apos.singleton(data.widget, 'singletonBio', 'apostrophe-rich-text', {
widgets: {
'apostrophe-rich-text': {}
}
}) }}
</div>
</div>
widget index.js
module.exports = {
extend: 'apostrophe-widgets',
label: 'Artist',
contextualOnly: true,
addFields: [
{
name: 'artistImage',
type: 'singleton',
label: 'Image Area',
required: true
},
{
name: 'artistName',
type: 'singleton',
label: 'Name Area',
required: true
},
{
name: 'artistBio',
type: 'singleton',
label: 'Bio Area',
required: true
},
]
};
Thanks in advance!
There is nothing preventing you from lining up horizontally, however, to maintain the proper flex contexts, you'll need to apply styles to apostrophe-generated markup instead of just your project level classes. Here is some sample code I just demo'd
.horizontal-area {
.apos-area-widgets, // proper context for logged-in user
.apos-area { // proper context for logged-out user
display: flex;
}
.apos-area-widget-wrapper {
flex-grow: 1;
flex-basis: 0;
}
}
http://g.recordit.co/IlOPYKRUo0.gif
You might want to provide additional UI changes to adjust the horizontal Add Content line within the horizontal area scope.
I'm trying to build a vue.js front-end and the design is calling for 100% width tiles with a dynamic background image that will be passed along the rest of the content to the page. I already have the payload passing to the component that renders each tile, but I need to render the background image for each of the tiles. I also need to mention that the images are actually 3 images for each tile that need to render for each of our 3 breakpoints. So far I was able to pass one image by using :style="'background-image: url(' + backgroundImage + ')'" but this only serves one image per tile. My question is, what would be the best way to pass all 3 images per tile and render them correctly?
I have heard online that I should just use srcset and pass all 3 to an <img> tag, and make that image the background by using CSS, but that just seems unorthodox.
Is there a more elegant way to deal with responsive background images in reusable components in vue.js?
Home Page
<template>
<div class="Home">
<HomePageTile v-for="tile in tiles" :key="tile.title" :tile-title="tile.title" :tile-desc="tile.description" :tile-type="tile.position" :background-image="tile.backgroundImage"/>
</div>
</template>
<script>
import HomePageTile from '#/components/HomePageTile'
import tileImage1 from '#/assets/optimized/image1.jpg'
import tileImage2 from '#/assets/optimized/image2.jpg'
import tileImage3 from '#/assets/optimized/image3.jpg'
import tileImage4 from '#/assets/optimized/image4.jpg'
export default {
name: 'Home',
components: {
HomePageTile: HomePageTile
},
data () {
return {
tiles: [
{
title: 'Title 1',
description: 'Content 1',
position: 'right',
backgroundImage: tileImage1
}, {
title: 'Title 2',
description: 'Content 2',
position: 'right',
backgroundImage: tileImage2
}, {
title: 'Title 3',
description: 'Content 3',
position: 'right',
backgroundImage: tileImage3
}, {
title: 'Title 4',
description: 'Content 4',
position: 'right',
backgroundImage: tileImage4
}
]
}
}
}
</script>
Tile Component
<template>
<div :class="tilePosition(tileType)" :style="'background-image: url(' + backgroundImage + ')'">
<template v-if="tileType">
<div class="home-page-tile--container home-page-tile--container__with-desc">
<h2 class="home-page-tile--container--title">{{ tileTitle }}</h2>
<p class="home-page-tile--container--description">{{ tileDesc }}</p>
</div>
<div class="home-page-tile--call-to-action" v-if="callToAction">
<p class="home-page-tile--call-to-action--text">{{ callToAction.text }}</p>
<Button class="home-page-tile--call-to-action--button" :button-route="callToAction.buttonPath" :button-text="callToAction.buttonText" :button-style="callToAction.buttonStyle" />
</div>
</template>
<template v-else>
<div class="home-page-tile--container">
<h2 class="home-page-tile--container--title">{{ tileTitle }}</h2>
<Button :button-route="buttonPath" :button-text="buttonText" button-style="pill"/>
</div>
</template>
</div>
</template>
<script>
import Button from './Button'
export default {
name: 'HomePageTile',
props: {
tileType: String,
tileTitle: String,
tileDesc: String,
backgroundImage: String,
buttonText: String,
buttonPath: String,
callToAction: Object
},
components: {
Button: Button
},
data () {
return {
tilePosition: function (el) {
if (el) {
return 'home-page-tile home-page-tile__' + el
} else {
return 'home-page-tile'
}
}
}
}
}
</script>
I have a master-detail scenario. I'm using paper-datatable by David Mulder for my user-list. Data is populated through firebase collection
When tapping a row, a paper-dialog pops up with the details of the selected user.
When trying to edit a field, updating at firebase stops after one keystroke.
What am I missing?
<dom-module id="user-list">
<template>
<style>
:host {
#apply(--layout-vertical);
}
#editDialog {
min-width: 500px;
}
</style>
<firebase-collection location="https://<FIREBASE_APP>.firebaseio.com/users" data="{{users}}"></firebase-collection>
<paper-dialog id="editDialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<div>
<paper-input value="{{selectedUser.name}}" label="Name" class="flex"></paper-input>
<paper-input value="{{selectedUser.username}}" label="Username" class="flex"></paper-input>
</div>
<div class="buttons">
<paper-button dialog-confirm autofocus>Ok</paper-button>
</div>
</paper-dialog>
<paper-datatable id="datatable" selected-item="{{selectedUser}}" selectable on-row-tap="_onDetail" data="{{users}}">
<div no-results>
Loading or no more items...
</div>
<paper-datatable-column header="Name" property="name" type="String" sortable style="min-width: 160px"></paper-datatable-column>
<paper-datatable-column header="Username" property="username" type="String" sortable style="min-width: 40px"></paper-datatable-column>
</paper-datatable>
</template>
<script>
Polymer({
is: 'user-list',
behaviors: [
Polymer.NeonAnimatableBehavior
],
properties: {
type: String,
selectedUser: {
type: Object,
notify: true
},
users: {
type: Array,
notify: true
},
animationConfig: {
value: function() {
return {
'entry': {
name: 'fade-in-animation',
node: this
},
'exit': {
name: 'fade-out-animation',
node: this
}
}
}
}
},
_onDetail: function() {
var dialog = document.getElementById('editDialog');
if (dialog) {
dialog.open();
}
}
})
</script>
</dom-module>
It seems firebase-collection isn't currently meant to be used in this way, it's more of a view into a Firebase location with data that's in an array-like structure. Although with the exception that you can add/delete new items but not update existing ones. See https://elements.polymer-project.org/elements/firebase-element?active=firebase-collection.
That said, each item in the collection has a __firebaseKey__ property that you could use to directly update that item in firebase.