Src unknown after push - javascript

Hi i have problem with pushing item from one array to another. It's system of equipment in my game. The problem is that image of item has unknown src after being pushed to another array.
angular ts
itemy = [{id: 0, name: "sword", url:'../../../../assets/img/sword.png'}, {id: 1, name: "sword2", url:"../../../../assets/img/sword2.png"}];
images = JSON.parse(localStorage.getItem('images')) || [];
add (){
let index=Math.round(Math.random())
this.images.push(this.itemy[index]);
localStorage.setItem('images', JSON.stringify(this.images));
}
eq = JSON.parse(localStorage.getItem('eq')) || [];
select() {
this.eq.push(this.images);
this.eq.length = 1;
localStorage.setItem('eq', JSON.stringify(this.eq));
}
unselect() {
this.eq.pop();
localStorage.setItem('eq', JSON.stringify(this.eq));
}
}
HTML
<div class="eq">
<div id="contentInside2" *ngFor="let image of eq">
<img class="item" src={{image.url}} (click)="unselect()"/> </div>
</div>
<button (click)="add()">Add</button>
<div id="content">
<div id="contentInside" *ngFor="let image of images">
<img class="item" src={{image.url}} (click)="select()"/>
</div>
</div>
Here is how it looks now

If you want to only select clicked image.
Change your template to :-
<div class="eq">
<div id="contentInside2" *ngFor="let image of eq; let i=index">
<img class="item" src={{image.url}} (click)="unselect(i, image)"/> </div>
</div>
<button (click)="add()">Add</button>
<div id="content">
<div id="contentInside" *ngFor="let image of images; let i=index">
<img class="item" src={{image.url}} (click)="select(i, image)"/>
</div>
</div>
then typescript method to :-
select(index, image) {
if(this.eq.length === 1) {
return;
}
this.eq.push(image);
this.images.splice(index, 1);
localStorage.setItem('images', JSON.stringify(this.images));
localStorage.setItem('eq', JSON.stringify(this.eq));
}
unselect(index, image) {
this.eq.splice(index, 1);
this.images.push(image);
localStorage.setItem('images', JSON.stringify(this.images));
localStorage.setItem('eq', JSON.stringify(this.eq));
}

Related

Add JSON item into localStorage

I'm working on an angular task and the goal is to add items to be purchase into localStorage before adding to cart.
I have four different object that users can add, item can be added several time, so the general condition is if object exist on localStorage and user add it other time I should update quantity attribute, if not add new object with new attribute quantity = 1.
here is the service :
addGiftToCard(type) {
let cardParse = JSON.parse(localStorage.getItem('cart')) || []
let index = _.findIndex(cardParse, item => item.type && item.id == type.id)
if (index == -1) {
type.qte = 1
cardParse.push(type)
} else {
cardParse[index].qte += 1
}
localStorage.setItem('cart', JSON.stringify(cardParse))
}
and the function in my component :
addGiftToCart(type) {
let index = this.cartService.addGiftToCard({ type: type })
}
html :
<div class="available-checks" *ngIf="!(types === null)">
<div class="row checks-list">
<div class="col-md-3" *ngFor="let type of types">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-8 logo-container justify-content-center">
<img class="card-logo" src="../../../assets/images/logo-gold.svg" alt="">
</div>
<div class="col-4 icon-container justify-content-center text-center">
<img [src]=" serverUrl+'/'+type?.image" alt="" style="width: 50px;height: 50px;">
</div>
</div>
<div class="row desc-title-c">
<p class="desc-title">Chèque cadeau</p>
</div>
<div class="row type-c">
<p class="check-type">{{type.type}}</p>
</div>
<div class="offer-container">
<p class="offer">{{type.designation}}</p>
<p class="price">{{type.amount}}€</p>
</div>
<div class="">
<button class="btn btn-footer" (click)="addGiftToCart(type)">Ajouter au panier</button>
</div>
</div>
</div>
</div>
</div>
</div>
The problem I got here is the one object added what ever the item is and only the quantity attribute counter updated and got json format like that :
and If I set type = type.type in the service function It works and I got json like that
I need the json element type do not contain an attribute qty, qty should be outside the object attributes like the first image !
I think you should have used item.type.id instead of item.id like below
let index = _.findIndex(cardParse, item => item.type && item.type.id == type.id)

Get the current element running in ngFor

