How to re-initialize PrimeNg Gallaria in angular 11 - primeng

Need bind the newly browsed image files array to the PrimeNg gallaria.
but as it's getting blank image array at the start when initialized and when browse the image files, the new array with image files is not getting updated in the primeNg gallaria.
if anyone have any idea please help.
Additions
Code HTML -
<p-fileUpload #fubauto1 mode="basic" multiple="multiple"
name="demo1[]" accept="image/*"
maxFileSize="maxImageFileSize"
(onSelect)="onSelectImages($event)"
chooseLabel="Select Images"></p-fileUpload>
<p-galleria [(value)]="previews"
[responsiveOptions]="responsiveOptions"
[containerStyle]="{'max-width': '640px'}"
[numVisible]="3">
<ng-template pTemplate="item" let-item>
<img [src]="item" style="width: 100%; display: block;" />
</ng-template>
<ng-template pTemplate="thumbnail" let-item>
<div class="p-grid p-nogutter p-justify-center">
<img [src]="item" style="display: block;width: 50%" />
</div>
</ng-template>
<ng-template pTemplate="caption" let-item>
<h4 style="margin-bottom: .5rem; color: #ffffff;">
{{item?.title}}</h4>
<p>{{item.alt}}</p>
</ng-template>
</p-galleria>
Code Angular TS -
onSelectImages(event) {
console.log(event);
this.selectedImages = event.currentFiles;
this.previews = [];
if (this.selectedImages && this.selectedImages[0]) {
const numberOfFiles = this.selectedImages.length;
for (let i = 0; i < numberOfFiles; i++) {
const reader = new FileReader();
reader.readAsDataURL(this.selectedImages[i]);
reader.onload = (e: any) => {
this.previews.push(e.target.result);
};
}
console.log(this.previews)
}
}
As you can see in the code I am trying to browse the image files and then I have to show the selected/browsed images in gallaria slider.
so after selecting/browsing the files they are get able to shown in the gallaria.
Note- the selected files are able to shown for normal image tag as follows -
<div *ngFor="let item of previews">
<img [src]="item" style="width: 100%; display: block;" />
</div>
Problem with base64 data image array.

Related

GetByRole Unable to find an accessible element with the role "listbox" and name

I have a Kendo dropdown on a react page as follows
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>CDN Code</Label>
<DropDownList
id="cdnCode-dropdown"
name="cdnCodeDD"
value={props.CdnCodeTxt}
onChange={handleChange}
data={componentState.cdnCodeList}
textField="text"
dataItemKey="id"
defaultItem={Constants.DefaultItem}
/>
</div>
and I have this react test code
test('renders cdncode dropdown', () => {
render(<ComponentDetailsContent />);
const element = screen.getByRole("listbox", {
name: "cdnCodeDD",
});
expect(element).toBeInTheDocument();
});
But when I run this test I get this error
TestingLibraryElementError: Unable to find an accessible element with the role "listbox" and name "cdnSicCodeDD"
It then goes on to list all the accessible roles and the name is blank for all of them.
Name "":
<span
aria-activedescendant="option-01abe0e8-1cc2-4ca2-ac35-d2a04f7dda62--1"
aria-expanded="false"
aria-haspopup="true"
aria-owns="0f6115c2-49f9-4430-bb2e-09841d34807b"
class="k-dropdown-wrap k-state-default"
id="cdnCode-dropdown"
role="listbox"
tabindex="0"
/>
Why is that even though my dropdown clearly has a name? I have also tried with "/cdncode/i" and I get the same error. I can't install Testing Playground plugin at work otherwise I would be able to tell the correct query for testing. Any alternatives that don't require chrome plugins?
Also, if I list out all the listboxes using GetAllByRoles I get the following array which contains the dropdown with the correct name?
[...
<select aria-hidden="true" name="cdnCodeDD" style="opacity: 0; width: 1px; border: 0px; z-index: -1; position: absolute; left: 50%;" tabindex="-1"><option value="[object Object]" /></select></span>]

How to use useRef to toggle between images

Given an image gallery, where the user can click an image and the selected image will be shown in the gallery below it, how can I use useRef to replace the image in the gallery div with the selected image on click? The idea is that the images will be populating the gallery at the top from an array, so each image will presumably have the useRef applied to it?
HTML
<div class="wrapper">
<div class="row">
<div class="column">
<img src="imageurl" alt="water" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl2" alt="tree" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl3" alt="snow" style="width:100%" onClick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl4" alt="mountain" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl5" alt="tree2" style="width:100%" onclick="myFunction(this);">
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg" style="width:100%">
<div id="imgtext"></div>
</div>
</div>
Function to toggle large image visibility
const myFunction = imgs => {
const imageRef = useRef();
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = imgs.src;
imgText.innerHTML = imgs.alt;
expandImg.parentElement.style.display = "block";
}
The current state can be seen here: jsFiddle
As the React Docs state: Don’t Overuse Refs
Your code snippet is not what refs should be used for. In React, you should make things interactive via state changes, not by fiddling with the DOM, React is designed to do that for you.
However from that jsfiddle, it looks like you aren't even using React? I am unsure why you are using useRef at all?
UPDATE: Code fix
By using function to define your function (instead of an arrow function), it gets hoisted so your HTML elements can pick it up, and the getElementById method gets you the element reference you need.
Just replace all your js with:
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
function myFunction(imgs) {
expandImg.src = imgs.src;
imgText.innerHTML = imgs.alt;
expandImg.parentElement.style.display = "block";
}
...and your jsfiddle works.

Add multiple dialogs into a single page

