toggle only one specific panel within a ngFor loop - javascript

Hello I want to toggle one specific panel but if I click on the button the panels of other objects will be opened. How can I just open the clicked panel?
toggle.component.ts
opened:Boolean=false;
toggle () {
this.opened = !this.opened;
}
HTML
<div class="main" *ngFor="let x of data; let i=index;">
<footer>
<div class="icons">
<span id="{{item.id}}" (click)="toggle()">6<i class="fa fa-users {{i}}" ></i></span>
<span >6<i class="glyphicon glyphicon-picture"></i></span>
<span >6<i class="glyphicon glyphicon-tag"></i></span>
<div class="iconsRight pull-right">
<span >EXIF<i class="glyphicon glyphicon-info-sign"></i></span>
<span ><i class="fa fa-map-marker"></i></span>
<span ><i class="fa fa-share-alt-square"></i></span>
</div>
</div>
</footer>
<div class="togglePanel{{item.id}}" *ngIf="opened" >
<hr/>
<ul class="toggleWrapper">
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
</ul>
</div>
</div>

You need to save state of individual panel. Currently you just set one variable which toggles all the panels.
In your toggle.component.ts, add a variable to store every item's state:
togglePanel: any = {};
Then, change your html to following:
<div class="main" *ngFor="let x of data; let i=index;">
<footer>
<div class="commentAgent">Text des Bewerters, der die Bearbeitung dieses Bildes vorgenommen hat</div>
<div class="icons">
<span id="{{item.id}}" (click)="togglePanel[i] = !togglePanel[i]">6<i class="fa fa-users {{i}}" ></i></span>
<span>6<i class="glyphicon glyphicon-picture"></i></span>
<span>6<i class="glyphicon glyphicon-tag"></i></span>
<div class="iconsRight pull-right">
<span>EXIF<i class="glyphicon glyphicon-info-sign"></i>/span>
<span><i class="fa fa-map-marker"></i></span>
<span><i class="fa fa-share-alt-square"></i></span>
</div>
</div>
</footer>
<div class="togglePanel{{item.id}}" *ngIf="togglePanel[i]">
<hr/>
<ul class="toggleWrapper">
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
</ul>
</div>
</div>
Also, you don't need the toggle() method and the variable opened in this approach.

If you need only one panel opened, then this method will work. Instead on setting your 'flag' property boolean, use number. It will keep the panel id. Set it to the panel id and you don't need an additional property on your data:
Typescript:
opened = -1;
toggle (index) {
this.opened = index;
}
HTML:
....
<span id="{{item.id}}" (click)="toggle(item.id)">6<i class="fa fa-users {{i}}" ></i>
...
<div class="togglePanel{{item.id}}" *ngIf="opened===item.id" >

Related

why nextelementsibling return null | dom traversing js

