AngularJs - On ng-click all items get affected - javascript

I'm trying to change the scope when i click on the element but when i do that all the elements get's changed
What im trying to accomplish is when i click on one of the div, i want te color of the div to change to red. this part works fine. Then i also want to the scope to change when i click on one of the divs. What is happening here is that all the scopes are changing.
<div class="col-md-3 col-sm-6 mb-3" ng-repeat="student in stuRegister.students" ng-click="stuRegister.absneceChange($index, absence)">
<div id="myDIV{{$index}}" class="card text-white bg-success o-hidden h-100" data-index="{{$index}}">
<div class="card-body">
<div class="mr-5" >
<p>{{$index + 1}}. <strong>{{student.name}}</strong></p></div>
<div class="mr-5" data-ng-model-options="stuRegister.aData.role" ><strong ng-bind="absence">Status: {{absence[0]}}</strong></div>
</div>
<a class="card-footer text-white clearfix small z-1" href="#">
<span class="float-left">Indmeld fravær</span>
<span class="float-right">
<i class="fa fa-angle-right"></i>
</span>
</a>
</div>
</div>
Js:
$scope.absence = "Tilstede";
this.absneceChange = function(index, absence){
var element = document.getElementsByClassName("card");
$scope.absence = $scope.absence === "Tilstede" ? "Fravær" : "Tilstede";
element[index].classList.toggle("bg-danger");
element[index].classList.toggle("bg-warning");
}

Related

Showing a button that pushes all other elements to the side (CSS Transition)

Basically, I'm having cards that have a height set by the flex behaviour. I'd like to add a button from the side that is only shown when the card is hovered so the button would come out from the right side of the container with a transition and start expanding and pushing all other content to the left until it finishes expanding. Therefore, I've looked for hours and I tried many things out and I couldn't find a solution. Could someone please help me out on this? here is my code, I'm using Bootstrap 5. Here is the UI I created
Here is my code . I'm using VueJS and my data is coming from an API.
<template>
<div class="d-flex col-12 flex-column bd-highlight mb-3">
<div class=" d-flex border border-dark col-12 flex-column" v-for="(question,index) in questions" :key="question + index">
<div class="d-flex col-12 justify-content-between">
<div>
<span class="text-wrap text-break">{{question.description}}</span>
</div>
<div class="d-flex">
<span :class="question.complexity.toLowerCase() === 'easy' ? 'badge bg-success align-self-start' : question.complexity.toLowerCase() === 'medium' ? 'badge bg-warning align-self-start' : 'badge bg-danger align-self-start' ">{{question.complexity}}</span>
</div>
</div>
<div class="d-flex flex-wrap">
<div class="p-2" v-for="(tag,index1) in question.tags" :key ="tag + index1">
<span class="badge bg-dark text-white"><i :class="'devicon-'+tag.nom.toLowerCase()+'-plain'"></i> {{tag.nom}}</span>
</div>
<div class="align-items-center d-flex w-100 justify-content-end">
<span>
<i class="fas fa-stopwatch"></i> {{question.duree}} secs </span></div>
</div>
</div>
</div>
</template>
Here is my UI
Expected Result ( Buttons should be with the same size )

JavaScript trying to append to HTML not working

