is it possible to use cdk virtual scroll in ngbaccordion - accordion

Need to know is it possible to use this new feature #angular/cdk/scrolling in a specific accordion like ng-bootstrap's (in mat-accordion it is https://stackblitz.com/edit/virtual-scroll-expansion-panels?file=app%2Fapp.component.ts)
https://stackblitz.com/edit/angular-ahzm1v?file=app%2Faccordion-basic.ts

Yes, possible a component consisting of the virtual scroll will reside inside the accordion component.
check the demo here
accordian.component.html:
<ngb-accordion #acc="ngbAccordion" >
<ngb-panel [title]="num" *ngFor="let num of numbers">
<ng-template ngbPanelContent>
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute,
non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua
put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore
wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings
<cdk-virtual-scroll> Loading..... </cdk-virtual-scroll>
occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore
sustainable VHS.
</ng-template>
</ngb-panel>
</ngb-accordion>
EDIT:
The stackblitz code above is still relevant. The following CSS makes the accordian inside a virtual scroll.
ngb-accordion {
height: 400px;
display: block;
overflow-y: scroll; }

Related

Display dynamic modal vuetify v-dialog in component Nuxtjs3

I want to open a dynamic modal on v-card onclick, each card clicked will change the content of the v-dialog.
In my case it open once and then nothing happen.
here the view
<template>
<div>
<OrderComment :display="display"/>
<h1 align="center">Commandes à Livrer</h1>
<v-row>
<!-- <Message></Message> -->
<v-col lg="3" sm="6" v-for="order in orders.orders" v-bind:key="order.id" class="mt-16">
<!-- </v-sheet>-->
<v-card #click="displayModal(order.id)">
<v-card-title align="center" class="big-font">
<strong>{{ order.id }}</strong>
</v-card-title>
<v-divider class="mx-4"></v-divider>
<v-card-text>
{{ order.date_upd }}
<!-- <OrderPartialCustomer :id_customer="order.id_customer" /> <br/>-->
<OrderPartialAddress :id_address_delivery="order.id_address_delivery"/>
</v-card-text>
<v-card-actions>
<v-btn #click="changeStatus(order.id)">
Passer en Livre
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</div>
</template>
method in script
const display = ref(false);
function displayModal(id_order: String) {
display.value = true;
console.log(display.value)
}
And my component
<template v-slot:activator="{ on, attrs }">
<div>
<v-dialog
v-model="props.display"
width="500"
>
<v-card>
<v-card-title class="text-h5 grey lighten-2">
Commentaires
</v-card-title>
<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="danger"
text
#click="display = false"
>
Fermer
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
display: {
type: Boolean,
required: true,
},
})
</script>
So finally it works only once. I don't know what is wrong or how i have to achieve it. I even don't know if i have to use v-slot:activator

Remove content from HTML with f:format.html

I want my homepage to have a list of articles, with the first bit of text from each as a preview. Something like:
<div class="article">
<h2>Article Title</h2>
<div class="article-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tortor quam, vulputate at pharetra et, molestie vel nisi. Donec quis tellus pretium, sollicitudin neque et, tristique nunc. Proin id nunc augue. Quisque iaculis iaculis dui, et dictum tortor.</p>
<p>Morbi ligula felis, rhoncus at felis a, egestas scelerisque metus. In sit amet urna nec sem tristique fringilla vel nec sem. Nullam at ante</p>
</div>
<p class="read-more">Read More…</p>
</div>
So, in my fluid template, I had:
<div class="article-text">
<f:format.crop maxCharacters="480" respectHtml="true">
<v:content.render column="0" pageUid="{article.uid}" />
</f:format.crop>
</div>
And as long as the article starts with text, this works fine. But then I had an article which started with some images with captions, like:
<div class="img-grid">
<figure>
<img src="/fileadmin/image1.jpg">
<figcaption>Here's a picture of a thing</figcaption>
</figure>
<figure>
<img src="/fileadmin/image2.jpg">
<figcaption>Here's a picture of another thing</figcaption>
</figure>
</div>
<p>Lorem ipsum, etc., etc...</p>
What I want is to somehow strip out that <div class="img-grid">, to instead show starting with the first bit of regular text from the article. I think the correct way to do this would be with <f:format.html>, but for some reason it isn't working for me. In my fluid template, I have:
<f:format.crop maxCharacters="480" respectHtml="true">
<f:format.html parseFuncTSPath="lib.parseFunc_List">
<v:content.render column="0" pageUid="{article.uid}" />
</f:format.html>
</f:format.crop>
And in my TypoScript setup.txt I have:
lib.parseFunc_List {
externalBlocks {
figure.stdWrap.HTMLparser = 1
figure.stdWrap.HTMLparser {
tags.figure = 0
tags.figcaption = 0
tags.img = 0
removeTags = "figure, figcaption, img"
}
}
}
But it doesn't strip anything out.
How can I parse my HTML, and remove the content I don't want?
If you just remove tags you still have the content, here the image captions.
If you only want the text part you might change the rendering of the CEs so you could more easily identify the text part. you might use a html comment before and after the text part and extract that substring before you use the crop VH.
You also have the option to render your content individually ignoring any / most types. this can be done in typoscript (CONTENT with individual renderObj) or in a PHP VH.