when I click on title ( Title Goes Here) text. I am getting null for nextElementSibling instead of a element...
Edit
you can nest any elements inside an <a> except the following :
<a>
<button>
follow link
<a> and<button> both are invalid..
but I am getting null for a tag.. not for button tag.... I am looking for more clarity and valid source...
if I console log console.log(document.links) .. it's give three HTMLCollection collection...
End Edit
Below Example Code
console.log(document.links)
document.querySelectorAll(".viewAbstractToggleTitle").forEach(function(item) {
item.addEventListener("click", function(e) {
if (e.target.parentElement.classList.contains('viewAbstractToggleTitle')) {
console.log(e.target.parentElement.nextElementSibling.nextElementSibling)
console.log(e.target.parentElement.nextElementSibling.nextElementSibling.nextElementSibling);
console.log(e.target.parentElement.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling);
}
})
})
<li style="border-bottom: 1px solid #d6d6d6;margin-bottom:10px;">
<a href="javascript:void(0)">
<span class="viewAbstractToggleTitle" style="display:inline-block;line-height:1.6 !important">
<span style="font-weight: 600;font-size:16px;">
Title Goes Here
</span>
<span> ( 1-10 page )</span>
</span>
<br>
<div class="authors">
<span><i class="fa fa-user" aria-hidden="true"></i>
Author
</span>
<span><i class="fa fa-user" aria-hidden="true"></i>
Author
</span>
</div>
<button>
button tag
</button>
<a class="inlineBlock" href="" download>
<i class="fa fa-download" aria-hidden="true"></i> Download PDF</a>
<a class="inlineBlock viewAbstractToggle" href="javascript:void(0)"> <i class="fa fa-eye" aria-hidden="true"></i> View Article</a>
<div class="showTabe sTab">
<div class="tabBox">
<div class="tab">
<label class="label" for="tab1_">Abstract</label>
<label class="label" for="tab2_">Graphical of Author </label>
</div>
<div class="box">
<div class="content"><input id="tab1_"> Description
</div>
<div class="content"><input id="tab2_">
<p>image</p>
</div>
</div>
</div>
</div>
<br>
</a>
</li>
Your HTML is invalid. You have disallowed things like nested hyperlinks. This means the HTML parser, which is designed to be forgiving in spite of errors, has to come up with a new interpretation of your element tree. Here's what Firefox at least translates it to:
<li style="border-bottom: 1px solid #d6d6d6;margin-bottom:10px;">
<a href="javascript:void(0)">
<span class="viewAbstractToggleTitle" style="display:inline-block;line-height:1.6 !important">
<span style="font-weight: 600;font-size:16px;">
Title Goes Here
</span>
<span> ( 1-10 page )</span>
</span>
<br>
<div class="authors">
<span><i class="fa fa-user" aria-hidden="true"></i>
Author
</span>
<span><i class="fa fa-user" aria-hidden="true"></i>
Author
</span>
</div>
<span>
span tag
</span>
</a>
<a class="inlineBlock" href="" download="">
<i class="fa fa-download" aria-hidden="true"></i> Download PDF</a>
<a class="inlineBlock viewAbstractToggle" href="javascript:void(0)"> <i class="fa fa-eye" aria-hidden="true"></i> View Article</a>
<div class="showTabe sTab">
<div class="tabBox">
<div class="tab">
<label class="label" for="tab1_">Abstract</label>
<label class="label" for="tab2_">Graphical of Author </label>
</div>
<div class="box">
<div class="content"><input id="tab1_"> Description
</div>
<div class="content"><input id="tab2_">
<p>image</p>
</div>
</div>
</div>
</div>
<br>
</li>
You can get this information for yourself by copying the HTML from your browser's DOM inspector.
As you can see, the other <a/> elements are not siblings of .viewAbstractToggleTitle. This is because the DOM parser had to insert a closing of your first <a/> element since you cannot nest them.

select the next class with the previous class containing a text I gave

<div class="">
<span>
<div class="ant-upload-list-item ant-upload-list-item-undefined ant-upload-list-item-list-type-text">
<div class="ant-upload-list-item-info">
<span>
<i aria-label="icon: paper-clip" class="anticon anticon-paper-clip">
</i>
<span class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-1" title="fileDoc.doc">fileDoc.doc</span>
<span class="ant-upload-list-item-card-actions ">
<a title="Remove file">
<i aria-label="icon: delete" title="Remove file" tabindex="-1" class="anticon anticon-delete">
...
</i>
</a>
</span>
</span>
</div>
</div>
</span>
</div>
<div class="">
<span>
<div class="ant-upload-list-item ant-upload-list-item-undefined ant-upload-list-item-list-type-text">
<div class="ant-upload-list-item-info">
<span>
<i aria-label="icon: paper-clip" class="anticon anticon-paper-clip">
...
</i>
<span class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-1" title="fileJpeg.jpeg">fileJpeg.jpeg</span>
<span class="ant-upload-list-item-card-actions ">
<a title="Remove file">
<i aria-label="icon: delete" title="Remove file" tabindex="-1" class="anticon anticon-delete">
...
</i>
</a>
</span>
</span>
</div>
</div>
</span>
</div>
This is my case, i want to select the " .ant-upload-list-item-card-actions > a" when the class "ant-upload-list-item-name ant-upload-list-item-name-icon-count-1" contains fileDoc.doc
I made this
candidateUploadFileButton = '#filesUpload';
candidateUploadRemoveButton = '.ant-upload-list-item-card-actions > a';
cy.get(this.candidateUploadFileButton, {force: true}).contains(fileName);
cy.get(this.candidateUploadRemoveButton).click();
It works for a single input only for a single div class, if there two classes like in the previously example , it doesn't work beacuse it says there are multiple values
I added this picture, maybe it will help what i want to do, i want to press Remove button for the file named "fileDoc.doc"
https://i.stack.imgur.com/voQqp.png
Refer here:
As per your markup, you can use this:
cy.contains(fileName).next().find('> a').click()

not able to get the selected tab value to the controller in angular.js