I'm working into an Angular app that displays some data into a dataGrid as follows.
<p-dataGrid [value]="docs" [paginator]="true" [rows]="8">
<ng-template let-doc pTemplate="item">
<div class="ui-g-12 ui-md-3">
<span>{{doc.title}}</span>
</div>
</ng-template>
</p-dataGrid>
I'm trying to add a button, that when clicked, displays some info regarding the selected doc. I did it as follows:
<p-dataGrid [value]="docs" [paginator]="true" [rows]="8">
<ng-template let-doc pTemplate="item">
<div class="ui-g-12 ui-md-3">
<span>{{doc.title}}</span>
<button (click)="showDialog(doc.id)" pButton type="button" icon="fas fa-info-circle" iconPos="left" label="Details"></button>
<p-dialog id="{{doc.id}}" #{{doc.id}} [(visible)]="display" modal="modal" width="300" [responsive]="true">
<p>{{doc.title}}</p>
</p-dialog>
</div>
</ng-template>
</p-dataGrid>
Into my component, I added a function:
display: boolean = false;
showDialog(id: string) {
alert(id);
this.display = true;
}
The problem is since I'm using the same variable ("display") to control the visibility of all dialogs, browser gets lost about which dialog it should show/hide. In general, it uses the last one.
Since the quantity of elements into the screen is variable, I cannot create display1, display2, displayN variables. So my doubt is, how do I dynamically control the visibility of an element?
I tried something like with no luck:
showDialog(id: string) {
var e = document.getElementById(id);
e.attributes['ng-reflect-visible'].value = true;
}
There's no need to create as many p-dialog elements as docs. Only once should be enough. So if you extract yours p-dialog outside of your p-datagrid, HTML code becomes something like that :
<p-dataGrid [value]="docs" [paginator]="true" [rows]="8">
<ng-template let-doc pTemplate="item">
<div class="ui-g-12 ui-md-3">
<span>{{doc.title}}</span>
<button (click)="showDialog(doc.id)" pButton type="button" icon="fas fa-info-circle" iconPos="left" label="Details"></button>
</div>
</ng-template>
</p-dataGrid>
<p-dialog id="dialog" [(visible)]="display" modal="modal" width="300" [responsive]="true">
<h1>{{selectedDoc.title}}</h1>
Details : {{selectedDoc.details}}
</p-dialog>
where selectedDoc is assigned when you click on a button :
showDialog(id: string) {
this.selectedDoc = this.docs[id-1];
this.display = true;
}
Here is a working Plunker

Button ng-class doesn't apply

I am trying to create custom pager for ion-slide-box. This is codepen sample
This is my js:
$scope.currentSlide = 0;
$scope.pagerClick = function (index) {
$ionicSlideBoxDelegate.slide(index);
}
$scope.slideChanged = function (index) {
$scope.currentSlide = index;
}
This is html file:
<ion-slide-box does-continue=true show-pager=false on-slide-changed="slideChanged($index)">
<ion-slide class="item-image" ng-repeat="i in getNumber(number) track by $index">
<img src='{{images[$index]}}' />
</ion-slide>
</ion-slide-box>
<div class="page-indicator" ng-repeat="i in getNumber(number) track by $index">
<a class="button" href ng-class="{activated: $index == currentSlide}" ng-click="pagerClick($index)">{{$index+1}}</a>
</div>
Almost all works fine, except one thing. When I click on my pager buttons it doesn't change active button in pager. When I swype slides all buttons change style correctly. I think it may be because of $index - I have two such variables. But I can't understand or fix it.
I finally solved this problem which was because activated is inline class of button.
When I push button this class was applying, but when I unpress button Angular delete this class.
I create my class active-button and all is now working.
<div class="page-indicator" ng-repeat="i in getNumber(number) track by $index">
<a class="button" href ng-class="{'active-button': $index == currentSlide}" ng-click="pagerClick($index)">{{$index+1}}</a>
and css
.active-button{
background-color: #b2b2b2 !important;
box-shadow: none !important;
color: #fff !important;
}

Polymer 1.0 paper-card displays {{ }} binding variables as it is inside Angularjs ng-repeat - [Issue only in Chrome]

I am very new to angularjs, i have done some experimental projects in Polymer 0.5, so new to Polymer 1.0 as well.
I am facing an issue like inside ng-repeat i want to display some paper-card.
This issue is only on Chrome browser, In Firefox and IE-edge it is coming fine.
<paper-card heading="{{ team.name }}">
<div class="card-content">Some content</div>
<div class="card-actions">
<paper-button>Some action</paper-button>
</div>
</paper-card>
//--------------------------- HTML ----------
<div class="row content">
<div><h3>Teams <img ng-show="loading" ng-src='images/loader2.gif' width="30px" height="30px"/></h3></div>
<div ng-repeat="team in teams" ng-repeat="team in teams | filter:teamsFilter">
<div>
<style>
.collapse-content {
padding: 15px;
border: 1px solid #dedede;
}
</style>
<paper-card heading="{{ team.name }}">
<div class="card-content">Some content</div>
<div class="card-actions">
<paper-button>Some action</paper-button>
</div>
</paper-card>
</div>
</div>
</div>
//--------------------------- HTML -------------
I am using ng-polymer-element module,
I have the below code in my application app.js
angular.module('ng-polymer-elements').constant('$ngPolymerMappings', {
paperCard: {
ngModel: function property(element) {
return element.hasAttribute('multi') ? 'selectedValues' : 'selected';
},
ngHeading: '=heading'
}
});
window.addEventListener('WebComponentsReady ', function() {
angular.bootstrap(wrap(document), ['myApp']);
});
The Card header is coming fine but the binding variable is also displaying inside the card.
I inspect the HTML in the browser, i could see the paper-material is added twice and the second one is showing the brackets as it is.
Any help is highly appreciated. Thanks.
Most likely that Angular is not loaded properly; therefore, it hasn't kicked in to evaluate the expressions in the braces. Please post your entire HTML page.

Resources