I am trying to create a simple eCommerce website with HTML, CSS, and JavaScript. When a user adds an item to their cart I add that item to local storage and I want when the user goes to their cart, all the items in local storage are read and then displayed to the cart. Whenever I try to append I get this. Instead of displaying the HTML it displays a string of all the HTML?
function getCartItems() {
var items = JSON.parse(localStorage.getItem("cartItems"));
console.log({ items });
for (let i = 0; i < items.length; i++) {
console.log(items[i]);
var cartRow = document.createElement("div");
// cartRow.classList.add("cart-row");
var cartItems = document.getElementsByClassName("cart-items")[0];
var cartRowContents = ` <li class="list-group-item d-flex flex-column">
<div class="row">
<div class="col col-lg-4">
<img
src="${items[i].image}"
alt="${items[i].name}"
class="d-block mx-auto"
/>
</div>
<div class="col col-lg-2 text-center">
<h5 class="mt-4 flex-wrap">${items[i].name}</h5>
<p>Size: 10.5</p>
<h2><span class="badge badge-danger">$189.99</span></h2>
</div>
<div class="col mt-4 text-center">
<p class="font-weight-bold">Quantity</p>
<input type="number" value="1" class="pl-2 w-50 rounded cart-quantity" />
<button
class="btn border border-none mx-5 mt-3 mt-lg-0 remove-item"
>
<i class="far fa-trash-alt"> </i>
</button>
</div>
</div>
</li>`;
cartRow.innerText = cartRowContents;
cartItems.append(cartRow);
}
}
Here is the code for my HTML
<!-- Cart -->
<div class="card m-5 border border-none mw-50">
<div class="card-header text-center text-white bg-primary">
Your Order
</div>
<ul class="list-group list-group-flush cart-items">
<li class="list-group-item d-flex flex-column">
<div class="row">
<div class="col col-lg-4">
<img
src="./images/products/air-max-270.jpg"
alt="Air Max 270"
class="d-block mx-auto"
/>
</div>
<div class="col col-lg-2 text-center">
<h5 class="mt-4 flex-wrap">Nike Air Max 270</h5>
<p>Size: 10.5</p>
<h2><span class="badge badge-danger">$189.99</span></h2>
</div>
<div class="col mt-4 text-center">
<p class="font-weight-bold">Quantity</p>
<input type="number" value="1" class="pl-2 w-50 rounded cart-quantity" />
<button
class="btn border border-none mx-5 mt-3 mt-lg-0 remove-item"
>
<i class="far fa-trash-alt"> </i>
</button>
</div>
</div>
</li>
</ul>
Call appendChild with innerHTML:
var cartItems = document.getElementsByClassName("cart-items")[0];
var cartRow = document.createElement("div");
cartRow.innerHTML = cartRowContents;
cartItems.append(cartRow);
Note: innerHTML is only destructive when used in combination with the += operator, as it causes a DOM refresh. It's all right to use it with createElement, as you're only changing the child's innerHTML, not the entire DOM. Reference
It seems you have confused Element.innerHTML with HTMLElement.innerText, as the latter sets your String to be the Node's actual text, not its HTML.
However, since it is discouraged to use Element.innerHTML for manipulating a Node's HTML, you should instead use Element.insertAdjacentHTML() instead.
This is because you are using innerText. You can use innerHtml instead but it's not recommended.
The way you are doing this, the only way you can pull it off is by using innerHTML like your last answer. However, if you want to do it the 'recommended' way, I would recommend using something called HTML DOM. You can recode all that you did simply by using the concept of creating elements and then appending them to each other and, finally, your cart. Here is the simple concept:
https://www.w3schools.com/js/js_htmldom.asp

Textarea cannot append to after typeing. Also, cannot append new text

