I am trying to create a generic component in my project which uses the NgPrime Carousel bases (such as indicators, navigators, etc) and only has to modify the HTML content of the items from my parent component.
Stackblitz Demo Code From PrimeNG
I don't know if what I'm trying to do is possible but I'm looking to try to do it since the generic component I'm creating has several common methods and css styles that will be repeated every time a carousel must be created
Code example of what I'm trying to do
// CustomCarouselComponent.ts
#Input() products
#Input() responsiveOptions
<!-- CustomCarouselComponent.html -->
<p-carousel [value]="products" [numVisible]="3" [numScroll]="3" [responsiveOptions]="responsiveOptions">
<ng-content ></ng-content>
</p-carousel>
//ParentComponent.ts
products = [
{
"id": "1000",
"code": "f230fh0g3",
"name": "Bamboo Watch",
"description": "Product Description",
"image": "https://cdn.pixabay.com/photo/2017/05/09/03/46/alberta-2297204__340.jpg",
"price": 65,
"category": "Accessories",
"quantity": 24,
"inventoryStatus": "INSTOCK",
"rating": 5
},
{
"id": "1001",
"code": "nvklal433",
"name": "Black Watch",
"description": "Product Description",
"image": "https://cdn.pixabay.com/photo/2017/05/09/03/46/alberta-2297204__340.jpg",
"price": 72,
"category": "Accessories",
"quantity": 61,
"inventoryStatus": "INSTOCK",
"rating": 4
}
]
responsiveOptions = [
{
breakpoint: '1024px',
numVisible: 3,
numScroll: 3
},
{
breakpoint: '768px',
numVisible: 2,
numScroll: 2
},
{
breakpoint: '560px',
numVisible: 1,
numScroll: 1
}
];
<!-- ParentComponent.html -->
<custom-carousel [products]="products" [responsiveOptions]="responsiveOptions">
<ng-template let-product pTemplate="item">
<div class="product-item">
<div class="product-item-content">
<div class="p-mb-3">
</div>
<div>
<h4 class="p-mb-1">{{product.name}}</h4>
<h6 class="p-mt-0 p-mb-3">${{product.price}}</h6>
<span [class]="'product-badge status-'+product.inventoryStatus.toLowerCase()">{{product.inventoryStatus}}</span>
</div>
</div>
</div>
</ng-template>
</custom-carousel>
Related
I'm having a trouble grouping my objects, I'm trying to use the ngx-group-by pipe but it doesn't seem to solve my problem.
Assuming the data structure is :
Every company has it products (which contains sub products), and it prices;
For example our company is XXX and it sales cars and motorcycles:
Products : TwoWheels , FourWheels
SubProducts : Bike,Motorcycle (TwoWheels) , Cars (FourWheels)
I'm trying to display the price for every SubProduct and group it by the ProductId
Here's my Json:
{
"id": 1,
"firstName": "test",
"lastName": "tast",
"displayName": "myname",
"profilePic": "none",
"location": "mylocation",
"pricingList": [
{
"id": 1,
"userId": 1,
"ProductId": 1,
"subProductId": 1,
"price": 50,
"subProduct": {
"id": 1,
"ProductId": 1,
"name": "MotorCycle",
"treatment": {
"id": 1,
"name": "TwoWheels"
}
},
"Product": {
"id": 1,
"name": "TwoWheels"
}
},
{
"id": 2,
"userId": 1,
"ProductId": 1,
"subTreatmentId": 7,
"price": 50,
"subProduct": {
"id": 7,
"ProductId": 1,
"name": "bike",
"Product": {
"id": 1,
"name": "TwoWheels"
}
},
"Product": {
"id": 1,
"name": "TwoWheels"
}
},
{
"id": 3,
"userId": 1,
"ProductId": 2,
"subTreatmentId": 8,
"price": 30,
"subProduct": {
"id": 8,
"treatmentId": 2,
"name": "Car",
"Product": {
"id": 2,
"name": "FourWheels"
}
},
"Product": {
"id": 2,
"name": "FourWheels"
}
}
]
}
And here's my Ionic 2/Angular html:
<div *ngFor="let p of User.pricingList | groupBy:p.ProductId">
<div class="ProductTitle">{{p.Product.name}}</div>
<div>
<div class="myClass">Name</div>
<div class="myClass">Price</div>
</div>
<div style="myClass2">
<div class="myClass">{{p.subProduct.name}}</div>
<div class="myClass">{{p.price}}</div>
</div>
</div>
GroupByPipe implementation
I have a list with items and have applied filter on those items by value from text box. I want to get new filtered list with parent and its children if parent has at least one filtered item.If doesn't, that parent should not be displayed.
For an example: If I enter "3D" in the text box I don't want to get "Day parts" and "Week parts" listed below as they don't have children anymore after filtering.
<div ng-controller="Ctrl">
<input type="text" data-ng-model="inputValue.name"/>
<ul data-ng-repeat="condition in conditions">
<div data-ng-click="setHeadingStatus(condition)">
<div>
{{condition.name}}
</div>
<li ng-repeat="item in condition.items | filter:inputValue">
<div class="custom-typeahead-list-title">{{item.name}}</div>
<div class="custom-typeahead-list-desc">{{item.description}}</div>
</li>
</div>
</ul>
function Ctrl($scope , $filter){
$scope.countryCode = 1;
$scope.conditions = [
{
"id": 1,
"name": "Experiences",
"expanded": false,
"items": [
{
"id": 1,
"name": "3D"
},
{
"id": 2,
"name": "Imax"
},
{
"id": 3,
"name": "D-Box"
},
{
"id": 4,
"name": "THX"
}
]
},
{
"id": 2,
"name": "Day parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Early Bird"
},
{
"id": 2,
"name": "Matinee"
},
{
"id": 3,
"name": "Last Night"
}
]
},
{
"id": 3,
"name": "Week parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Monday"
},
{
"id": 2,
"name": "Wednesday"
},
{
"id": 3,
"name": "Weekend"
}
]
}
]
}
Here is the example of it
http://jsfiddle.net/KJ3Nx/48/
You can put an ng-show on the div that displays each block, and set the expression to the filtered length;
<div data-ng-show="(condition.items | filter:inputValue).length > 0" data-ng-click="setHeadingStatus(condition)">
Updated fiddle
I have this array sports, json looks like:
[
{
"id": 26,
"name": "LIVE Betting",
"priority": 0,
"leagues": []
},
{
"id": 8,
"name": "NBA",
"priority": 3,
"leagues": [
{
"id": 5932,
"parent": 1000,
"name": "NBA",
"sport": {
"id": 8,
"name": "NBA"
},
"lineType": "G",
"priority": [
1,
3
],
"part": "0"
}
]
},
{
"id": 24,
"name": "College Basketball",
"priority": 4,
"leagues": [
{
"id": 2599,
"parent": 1000,
"name": "NCAA BASKETBALL",
"sport": {
"id": 24,
"name": "College Basketball"
},
"lineType": "G",
"priority": [
0,
4
],
"part": "0"
},
{
"id": 2631,
"parent": 1000,
"name": "NCAA BASKETBALL ADDED GAMES",
"sport": {
"id": 24,
"name": "College Basketball"
},
"lineType": "G",
"priority": [
1,
4
],
"part": "0"
},
...
within that array you can see other array named "leagues": [{...}] which contains an Object, my filter is searching fine through the top array which is sports but once I try to find through the "name" within leagues array then my app shows up a message that the filter is empty.
I just realized that this is happening because I am using the version 1.3.6 of Angular but I am unable to change it until the Ionic people upgrade it to the 1.3.8, I made this Plnkr with the version 1.3.8 and it works properly, but if you change the version on that same Plnkr to the 1.3.6 automatically stop searching through leagues.name and only works with sport.name, and here is a Plnkr with the version 1.3.6, on both Plnkrs try searching Greece, in the first with the version 1.3.8 works, but in the version 1.3.6 just the message no sports to show comes up
<input type="search" ng-model="query">
<div ng-repeat="sport in sportsFilter = (sports | filter:query)">
<!--this array works fine-->
<strong>{{sport.name}}</strong>
</div>
<div ng-repeat="league in sport.leagues">
<!--this one not works at all-->
{{league.name}}
</div>
</div>
I've been trying all the ways already, with a resolve, with different models, etc and actually I just realized that I need a custom filter so I would like you to give me a hand because I do not where to start from with it.
or is there any easier way ?
<div ng-app="myApp">
<div ng-controller="TestController">
<input type="search" placeholder="Search" ng-model="query">
<div role="alert" ng-show="sportfilter.length==0">No sports to show</div>
<div ng-repeat="sport in sportfilter=(sports | filter:matchNameDeep(query))" ng-show="sport.leagues.length">
<div>
<strong>{{sport.name}}</strong>
</div>
<div class="item item-button-right" ng-repeat="league in sport.leagues" on-tap="goToLines(league)">
{{league.name}}
</div>
</div>
</div>
</div>
$scope.matchNameDeep = function(query) {
return function(sport) {
return !query || sport.name.match(new RegExp(query, "ig")) || sport.leagues.some(function(element, index, array) {
return element.name.match(new RegExp(query, "ig"))
});
}
};
see here it working with angular 1.3.6 http://plnkr.co/edit/0w9PYbDsOz0mHBdVldZt?p=preview
You can use https://github.com/marklagendijk/lodash-deep for this type of thing.
I am having an issue with this handlebar-template:
<div id="shifts" style="visibility:hidden">
{{#sites}}
<div>{{name}}</div>
{{#groups}}
<div>{{name}}</div>
<table>
<thead>
<tr>
{{#users}}
<th class='username' data-userID='{{id}}'>{{name}}</th>
{{/users}}
</tr>
</thead>
<tbody>
{{#shifts}}
<tr>
<td>{{time}}</td>
{{#individuals}}
<td class='vuorot_tyhja' id='{{id}}'>{{name}}</td>
{{/individuals}}
</tr>
{{/shifts}}
</tbody>
</table>
{{/groups}}
{{/sites}}
</div>
During testing it seems that the table actually causes the problem. If I add table, tr ,td, th tags (or others) inside the handlebars, it won't generate the output for those. So basically in this case only the #sites and #groups are shown. If I change the layout so that even sites and groups are within the table, then even those don't show up.
So the data is shown without problems if I remove the styling or ie. use div.
The test-data (if needed) is as follows:
var data = {
"sites": [{
"name": "Site",
"groups": [{
"name": "Ryhmä 1",
"users": [{
"name": "Name1",
"id": 1
},{
"name": "Name2",
"id": 2
},{
"name": "Name3",
"id": 3
},{
"name": "Name4",
"id": 4
},{
"name": "Name5",
"id": 5
}],
"vuorot": [{
"time": "Ke 01.01.14",
"individuals": [{
"id": 1,
"name": "aamu"
},{
"id": 2,
"name": "aamu"
},{
"id": 3,
"name": "aamu"
},{
"id": 4,
"name": "aamu"
},{
"id": 5,
"name": "aamu"
},{
"id": 6,
"shift": "aamu"
},{
"id": 13,
"name": "aamu"
}]
}]
}]
}]
};
What am I missing?
Ok. I found the answer from earlier posts: Handlebars does not fill table
So case mostly solved. The problem fits totally the description, so with that I can debug it.
Probably a trivial question for some. I have a view model for my objects that looks like so:
this.Activities = ko.observableArray([
{ "date": "28/11/2012 00:00:00",
"activities": [
{ "company": "BOW",
"description": "Backup Checks",
"length": "60"
},
{ "company": "AMS",
"description": "Data Request",
"length": "135"
},
]},
{ "date": "30/11/2012 00:00:00",
"activities": [
{ "company": "BOW",
"description": "Backup Checks",
"length": "60"
},
{ "company": "SLGT",
"description": "Software Development",
"length": "240"
},
{ "company": "BOW",
"description": "Data Request",
"length": "30"
},
]},
]);
I want to build an accordion which will hide activities arrays and will display dates. Whenever a date is clicked a list of activites matching this date will be presented by expanding appropriate panel below. Now, in the project I don't use Knockout.js for, I just use Id of a general Activity object to link ID attribute of accordion header with a name attribute in accordion body element. I use Model properties in the strongly typed view to achieve that. Since in the Knockout.js I feed a view model with the details of the Activities I have limited control over the structure of Html being created while data-binding. How can I link accordion headers with matching body elements then?
This assumes you are using the bootstrap accordions but should give you a good idea of how to do it with any accordion system.
http://jsfiddle.net/billpull/f8Cbb/1/show/
HTML
<div class="accordion" id="accordion2" data-bind="foreach: {data: Activities, as: 'activity'}">
<!-- ko template: 'accordionTmpl' --><!-- /ko -->
</div>
<script type="text/html" id="accordionTmpl">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" data-bind="text: activity.date, attr: { href: '#' + activity.order}"></a>
</a>
</div>
<div class="accordion-body collapse" data-bind="attr: { id: activity.order}">
<div class="accordion-inner">
<ul data-bind="foreach: {data: activity.activities, as: 'subActivity'}">
<li>
<span data-bind="text: subActivity.company"></span><br>
<span data-bind="text: subActivity.description"></span><br>
<span data-bind="text: subActivity.length"></span>
</li>
</ul>
</div>
</div>
</div>
</script>
Javascript
var ViewModel = function () {
this.Activities = ko.observableArray([
{ "date": "28/11/2012 00:00:00",
"order" : 1,
"activities": [
{ "company": "BOW",
"description": "Backup Checks",
"length": "60"
},
{ "company": "AMS",
"description": "Data Request",
"length": "135"
},
]},
{ "date": "30/11/2012 00:00:00",
"order" : 2,
"activities": [
{ "company": "BOW",
"description": "Backup Checks",
"length": "60"
},
{ "company": "SLGT",
"description": "Software Development",
"length": "240"
},
{ "company": "BOW",
"description": "Data Request",
"length": "30"
},
]},
]);
};
$(function () {
ko.applyBindings(new ViewModel());
});