In html A i am calling html B which contain tab as shown is the image. now the "Save " and "Save All" button is in html B i have used css to move to the top but this is not the right way to do. I need "Save" and "Save All" button in html A but for this i need to know which tab is selected.
HTML B
<div id="confi">
<div class="row">
<section widget-grid id="widget-grid">
<div class="col col-md-12">
<div ng-if="currComp" jarvis-widget id="script-widget" data-widget-color="darken" data-widget-colorbutton="false" data-widget-editbutton="false"
data-widget-deletebutton="false">
<header>
<span class="widget-icon">
<i class="fa fa-gear"></i>
</span>
<h2>Script Configuration for {{comp}}</h2>
</header>
<div class="widget-body padding-10">
<ul id="scriptTabs" class="nav nav-tabs bordered">
<li ng-repeat="s in scripts track by $index">
<a id="s{{$index}}tab" href="#s{{$index}}" data-toggle="tab">
<i class="fa fa-fw fa-lg fa-file"></i> {{s}}
<!-- <span class="badge bg-color-blue txt-color-white">6</span> -->
</a>
</li>
</ul>
<!-- style="height:400px;margin-bottom: 30px;" -->
<div id="scriptTabsContent" class="tab-content padding-10">
<div class="tab-pane active" id="s{{$index}}" ng-repeat="s in scripts track by $index">
<div style="height:753px;width: 100%;">
<div id="{{ s }}" style="height:100%;width: 100%"></div>
<div style=" position: absolute;margin-top: -910px;right: 0px;">
<button class="btn btn-sm btn-primary pull-right" style="margin-top: 20px;" ng-click="save(s)">Save</button>
<button class="btn btn-sm btn-primary pull-right" style="margin-top: 20px;margin-right: 20px;" ng-click="saveAll('all')">Save All</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
Currently i am using button in TabsContent so that i can get the value of "s" to the controller B and i cont use ng-click it is giving me error
<li ng-repeat="s in services track by $index" ng-click="functionInScope(s)">
<a id="s{{$index}}tab" href="#s{{$index}}" data-toggle="tab">
<i class="fa fa-fw fa-lg fa-file" ></i> {{s}}
</a>
</li>
please help me to get the value of "s" with out using the ng-click, so that i can send the value of "s" to the controller A for the save function.
Just a suggestion, Can't we create a variable named "selectedTab" and when you click the tab just generate a KeyUp event from that tab and in this event you can change the value this variable and while posting just get the value from that "selectedTab" variable.
For reference how to generate an click event
https://angular.io/guide/user-input

Bootstrap Model is closed everytime after click on the cancel icon in AngularJS?