I am new to javascript and jquery. While learning this I ran into a few issues. I wanted to know what I am doing wrong here. I am using a textarea element to type in. When I run the jQuery script below it will post to the dive I called read-post no problem But I cannot run the click Function to append to the textarea. Also, if I start typing in the text area I cannot append to the textarea. However, If I start frest I can append to the textarea no problem.
$(".btn-post").click(function() {
$("div").append($("textarea").val() + '<br />');
$("textarea").val('');
$("textarea").html('');
});
$("div #icon > span").click(function() {
$(".textarea").append($(this).text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row post-body">
<div class="col-2 p-0 post-img-holder my-auto p-1">
<div class="embed-responsive embed-responsive-1by1 text-center">
<div class="embed-responsive-item">
<a href="uuid">
<img class="post-img" src="$imgPath">
</a>
</div>
</div>
</div>
<div class="col-10 p-0">
<textarea class="post-input" type="textblock" placeholder="What do you want to share, uuid?"></textarea>
</div>
</div>
<div class="row post-footer">
<div class="col-10 float-left dropdown">
<a class="dropdown-toggle emoji-icon" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">πŸ˜€</a>
<div id="emoji-icon" class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<span>πŸ˜€</span><span>πŸ˜ƒ</span><span>πŸ˜„</span><span>😁</span><span>πŸ˜†</span>
<span>πŸ˜…</span><span>🀣</span><span>πŸ˜‚</span><span>πŸ™‚</span><span>πŸ™ƒ</span>
</div>
</div>
<div class="col-2 float-right">
<button class="btn btn-secondary btn-sm btn-post" type="post">Post</button>
</div>
https://jsfiddle.net/hmwLox17/
u have two missing one of them is your icon id is #emoji-icon but u wrote just #icon,
second missing is u should write $("textarea") bu u wrote $(".textarea")
$(".textarea") means u have an element whose class is textarea
#icon means u have element whose id is icon
$("div #emoji-icon > span").click(function(){
$("textarea").val($("textarea").val()+$(this).text());
});

HTML and Javascript search bootstrap cards

Javascript returning : "Uncaught TypeError: Cannot read property 'innerText' of null" while typing on search form.
I have a page with some Bootstrap cards, and I want to filter the cards by name.
I have tried to get "card-title" element class to validate the search filter.
HTML code:
<div class="container">
<div class="row">
<div class="col-sm-4 mb-4">
<input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for card name...">
</div>
</div>
<div class="row" id="myProducts">
<div class="col-md-4">
<div class="card">
<div class="card-header bg-dark d-sm-flex justify-content-sm-between align-items-sm-center">
<div class=" card-title">
<a href="#" style="color:white" class="display-inline- block" onmouseover="this.style.color='#00e6ac'" onmouseout="this.style.color='#fff'">
<strong>Card 1</strong>
</a>
</div>
</div>
<div class="card-body bg-light">
0000x01
</div>
<div class="card-footer bg-white d-flex justify-content-between">
<div>
<i class="icon-arrow-right5 mr-2"></i>Card number one
</div>
</div>
</div>
<div class="card">
<div class="card-header bg-dark d-sm-flex justify-content-sm-between align-items-sm-center">
<div class=" card-title">
<a href="#" style="color:white" class="display-inline- block" onmouseover="this.style.color='#00e6ac'" onmouseout="this.style.color='#fff'">
<strong>Card 2</strong>
</a>
</div>
</div>
<div class="card-body bg-light">
0000x02
</div>
<div class="card-footer bg-white d-flex justify-content-between">
<div>
<i class="icon-arrow-right5 mr-2"></i>Card number two
</div>
</div>
</div>
</div>
<!-- /transparent header, white footer -->
</div>
</div>
Javascript
function myFunction() {
var input, filter, cards, cardContainer, title, i;
input = document.getElementById("myFilter");
filter = input.value.toUpperCase();
cardContainer = document.getElementById("myProducts");
cards = cardContainer.getElementsByClassName("card");
for (i = 0; i < cards.length; i++) {
title = cards[i].querySelector("card-title");
if (title.innerText.toUpperCase().indexOf(filter) > -1) {
cards[i].style.display = "";
} else {
cards[i].style.display = "none";
}
}
}
also testing on:
https://codepen.io/pratykus/pen/WNeJpyK
Every time I type on filter box I got incremented error:
(6) Uncaught TypeError: Cannot read property 'innerText' of null
When you use .querySelector you should specify the class or the element. In your case your element is the div and your class that you're trying to access is card-title, so change:
title = cards[i].querySelector("card-title");
to:
title = cards[i].querySelector(".card-title");
If you are passing a CSS class as the selector to querySelector(), then you have to append it with dot .
title = cards[i].querySelector(".card-title");
Make this change to fix the issue.

String interpolation with angular not binding

I'm trying to bind the data to a template using string interpolation. When I am trying to refer the variable in the template, then it returns the following error:
core.js:1350 ERROR TypeError: Cannot read property 'status' of
undefined.
HTML code:
<div class="chat-main">
<div class="col-md-12 chat-header rounded-top bg-primary text-white hide-chat-box">
<div class="row">
<div class="col-md-6 username pl-2">
<h6 class="m-0"> Tasks</h6>
<span class="badge" style="background: red">{{ task?.status?.length }}</span>
</div>
<div class="col-md-6 options text-right pr-2">
<i class="fa fa-window-minimize" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="chat-content">
<div class="col-md-12 chats border">
<br/>
<ul class="p-0" *ngFor="let task of tasksRes">
<li class="pl-2 pr-2 text-dark send-msg mb-1">
<div>
<a href="javascript:;" [routerLink]="[task.link]" style="text-decoration: none !important;">
<span class="text-warning" *ngIf="task.status == 'In_progress'"><i class="fa fa-spinner fa-spin"></i></span>
<span class="text-success" *ngIf="task.status == 'Done'"><i class="fa fa-check"></i></span>
<span> {{ task.name }}</span>
</a>
<br/>
<span class="pull-right text-muted">{{task.createdDate | timeAgo}}</span>
<span class="text-muted"> {{task.eventType}}</span>
</div>
</li>
</ul>
</div>
</div>
</div>
task is local variable scope only inside ngFor template that mean ul element here
just move this span element to be inside `ngFor' template
<span class="badge" style="background: red">{{ task?.status?.length }}</span>
NgFor Local Variables

Categories