List of images are executing in a loop(ngFor). I am trying to get the current element that is being clicked by calling the function (click)="addStyle()".The issue I am facing here is ,if i am adding a style [class.active] depending upon the clicked method,it gets reflected in all the image tags.But I am trying to add style to only the particular image being clicked.
component.html
<div class="item" *ngFor="let i of img;let i = index">
<img class="product-i-2" [src]="i" [class.active]="isActive" (click)="addStyle()">
</div>
component.ts
isActive:false;
addStyle()
{
this.isActive=true;
}
component.css
.active
{
border:1px solid red;
}
In short,I am trying to add style to only particular image tag and not all the images in the loop
Try this one.
<div class="item" *ngFor="let i of img;let i = index">
<img class="product-i-2" [src]="i" [class.active]="i === activeIdx"
(click)="addStyle(i)">
</div>
activeIdx: number;
addStyle(i)
{
this.activeIdx = i;
}
you can try like this
HTML
<div class="item" *ngFor="let i of img;let j = index">
<img class="product-i-2" [src]="i" [class.active]="isActive[i] == true ? 'active' : '' " (click)="addStyle(j)">
</div>
TS
isActive: any[] = false;
ngOnInit() {
// here we set defalut value to false
for (let i = 0; i < img.length; i++) {
this.isActive.push(false);
}
}
addStyle(j)
{
this.isActive[j]= !this.isActive[j];
}
You can pass event parameter on click and in that you will get element and than you can add class into it.
<div class="item" *ngFor="let i of img;let i = index">
<img class="product-i-2" [src]="i" (click)="addStyle(e)">
</div>
// In TS file
addStyle(event)
{
event.target.classList.add(className);
}
The best way is you convert the array of images to array of object of images and mark as active.
ngOnInit(){
this.img.forEach((img)=>{
this.alter.push({src:img, isActive:false})
})
}
addAlterStyle(index){
this.alter.forEach((img) => img.isActive = false);
this.alter[index].isActive = true;
}
HTML
<div class="item" *ngFor="let image of alter;let i = index">
<img class="product-i-2" [ngClass]="{'isActive':image.isActive}" [src]="image.src" (click)="addAlterStyle(i)">
</div>
If you dont want to change the img array structure
TS
addStyle(event){
let imageTags = document.querySelectorAll('.image');
imageTags.forEach((element)=>{
element.classList.remove('isActive')
})
event.target.classList.add('isActive')
}
HTML
<div class="item" *ngFor="let image of img;let i = index">
<img class="product-i-2 image" [src]="image" (click)="addStyle($event)">
</div>
Here is the stackblitz working demo
don't save isActive property save active Image and then you can check a condition by reference
activeImg:any;
addStyle($event){
this.activeImg=$event;
}
<div class="item" *ngFor="let i of img;let i = index">
<img class="product-i-2" [src]="i" [class.active]="activeImg==i" (click)="addStyle()">

How to show images when hovered a single list element of ngfor ulist in angular2?