I have to remove the product from the list. My product is removed properly but after I click on the cancel icon, the model closes. I am using AngularJS.
/**
* #Summary: removeSelectedProductFromAlbum function, remove the productKey from the album
* #param: event, index, productObject
* #return: NA
* #Description:
*/
$scope.albumKey = [];
$scope.albumObject = [];
$scope.setAlbumObject = [];
$scope.removeSelectedProductFromAlbum = function(event, index, productObject) {
//GET THE ALBUM OBJECT FROM THE SCOPE
$scope.setAlbumObject = $scope.setAlbumObject;
//PROCESS TO REMOVE productKeyId IN ALBUM.
var productKeyId = productObject.keyId;
if(productKeyId != undefined) {
if($scope.productsKeyIdList != undefined && $scope.productsKeyIdList != null) {
var index = $scope.productsKeyIdList.indexOf(productKeyId);
$scope.productsKeyIdList.splice(index, 1);
updatedProductKeyArray = $scope.productsKeyIdList;
//Calling updateArray inner function for update sharedBuyerKeyIdList after remove the keyId
updateArray();
}
}
}
//CALLING THE updateArray FUNCTION FOR UPDATE THE PRODUCT AFTER DELETING THE DATA
function updateArray () {
var PRODUCT_DB_REF = firebase.database().ref('datastore/productsAlbum');
// Updating product key in album.
PRODUCT_DB_REF.child($scope.setAlbumObject.key).update({
productKey : updatedProductKeyArray
});
CMN.showNotification("top","center","info","Product is Successfully Removed");
//$(event.currentTarget).parents("#hideAfterRemove").hide("slow");
}
<div style="overflow:auto; max-height:300px;" >
<div class="dashboard-prod-wrap decorCardD2"
style="width:342px;" ng-repeat="sellerAlbum in sellerSelAlbumProducts" ng-if="sellerSelAlbumProducts.length > 0">
<i class="fa fa-remove" style="font-size:14px; cursor:pointer;" title="Remove"
ng-click="removeSelectedProductFromAlbum($event, $index, sellerAlbum)">
</i>
<div class="w3-row w3-padding-top ng-cloak">
<span class="pull-left color-d4 text-capitalize no-wrap dash-prod-name w3-small ng-cloak">
<span class="product-name" style='padding-right:3px;'>
{{sellerAlbum.categoriesDto.categoryName}}
</span>
<span class="w3-text-teal ng-cloak">
<b>{{sellerAlbum.sellerProductDesignsDtos[0].designsName}}</b>
</span>
<span class="w3-text-teal ng-cloak" ng-if="sellerAlbum.designNumber != 'undefined'">
-<b>{{sellerAlbum.designNumber}}</b>
</span>
<small class="text-muted w3-left w3-price-tag ng-cloak">
<div class='list-icon-f'>
<i class="fa fa-inr" aria-hidden="true"></i>
</div>
<span ng-if="!sellerAlbum.inOffer">
<i class="fa fa-inr"></i>
{{sellerAlbum.fixedPrice}}
</span>
<span ng-if="sellerAlbum.inOffer">
<i class="fa fa-inr"></i>
<strike class="w3-text-red">{{sellerAlbum.fixedPrice}}</strike>
<span class="w3-text-green">
{{sellerAlbum.offerPrice}}
</span>
</span>
</small>
<small class="text-muted w3-left w3-price-tag ng-cloak" ng-if="sellerAlbum.fixedPrice == 0">
<div class='list-icon-f'>
<i class="fa fa-inr" aria-hidden="true"></i>
</div>
<span ng-if="!sellerAlbum.inOffer">
<i class="fa fa-inr"></i>
{{sellerAlbum.maxPrice}}
</span>
<span ng-if="sellerAlbum.inOffer">
<i class="fa fa-inr"></i>
<strike class="w3-text-red">{{sellerAlbum.maxPrice}}</strike>
<strong class="w3-text-green">
{{sellerAlbum.offerPrice}}
</strong>
</span>
<small class="w3-small"> (<i class="fa fa-inr"></i>{{sellerAlbum.minPrice}}
- <i class="fa fa-inr"></i>{{sellerAlbum.maxPrice}})
</small>
</small>
</span>
<div class="pull-right ng-cloak" style="width:100%;margin-top:10px;">
<div class='owner-img'>
<img src="{{sellerAlbum.sellerDto.userTypeDto.imageURL != 'null' ? sellerAlbum.sellerDto.userTypeDto.imageURL : '/static/assets/img/image_placeholder.jpg'}}"
alt="Avatar" class="w3-right w3-circle w3-margin-left">
</div>
<small class="text-uppercase w3-tiny text-muted text-right ng-cloak">
<b>{{sellerAlbum.sellerDto.personName}}</b>
<span ng-repeat="address in sellerAlbum.sellerDto.userTypeDto.userTypeAddressDtos"
ng-if="address.keyId === sellerAlbum.sellerDto.userTypeDto.defaultAddressKeyId">
- <b>{{address.city}}</b>
</span><br>
</small>
</div>
</div>
<hr class="w3-clear margin0">
<div class="w3-row-padding w3-padding-top" style="margin: 0 -16px">
<!-- START:This will display Large Product Image -->
<div class="dashboard-prod-col-left w3-center">
<div class="text-center w3-padding-8"
ng-init="setImageURLList[sellerAlbum.keyId] = sellerAlbum.sellerProductSetDto[0].setImageURLList">
<div ng-repeat="image in setImageURLList[sellerAlbum.keyId]"
ng-click="sellerAlbum.defaultImageURL = image.imageURL"
onClick="imgShadowArr(this);"
ng-init="sellerAlbum.defaultImageURL = setImageURLList[sellerAlbum.keyId][0].imageURL"
class="dashboard-prod-img-wrap {{sellerAlbum.defaultImageURL == image.imageURL ? 'w3-border-teal-orange' : ''}}">
<img src="{{image.imageURL}}" class="prod-img-xs cursor-pointer">
</div>
<div class="dashboard-prod-img-wrap"
ng-if="productImgsList[sellerAlbum.keyId].length < 1">
<img src="/static/assets/img/product_default.jpg"
class="prod-img-xs">
</div>
</div>
</div>
<!-- END:This will display Large Product Image -->
<div class="dashboard-prod-col-right w3-center hover-div">
<img src="{{sellerAlbum.sellerProductSetDto[0].setImageURLList[0].imageURL != null ? sellerAlbum.sellerProductSetDto[0].setImageURLList[0].imageURL :'/static/assets/img/product_default.jpg'}}"
class="cursor-pointer" style="max-height:200px;border:1px solid black;">
<br>
</div>
</div>
<div class="">
<div class="text-center pull-left ng-cloak list-by-a list-by-color">
<div class='list-icon'>
<i class="fa fa-th-large" aria-hidden="true"></i>
</div>
<ul class='margin0'>
<li class="prodColorWrap" ng-repeat="productSet in sellerAlbum.sellerProductSetDto track by $index"
style="cursor:pointer; background-color:{{productSet.colorCode}}"
ng-click="setImageURLList[productSet.keyId] = sellerAlbum.setImageURLList;
productSet.defaultImageURL = setImageURLList[productSet.keyId][0].imageURL">
</li>
</ul>
</div>
<div class='w3-offer-tag' ng-if="sellerAlbum.inOffer">
<label>
<i class="fa fa-star w3-spin"></i>
Offer
</label>
</div>
</div>
<br>
</div>
function for remove icon , please sir how to fix this issue?

