When I click a row of object, I want it to be pushed into the selectedProducts array.
I have this in my typescript
selectedProducts: Product[] = [];
select(prod) {
this.selectedProducts.push(prod);
console.log(this.selectedProducts);
}
but it only gets the first object I click in the user's side
Below is my HTML
<div class="list-content fluid">
<div class="products-cards" *ngFor="let product of dataSource['docs']">
<app-product-card [product]="product" (click)="select(product)"></app-product-card>
</div>
</div>
I suggest to try this :
<div class="list-content fluid">
<div class="products-cards" *ngFor="let product of dataSource['docs']" (click)="select(product)">
<app-product-card [product]="product"></app-product-card>
</div>
</div>
Related
I'm following this tutorial and I'm stuck in this feature where I have to display a filtered array (object coming from firebase) when clicking an anchor. I followed all the implementation steps but I'm missing something...The code:
HTML:
<div class="row">
<div class="col-3">
<div class="list-group">
<a
*ngFor="let c of categories$ | async"
routerLink="/"
[queryParams]="{category: c.$key}"
class="list-group-item list-group-item-action"
[class.active]="category===c.$key">
{{c.name}}
</a>
</div>
</div>
<div class="col">
<div class="row">
<ng-container *ngFor="let p of filteredProducts; let i =index">
<div class="col">
<div class="card" style="width: 15rem;">
<img src="{{p.imageURL}}">
<div class="card-body">
<h5 class="card-title">{{p.title}}</h5>
<p class="card-text">{{p.price | currency: 'EUR': true}}</p>
Add to cart
</div>
</div>
</div>
<div></div>
</ng-container>
</div>
</div>
</div>
TS class:
products:Product[]=[];
filteredProducts: Product[]=[];
category: string;
categories$;
constructor(
private productService: ProductService,
private categoryService: CategoryService,
private route: ActivatedRoute) {
this.categories$=this.categoryService.getCategories();
this.productService.getAll().subscribe(products =>this.products=products)
this.route.queryParamMap.subscribe(params =>{
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p=>p.category===this.category) :
this.products;
});
}
The service retrives data correcly, but when I log the filtered array, I get nothing...Can someone give me a hand?
EDIT:
your attempting to set your array before you retrieve the products. subscribe is an asynchronous operation so it doesn't execute in the order it's started, but rather in the order the results arrive, and queryParams is a type of observable that emits immediately, so that subscribe is executing BEFORE the products arrive, instead, use observable combineLatest and the map operator and the async pipe:
filteredProducts$: Observable<Product[]>;
....
const category$ = this.route.queryParamMap.pipe(map(params => params.get('category')));
this.filteredProducts$ = combineLatest(this.productService.getAll(), // combine the streams
category$)
.pipe(
tap(([products, category])=> console.log(products, category)), // this is how you log in a stream
map(([products, category]) => // you'll have the latest value from both
(category) ? // run your filter
products.filter(p => p.category.toLowerCase() === category.toLowerCase()) :
products),
tap(filteredProducts => console.log(filteredProducts)) // this is how you log in a stream
);
then in your template just use the async pipe like you did with categories$
<ng-container *ngFor="let p of filteredProducts$ | async; let i =index">
an Observable is JUST a definition of how to handle a stream of data. logging things outside of that stream will not show you the values inside of that stream. the tap operator exists to allow you to log things inside of the stream
I have a list in which data is filled as such:
<ul ui-sortable="sortableOptions" ng-model="hiringstagelist" class="sortable list">
<li ng-repeat="y in hiringstagelist">
<div class="row">
<div class="col-md-1">
<label class="switch">
<input id="{{y.id}}" class="switch-input" type="checkbox" ng-model="y.isDeleted" ng-click="deletehiringstage(y.id)" />
<span id="data_{{y.id}}" class="switch-label" data-on="" data-off=""></span>
<span class="switch-handle"></span>
</label>
</div>
<div class="col-md-11">
{{y.stageName}}
<span style="float:right;margin-right:10px;"><img src="~/Images/sortarrow.png" /></span>
</div>
</div>
</li>
</ul>
As I'm using angularjs drag and drop hence as soon as I drag and drop any item in the list an event gets triggered which is :
$scope.sortableOptions = {
stop: function (e, ui) {
var model = ui.item.model;
console.log(model);
var index = ui.item.sortable.index;
var draggedModel = ui.item.sortable.model;
var newProdArray = ui.item.sortable.resort.$modelValue;
}
}
With index I only get the old value of the item in the list. "newProdArray" doesn't seems to work. Can i use anything so that i can get a model with new index values along with other parameters od the item like id etc ?
Please guide
I think you want ui.item.sortable.dropindex which gives you the index the item was dropped at. See here for documentation.
I am a beginner at angular. I am pretty certain I am doing this the completely incorrect way but because I finally have it "somewhat working" as it works on the second click I am stuck going in this direction and can't seem to figure out another way to do it.
The filter sorts on the second click because it is initialing as "undefined" before the first click and sets it based on that I believe.
In my html:
<div class="col-xs-12 col-sm-4 location-list" ng-repeat="key in careerlist.location">
<div class="locations" ng-click="careerlist.criteriaMatch()">{{key}}
</div>
</div>
<div class="col-xs-12">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 job-container" ng-repeat="job in careerlist.career | filter : searchText | filter: selectExperience | filter: careerlist.criteria.name">
<h2>
{{job.title}}
</h2>
<h3>
{{job.location}}
</h3>
<div class="job-description" ng-bind-html="job.description | limitHtml : 200">
</div>
<br><br>
<button>Read More</button>
</div>
<br><br>
</div>
</div>
In my controller:
cl.criteriaMatch = function( criteria ) {
jQuery(document).on('click', '.locations', function(){
cl.criteria = {};
console.log("just the element text " + jQuery(this).text());
cl.criteria.name = jQuery(this).text();
return function( criteria ) {
return criteria.name === criteria.name;
};
});
};
Use ng-click instead of jQuery#on('click'). Angular does not know that the filter should be updated.
Update
#Makoto points out that the click is bound twice. It very much looks like you should just remove the jQuery binding altogether. I would even go so far as suggesting removing jQuery from you project.
I have this:
<div class="account-item">
<div class="account-heading" ng-class="active">
<h4 class="account-title">
<a href="#/Messages" onclick="SetActiveAccountHeading(this);">
7. #Translate("SYSTEM_MESSAGES")</a>
</h4>
</div>
</div>
<div class="account-item">
<div class="account-heading" ng-class="active">
<h4 class="account-title">
<a href="#/Info" onclick="SetActiveAccountHeading(this);">
7. #Translate("SYSTEM_INFO")</a>
</h4>
</div>
</div>
In angular i have this:
$scope.active = "active";
but how can i change this on click so if user click on menu once it would be active if again click it would be NOT active?
Ok say you have multiple menu items and you want to toggle the class according to click,
you can create a array in the controller which represents the menu items as,
$scope.menuItems = ['Home', 'Contact', 'About', 'Other'];
assign the default selected ,menu item
$scope.activeMenu = $scope.menuItems[0];
create a function to assign the selected Menu value, this function will assign the $scope.activeMenu a last selected menu item.
$scope.setActive = function(menuItem) {
$scope.activeMenu = menuItem
}
in HTML
loop through the menuItems array and create the menu.
in the ng-class check last clicked menu item is equal to item in the repeat.
if click on the menu then call setActive() function in the controller and pass the menu item name as an argument.
<div class="account-item" ng-repeat='item in menuItems'>
<div class="account-heading" ng-class="{active : activeMenu === item}">
<h4 class="account-title">
{{ item }}
</h4>
</div>
</div>
here is the DEMO
here is a DEMO without ng-repeat
This is what you need.
<div class="account-item" ng-init="active = true">
<div class="account-heading" ng-class="{'active': active === true}" ng-click="active = !active">
<h4 class="account-title">
7. #Translate("SYSTEM_MESSAGES")
</h4>
</div>
</div>
No other scripting. +1 if it helps.
Angular4:
<a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
<a [routerLink]="['calendar']" routerLinkActive="active">
Documentation: https://angular.io/api/router/RouterLinkActive
If you are using [ui-router] you not need to write anything just you have add this ui-sref-active="active-menu" property in your tag which you want to active after click/navigate.
For cleaner code try this:
<div class="account-item" ng-init="active = true">
<div class="account-heading" ng-class="{'active': active}">
<h4 class="account-title">
7. #Translate("SYSTEM_MESSAGES")
</h4>
</div>
</div>
You can remove the onclick event SetActiveAccountHeading(this);.
Here's the JsFiddle link.
You can view the result in the developer's console.
Hope it helps.
I want that the .prerequisites container be shown and populated only when the .popPrereq link(which can become a button) is clicked.
The json data is already available in the main controller and the filter works fine. I just need a way to tell angular to populate the data on click.
Prerequisites
<div class="prerequisites" style="background:pink">
<div class="prerequisite" data-ng-repeat="prerequisite in courses | getPrerequisites:course.CoursePrerequisites">
<p>{ {prerequisite.ProgramCode} } <br> <b>{ {prerequisite.pagetitle} }</b></p>
</div>
</div>
here is my custom filter
coursesSearchApp.filter('getPrerequisites', function(){
return function(prerequisites, ids){
var searchIds = ids.split(',');
var arrayToReturn = [];
for (var i=0; i<prerequisites.length; i++){
if (searchIds.indexOf(prerequisites[i].id) != -1) {
arrayToReturn.push(prerequisites[i]);
}
}
return arrayToReturn;
};
});
Thank you
Add to the popPrereq hyperlink ngClick directive where set show/hide status for prerequisites container to true. And add ngIf directive with this flag value to the prerequisites.
<a href="#" data-ng-show="course.CoursePrerequisites"
data-ng-click="showPrerequisites = true"
class="popPrereq">Prerequisites</a>
<div data-ng-if="showPrerequisites" class="prerequisites" style="background:pink">
<div class="prerequisite" data-ng-repeat="prerequisite in courses | getPrerequisites:course.CoursePrerequisites">
<p>{ {prerequisite.ProgramCode} }
<br> <b>{ {prerequisite.pagetitle} }</b>
</p>
</div>
</div>