showfavstar(val)
{
this.favstar = true;
}
<ul class="listboxtickets">
<li class="selectlistticket" *ngFor="let fav of favlist" (mouseover)="showfavstar(fav.req_id)" (mouseleave)="hidefavstar()">
<div class="atickname" (click)="timetracker(fav.req_id,fav.ticket_summary,fav.time_logged*60*1000)"> {{fav.ticket_summary.substring(0,20)}} </div>
<div> {{fav.time_logged} </div>
<div class="atickstat" [hidden]="!favstar"> <img class="staraimg" src="assets/images/star_icon.png" (click)="removefav(fav.req_id)"/> </div>
<div class="namelinet"> <img src="assets/images/text_bottomline.png"/> </div>
</li>
</ul>
I want to show star image for only hovered list?Now i get all the star images
This cannot be achived using single variable which you took here i.e favstar.
Try your code like this
<ul class="listboxtickets">
<li class="selectlistticket" *ngFor="let fav of favlist" (mouseover)="showfavstar(fav)" (mouseleave)="hidefavstar(fav)">
<div class="atickname" (click)="timetracker(fav.req_id,fav.ticket_summary,fav.time_logged*60*1000)">
{{fav.ticket_summary.substring(0,20)}}
</div>
<div> {{fav.time_logged} </div>
<div class="atickstat" [hidden]="!fav?.Show">
<img class="staraimg" src="assets/images/star_icon.png" (click)="removefav(fav.req_id)"/>
</div>
<div class="namelinet"> <img src="assets/images/text_bottomline.png"/> </div>
</li>
</ul>
showfavstar(fav){
fav.Show = true;
for(let i = 0; i < this.favlist.length; i++){
this.favlist[i].Show = false;
}
}
hidefavstar(val){
fav.Show = true;
for(let i = 0; i < this.favlist.length; i++){
this.favlist[i].Show = true;
}
}

iterating a multidimensional Json with AngularJS(Ng-Repeat)

I have problem to show all elements of subcategory with Ng-Repeat. Actually i can show all events from selected category with this code, but i don't know how to show all activities from specific event.
i have this code....
HTML
<div class = "categorias_eventos">
<ul>
<li value = "0" class = "active">
<img src="images1" ng-click="categorySelected = {categoryName: '1'}">
</li>
<li value = "1" class = "active">
<img src="images2" ng-click="categorySelected = {categoryName: '2'}">
</li>
<li value = "2">
<img src="images3" ng-click="categorySelected = {categoryName: '3'}">
</li>
<li value = "3" >
<img src="images4" ng-click="categorySelected = {categoryName: '4'}">
</li>
<li value = "4">
<img src="images5" ng-click="categorySelected = {categoryName: '5'}">
</li>
</ul>
</div>
<div ng-controller="Test">
<div ng-repeat="evento in eventos | filter:categorySelected" ng-click = "eventSelected = {id: '{{evento.id}}'}">
<div class="infoEvento">
<div class="name_event">
{{evento.eventName}}
</div>
</div>
</div>
</div>
<!-- Activitys -->
<div ng-controller="Test">
<div ng-repeat="activity in evento.activitys | filter:eventSelected">
<div class="infoEvento">
<div class="name_event">
{{activitys.description}}
</div>
</div>
</div>
</div>
JAVASCRIPT
function Test($scope) {
$scope.eventos = [
{
"id":"1",
"dateStart":"01-12-2014",
"dateEnd":"12-12-2014",
"eventName":"partyDeluxe",
"categoryName":"Category 1",
"activitys":
[
{
"pic_id":"1500",
"description":"Picture of a computer",
"localion":"img.cloudimages.us/2012/06/02/computer.jpg",
"type":"jpg"
},
{
"pic_id":"100",
"description":"Picture of a computer",
"localion":"img.cloudimages.us/2012/06/02/computer.jpg",
"type":"jpg"
},
{
"pic_id":"15",
"description":"Picture of a computer",
"localion":"img.cloudimages.us/2012/06/02/computer.jpg",
"type":"jpg"
}
]
},
];;
}
The problem you have is that your inner ng-repeat is sitting outside your outer, which means the activity context is unknown. To fix this, you simply need to rethink your div layout to include one ng-repeat inside the other. For example:
<div ng-controller="Test">
<div ng-repeat="evento in eventos | filter:categorySelected">
<div ng-click = "eventSelected = {id: '{{evento.id}}'}">
<div class="infoEvento">
<div class="name_event">
{{evento.eventName}}
</div>
</div>
</div>
<!-- Activitys -->
<div ng-controller="Test">
<div ng-repeat="activity in evento.activitys | filter:eventSelected">
<div class="infoEvento">
<div class="name_event">
{{activitys.description}}
</div>
</div>
</div>
</div>
</div>
</div>

Combine two collections of elements with mobify.js

everyone.
I've just started using the mobifyjs toolkit and I've ran into a problem of combining two collections of elements into one.
On a page I'm trying to mobify there are two sets of links: with text and images. The HTML looks like the following:
<!-- links with text -->
<div id="products">
Product 1
Product 2
</div>
...
<!-- somewhere else on the page -->
<div id="productImages">
<img src="Product1.png />
<img src="Product2.png />
</div>
It needs to turn into the following:
<div class="items">
<div class="item">
<div class="img">
<img src="Product1.png />
</div>
<div class="title">
Product 1
</div>
</div>
<div class="item">
<div class="img">
<img src="Product2.png />
</div>
<div class="title">
Product 2
</div>
</div>
</div>
My current solution is to use map function, so in the mobify.konf I have something like the following:
'content': function(context) {
return context.choose(
{{
'templateName': 'products',
'products': function(){
return $('#productImages a').map(function() {
var href = $(this).attr('href') || '';
var div = $('<div class="item"><div class="img"></div><div class="title"></div></div>');
div.find('.img').append($(this).clone());
div.find('.title').append($('#products a[href="' + href + '"]').clone());
return div;
});
}
})
}
And the template is:
<div class="items">
{#content.products}
{.}
{/content.products}
</div>
This code does work but the approach itself is pretty ugly since I have to move a piece of markup code from the tmpl file into mobify.konf. Can anyone suggest a better solution?
The best way to do this sort of thing is to collect the relevant properties for your items (e.g. the product name, the image url and the link href) into a data structure in javascript, and then create a template for your new html structure in the .tmpl file. Something like
'products': function() {
var products = [],
$productLinks = $('#products a'),
$productImages = $('#productImages img')
len = $productNames.legnth;
for(var i = 0; i<len; i++) {
var $link = $productLinks.eq(i);
var $img = $productImages.eq(i);
products.push({name: $link.text(), href: $link.attr('href'), imgSrc: $img.attr('src')});
}
return products;
}
and then template it by iterating over the array items and inserting them into relevant places in the markup:
<div class="items">
{#content.products}
<div class="item">
<div class="img"><img src="{.imgSrc}" /></div>
<div class="title">{.name}</div>
</div>
{content.products}
</div>

Categories

Resources