onClick event is being caught by the parent element along with the clicked element

I have a div and inside it there are some elements.
my parent div has a test() function by using onClick.
in inside parent div there is a quickView() function by using onClick.
now, when I click on quickView() function, test() function fired .
<div onClick="test();" class="product-inner">
<h5 class="product-title height-40-px">
title
</p>
</h5>
<hr class="mt8 mb8">
<div class="product-meta">
<ul class="product-price-list">
<li><span class="product-save dir-to-right"><strong>7500</strong></span>
</li>
<li><span class="product-old-price dir-to-right">120,000</span>
</li>
<li><span class="product-price">%95</span>
</li>
</ul>
<hr class="mt0 mb0 mr6 hr-blue">
<div class="col-md-12 mt10">
<span class="col-md-6">
۹ <i class="fa fa-users"></i>
</span>
<span class="col-md-6">
<p class="font-size-12 display-inline">
zone
<i class="fa fa-map-marker"></i>
</p>
</span>
</div>
<ul class="product-actions-list mt35">
<li><a data-original-title="add cart" class="btn btn-cart btn-sm popup-text" href="#product-quick-view-add-to-cart" onclick="quickView(18730);" data-effect="mfp-move-from-top" data-toggle="tooltip" data-placement="top" title="">cart <i class="fa fa-shopping-cart"></i></a>
</li><li>details <i class="fa fa-eye"></i>
</li>
</ul>
</div>
</div>
Use event.stopPropagation() to prevent the click event from propagating to the parent. This is how you use it.
P.S. IE supports e.cancelBubble instead of e.stopPropagation()
function quickView(value, e) {
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
console.log(value);
}
function test() {
console.log('test Fired');
}
<div onClick="test();" class="product-inner">
<h5 class="product-title height-40-px">
title
</p>
</h5>
<hr class="mt8 mb8">
<div class="product-meta">
<ul class="product-price-list">
<li><span class="product-save dir-to-right"><strong>7500</strong></span>
</li>
<li><span class="product-old-price dir-to-right">120,000</span>
</li>
<li><span class="product-price">%95</span>
</li>
</ul>
<hr class="mt0 mb0 mr6 hr-blue">
<div class="col-md-12 mt10">
<span class="col-md-6">
۹ <i class="fa fa-users"></i>
</span>
<span class="col-md-6">
<p class="font-size-12 display-inline">
zone
<i class="fa fa-map-marker"></i>
</p>
</span>
</div>
<ul class="product-actions-list mt35">
<li><a data-original-title="add cart" class="btn btn-cart btn-sm popup-text" href="#product-quick-view-add-to-cart" onclick="quickView(18730, event); " data-effect="mfp-move-from-top" data-toggle="tooltip" data-placement="top" title="">cart <i class="fa fa-shopping-cart"></i></a>
</li><li>details <i class="fa fa-eye"></i>
</li>
</ul>
</div>
</div>
Click events are bubbling up from the inner element clicked up to the document root going through all the parents of the clicked element. in order to stop it from propagating up you should use - event.stopPropagation();
That's how event bubbling works. First the click event is triggered on the element that actually was clicked (a.btn.btn-cart in your case) and then it goes upwards and reaches the parent div with test(). You can prevent further event propagation by passing an event to your quickView() function and calling event.stopPropagation(). Then, your HTML should look like this:
<a class="btn btn-cart btn-sm popup-text" onclick="quickView(event, 18730);">Cart</a>
And your JavaScript function:
function quickView(event, number) {
event.stopPropagation();
console.log(number) // Do some stuff with the passed ID.
}

Categories