How can I create an Accordion List within ionic 2?

I want to integrate an accordion in my project using expandable groups but for a recent project, I was needing a rendition of an accordion that expanded text or more precisely overflowed content.
Can you tell me how it will done within ionic 2 ?
Check the demo of accordion list within ionic 2 on Github :
https://github.com/mahmoudissmail/ionic2Accordion
.html
<ion-content padding>
<ion-list>
<ion-list-header>
Ionic 2 Accordion Example.
</ion-list-header>
<ion-item padding *ngFor="let d of data" (click)="toggleDetails(d)"><ion-icon color="primary" item-right [name]="d.icon"></ion-icon>
{{d.title}}
<div *ngIf="d.showDetails">{{d.details}}</div>
</ion-item>
</ion-list>
</ion-content>
.ts
export class HomePage {
data: Array<{title: string, details: string, icon: string, showDetails: boolean}> = [];
constructor(public navCtrl: NavController) {
for(let i = 0; i < 10; i++ ){
this.data.push({
title: 'Title '+i,
details: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
icon: 'ios-add-circle-outline',
showDetails: false
});
}
}
toggleDetails(data) {
if (data.showDetails) {
data.showDetails = false;
data.icon = 'ios-add-circle-outline';
} else {
data.showDetails = true;
data.icon = 'ios-remove-circle-outline';
}
}
thanks for #LPeteR90.
EDIT:
Ok, I think I've figured it out. This tutorial helped me a lot, so I would recommend reading it also.
I've split my code up into components, where
#Component({
directives: [DataCards],
templateUrl: 'build/pages/data-list/data-list.html'
})
export class DataList {
public dataList: Data[];
constructor() {
this.dataList = [
new Data('Test title', 'Test Details 1, 2, 3, 4, 5', false),
new Data('Second title', 'These are the details for my second title :)', false)
];
}
}
and the corresponding HTML
<ion-content class="cards-bg">
<data-cards [data]="dataList"></data-cards>
</ion-content>
contain my custom component data-cards. data-cards has an input parameter data, through which the list of data is passed. To be able to use the data-cards component, you need to set the directives attribute. Data is a class containing everything you need in an item of your list.
export class Data {
constructor(public title: string, public details: string, public showDetails: boolean) {}
}
The component data-cards itself has the selector and inputs attributes set, so the component can be used from the data-list HTML. The function toggleDetails is used to toggle whether the detail part of a list entry is shown.
#Component({
selector: 'data-cards',
inputs: ['data'],
templateUrl: 'build/pages/data-cards/data-cards.html'
})
export class DataCards {
public data: Data[];
constructor() {}
toggleDetails(data: Data) {
if (data.showDetails) {
data.showDetails = false;
} else {
data.showDetails = true;
}
}
}
Finally, in the data-cards template file, I build up the list of data using *ngFor and make the details <div> element's visibility dependent on the data showDetails attribute with *ngIf.
<ion-card *ngFor="let d of data">
<h1>{{d.title}}</h1>
<button (click)="toggleDetails(d)">+</button>
<div *ngIf="d.showDetails">{{d.details}}</div>
</ion-card>
To get everything to work you will need to add some imports to my code, since e.g. the DataList class depends on DataCards and Data.
I also recommend changing the style of the data-cards template... Without being styled, it doesn't look beautiful exactly :)
UNEDITED ORIGINAL ANSWER:
I'm working on something similar right now. I think this can be implemented by using cards and *ngIf.
So I think I will do something like
<ion-card>
<h2>Card Title</h2>
<button (click)="toggleDetails()">+</button>
<div *ngIf="showDetails">
Here are some details for the title.
</div>
</ion-card>
In the toggleDetails() i would set the showDetails variable to true...
This is just my approach (and untested), I'm going to edit my answer when I'm done implementing it.

Using Ionic with OMBd API?

I recently started playing with Ionic and I'm trying to pull data from OMDb API. Seems there is some trouble with CORS and I've read the guide at http://blog.ionic.io/handling-cors-issues-in-ionic/, tried adding proxyURL but doesn't seem to work or I'm missing something.
Here's what I'm trying to do:
.controller('MovieController', ['$scope', '$http', function($scope, $http) {
$http.get('http://www.omdbapi.com/?s=Star+Wars').success(function(data) {
$scope.movies = data;
});
}]);
And trying to show the movie data here:
<ion-content ng-controller="MovieController" class="has-subheader">
<ion-list>
<ion-item ng-repeat='item in movies' class="item-left item-text-wrap">
<img src="http://placehold.it/100x150" alt="Photo">
<h2>{{ item.Title }}</h2>
<h3>{{ item.Year }}</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</ion-item>
</ion-list>
</ion-content>
Full code (not much besides this above) here http://play.ionic.io/app/84f6a0092ffe
What am I missing here? Something needs to be changed in my Ionic project or I'm misusing the OMDb API? Thank you very much in advance.
Alright, I got this. Seems that I needed to request the API a bit differently. Here's an updated, working code.
angular.module('app', ['ionic'])
.controller('AppCtrl', function($scope, HttpService) {
HttpService.getPost()
.then(function(response) {
$scope.post = response;
})
})
.service('HttpService', function($http) {
return {
getPost: function() {
return $http.get('http://www.omdbapi.com/?t=Star+Wars')
.then(function (response) {
console.log('Get Post', response);
return response.data;
});
}
}
})
This shows only one item. Remove the ng-repeat in the view.
EDIT: It's weird. Doesn't always fetch from OMDb Api. It says Cross-Origin Request Blocked now.

Detecting select slider change event in jQuery Mobile

What is a reliable way to detect change of a select slider in jQuery Mobile? I try to bind a handler to change event of the select control itself, but it fires on initial page display, and then fires multiple times on clicks, and sometimes even on hover (in desktop browser).
The minimal working example of this behaviour is posted here: http://jsfiddle.net/NPC42/mTjtt/3/
This is probably caused by jQuery Mobile adding more elements to style the select as the flip-toggle, but I can't find the recommended way to do it.
Any help is much appreciated.
May not be the slickest solution but it works
http://jsfiddle.net/mTjtt/4/
Live Example:
http://jsfiddle.net/KCQ4Z/14/
http://jsfiddle.net/phillpafford/KCQ4Z/70/ (using stopPropagation() )
JS:
$('#my-slider').change(function(event) {
event.stopPropagation();
var myswitch = $(this);
var show = myswitch[0].selectedIndex == 1 ? true:false;
if(show) {
$('#show-me').fadeIn('slow');
$('#first-me').fadeOut();
} else {
$('#first-me').fadeIn('slow');
$('#show-me').fadeOut();
}
});
HTML:
<div data-role="page" id="home" class="type-home">
<div data-role="content">
<div class="content-primary">
<p>The flip toggle switch is displayed like this:</p>
<div data-role="fieldcontain">
<label for="slider">Flip switch:</label>
<select name="slider" id="my-slider" data-role="slider">
<option value="off">Off</option>
<option value="on">On</option>
</select>
</div>
<div id="first-me">
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
</div>
<div id="show-me" class="hidden">
<p>
Bacon ipsum dolor sit amet bresaola velit laboris bacon eiusmod. Id ex short ribs, dolor dolore rump pork belly beef ad ullamco salami labore aute ut. Jowl et in do, fatback jerky salami reprehenderit irure laboris pork loin commodo qui eu. Chuck tri-tip cupidatat, turkey sunt in anim jerky pork belly exercitation bacon. Eu corned beef qui adipisicing, ground round veniam turkey chicken incididunt deserunt. Proident t-bone chuck, non excepteur biltong elit in anim minim swine short loin magna do. Sint enim nisi, minim nulla tongue ut incididunt ground round.
</p>
</div>
</div>
</div>
</div>
UPDATE:
I have raised an issue/bug with jQM here:
https://github.com/jquery/jquery-mobile/issues/2188
Use this code,
$( ".mySliders" ).slider({
create: function (event, ui) {
$(this).bind('change', function () {
...
...
});
}
});
!Do not put type="range" to your input tags , put type="text" instead.
Since you are calling slider function manually.