Apply class based on integer value in an AngularJS expression - javascript

I'm calculating differences between 2 values then storing that value in a variable named "allCallsNet", I want to toggle a class based on if the number is a Positive or Negative number in my HTML, using AngularJS Expressions
Example:
{allCallsNet=allCallsWeek1 - allCallsWeek2;""}
<p ng-class"{{positive: (allCallsNet.value != 'Negative')}}">{{allCallsNet}}</p>

And if you also need help checking the number sign this could help
angular.module('Stack', []).controller('MainCtrl', function($scope) {
$scope.allCallsNet = 0;
$scope.add = function() {
$scope.allCallsNet += 1;
}
$scope.sub = function() {
$scope.allCallsNet -= 1;
}
});
.negative {
color: red;
}
.positive {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="Stack" ng-controller="MainCtrl">
<!-- You can use the ternary operator, to exchange between classes -->
<p ng-class="allCallsNet > 0 ? 'positive' : 'negative'">Start editing and see your changes reflected here!</p>
<button ng-click="add()">Add</button>
<button ng-click="sub()">Subtract</button>
<p>{{ allCallsNet }}</p>
</div>

Try this:
<p [class.positive]="allCallsNet.value != 'Negative'" >{{allCallsNet}}</p>

Related

Replace values in an array dynamically

I have a scenario like this. Say: let a = [2,5,6] and let b = [1,2,3,4,5,6,7,8]. Array b is displayed in boxes and revealed when one clicks any of the boxes. What I am trying to do is, when one clicks on any box and the value is the same as any value in array a, I replace the value with other unique values and if they're not the same I display as it is.
e.g. If I click a box that has a value of 2 or 5 or 6 i replace the values with the other values.
A minimal example is:
new Vue({
el: "#app",
data: {
a: [2,5,6],
b: [1,2,3,4,5,6,7,8]
},
methods: {
replaceNumber() {
// function to replace the values
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.numbers {
display: flex;
}
li {
list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Numbers:</h2>
<br/>
<ul class="numbers">
<li v-for="num in a">
{{num}}
</li>
</ul>
<br/>
<template>
<button #click="replaceNumber" v-for="number in b">
{{ number }}
</button>
</template>
</div>
Use indexOf() to locate the position of the element you want to replace.
Then use splice() together with the index you got to remove that element.
Then use splice() again to insert a new value to the same index.
Check the documentation of each method above to understand their syntax.
You can try with random numbers if found in first array i.e a
var a = [2,5,6]
var b = [1,2,3,4,5,6,7,8]
a.forEach(function(e){
$("#aDiv").append(`<h2>${e}</h2>`);
})
b.forEach(function(e){
$("#bDiv").append(`<h2 class="seconddiv">${e}</h2>`);
});
$(".seconddiv").on('click',function(){
let val= $(this).html();
if(a.includes(parseInt(val))){
var uniqueNo = 0;
do {
uniqueNo=getRandomInt(0,10);
}
while (a.includes(parseInt(uniqueNo)));
$(this).html(uniqueNo);
}
})
let getRandomInt= (x,y)=>x+(y-x+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0
#aDiv,#bDiv{
color:yellow;
background-color:black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="maindiv">
<div id="aDiv">
</div>
<div id="bDiv" style="margin-top:50px;">
</div>
</div>

Problem with ui-select with multiple and async options

I have a problem with the ui-select directive (AngularJS 1.6.4, Ui-select 0.19.8).
I have created the fiddle here.
It's supposed to show contacts in the dropdown I if type more than 3 chars. (I don't even try to filter anything at the moment, the same list of contacts is returned). It works well the first time, then the other times no dropdown is shown.
I use the async way of returning results so it calls my "refresh" function after 1sec.
Can someone help me understand why no dropdown is displayed after the first time ?
(also, if someone knows why I need to force the display: block for the <ul> tag - cf CSS )
Thanks
HTML
<body ng-app="myApp">
<div body ng-controller="ctrl as ctrl">
<div class="element">
Selected Contacts:<br>
<div ng-repeat="contact in ctrl.contacts" class="contact">
{{ contact }}
</div>
</div>
<ui-select multiple ng-model="ctrl.contacts" class="element">
<ui-select-match placeholder="Pick one...">{{$item}}</ui-select-match>
<ui-select-choices
position="down"
refresh="ctrl.refreshContacts($select.search)"
refresh-delay="1000"
minimum-input-length="3"
repeat="person in ctrl.people">
<div ng-bind-html="person | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<div class="element">
<div ng-repeat="log in ctrl.logs track by $index" >
<div>
{{log}}
</div>
</div>
</div>
</div>
</body>
JS
var myApp = angular.module('myApp', ['ngSanitize','ui.select']);
myApp.controller("ctrl", [function () {
var ctrl = this;
ctrl.logs=[];
ctrl.refreshContacts = function(search) {
var people = [
"mickael",
"pierre",
"anna",
"alice",
"bob"
];
ctrl.people = people;
ctrl.logs.push("refreshContacts called")
}
ctrl.people = [];
}]);
CSS
.element {
margin-bottom: 20px;
}
.contact {
display: inline-block;
margin: 5px;
padding: 5px 8px;
background: grey;
}
/* why do I need this ?! */
.ui-select-choices {
display: block;
}
If I am remembering correctly there is a bug when using both minimum-input-length and refresh. I solved this problem by removing minimum-input-length and adding an if statement inside refresh function.
ctrl.refreshContacts = function(search) {
if(search == undefined || search.length < 3){
return;
}
else{
people = [
"mickael",
"pierre",
"anna",
"alice",
"bob"
];
ctrl.people = people;
}
}

How to change all items values in a document.getClassName call (Without it just using the first elements value)

I'm trying to change the individual product prices on my page, since the encoding is all messed up thanks to the e-commerce platform i use. I'm needing to split on a £ sign, which seems to work well for individual items
I've tried changing the way I do this by using getElementID, but it's no good due to how the e-commerce platform operates, and I can't change any backend stff.
<div class="products-price">
<!--START: ITEMPRICE-->
<span class="subfix">[ITEMPRICE]</span>
<!--END: ITEMPRICE-->
</div>
jQuery(document).ready(function () {
var total = document.getElementsByClassName('subfix')
for (i = 0; i < total.length; i++) {
total[i].textContent.split('£')[1];
}
});
You also have to set the text to that element
jQuery(document).ready(function() {
var total = document.getElementsByClassName('subfix')
for (i = 0; i < total.length; i++) {
total[i].textContent=total[i].textContent.split('£')[1];
}
});
<div class="products-price">
<span class="subfix"> </span>
</div>
If I understand your question correctly you would like to change the price, but the currency symbol is what makes it difficult?
You could acheive it like this:
jQuery(document).ready(function() {
var total = document.getElementsByClassName('subfix')
for (i = 0; i < total.length; i++) {
var price = parseInt(total[i].textContent.split('£')[1])
var newPrice = price + 5;
total[i].textContent = "£" + newPrice;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="products-price">
<span class="subfix">£4</span>
</div>
<div class="products-price">
<span class="subfix">£8</span>
</div>
<div class="products-price">
<span class="subfix">£32</span>
</div>
<div class="products-price">
<span class="subfix">£2</span>
</div>
<div class="products-price">
<span class="subfix">£12</span>
</div>
<div class="products-price">
<span class="subfix">£6</span>
</div>
.split('£').pop();
If you want the last element returned use .pop(), then overwrite the <span> with .textContent in same iteration. .split() can use regular expressions and regex can now match unicode. The following is a regex that matches a standard pound symbol and a full width pound symbol in unicode:
/\u{a3}|\u{ffe1}/u
Demo
var total = document.getElementsByClassName('subfix')
for (i = 0; i < total.length; i++) {
var price = total[i].textContent.split(/\u{a3}|\u{ffe1}/u).pop();
total[i].textContent = price;
console.log(price);
}
span {
display: block;
}
.as-console-wrapper {
width: 50%;
margin-left: 50%;
min-height: 100%;
}
<div class="products-price">
<span class="subfix">£10.00</span>
<span class="subfix">£53.00</span>
<span class="subfix">£101.09</span>
<span class="subfix">£90.01</span>
<span class="subfix">£22.00</span>
<span class="subfix">£18.55</span>
<span class="subfix">£10.20</span>
<span class="subfix">£70.67</span>

Counter if word appears in div [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Take a look at my jsfiddle first.
Now, I want to create a counter everytime Scissor, Rock and Paper appears in the div #myChoice.
I have to do it like this.. so no other ways like on click whatever please.
How to do this?
if "Rock" appears in the div #myChoice
-> Rock Count: 1
-> Paper Count: 0
-> Scissor Count: 0
if "Scissor" appears in the div #myChoice
-> Rock Count: 1
-> Paper Count: 0
-> Scissor Count: 1
if "Rock" appears in the div #myChoice AGAIN
-> Rock Count: 2
-> Paper Count: 0
-> Scissor Count: 1
Thanks for your help & sorry for my latest question that nobody understood lol
Use Event delegation to handle clicks. If the user clicks on an option, then look for an associated count element and update the count. The example below uses .hasClass() to see if the element clicked on has a class name option (added to distinguish the options from other elements), parseInt() to check for a number in the count container and then isNaN() to check if the count number is actually a number (unlike an empty string).
$(document).ready(function() {
$(document).click(function(event) {
if ($(event.target).hasClass('option')) {
$('#myChoice').text(event.target.innerText);
var countElement = $('#' + event.target.id + 'Count');
if (countElement.length) {
var count = parseInt(countElement.text(), 10);
if (isNaN(count)) {
count = 0;
}
countElement.text(++count);
}
}
});
});
#myChoice {
width: 100px;
height: 20px;
border: 1px solid black
}
li {
width: 50px;
border: 1px solid black;
padding: 3px;
margin-bottom: 5px
}
li:hover {
background-color: gainsboro;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<div id="scissor" class="option">Scissor</div>
</li>
<li>
<div id="rock" class="option">Rock</div>
</li>
<li>
<div id="paper" class="option">Paper</div>
</li>
</ul>
<br />
<div id="myChoice">
</div>
<br />
<div id="counter">
<p>Scissor Count:
<span id="scissorCount"></span>
</p>
<p>Rock Count:
<span id="rockCount"></span>
</p>
<p>Paper Count:
<span id="paperCount"></span>
</p>
</div>
Is this what you want ?
var helloLength = $('#container:contains("Hello")').length;
if(helloLength >= 1) {
$("#counter").text("Hello " + helloLength + " times");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"> Hello </div>
<div id="counter"> Hello: /*here the number*/ times </div>
If you want to count the number of hello, you should use class instead of id: like this:
var helloLength = $('.container:contains("Hello")').length;
if(helloLength >= 1) {
$("#counter").text("Hello " + helloLength + " times");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"> Hello </div>
<div class="container"> Hello </div>
<div class="container"> Random div </div>
<div class="container"> Hello </div>
<div class="container"> Hello </div>
<div id="counter"> Hello: /*here the number*/ times </div>
You can achieve this by using a regular expression and the match() method to find the number of occurrences of 'Hello' within your string. From there you can use text() on a span within the #counter element to show the value. Try this:
var re = /hello/gi;
var count = ($('#container').text().match(re) || []).length;
$('#counter .count').text(count);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"> Hello hello </div>
<div id="counter"> Hello: <span class="count"></span> times </div>
I just want to count +1 inside of a div everytime the other div contains the word Hello.
I took this to mean you want to count the number of times the word "Hello" is in the first div, so here's a simple loop to do that.
// create an array out of the text of #container using spaces to delimit
var text = $('#container').text().split(" ");
var count = 0;
// loop through the array of text and check to see if each word is "Hello"
for (var i = 0; i < text.length; i++) {
if (text[i] === "Hello") {
count++;
}
}
$('#counter').text("Hello: " + count + " times");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">Hello Hello Hello Hello</div>
<div id="counter"></div>
You can just use this simple function countWords()
function countWords(str){return (str.match(/Hello/g) || []).length;;}
$('#counterValue').text( countWords($("#container").text()) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="container"> Hello and Hello but Hello is what I'm saying... last Hello!</div>
<div id="counter"> Hello: <span id="counterValue"></span> times </div>

jquery: Count number of words in data attribute

I have some elements with data attribute containing some tags.
I need to count number of each element's tags.
like this:
<div data-tags="foo bar something else">
some text
</div>
<div data-tags="foo bar">
some text
</div>
<div data-tags="foo">
some text
</div>
<div data-tags="">
some text
</div>
and I want to do something like this:
$('div[data-tags]').each(function(){
var tags = $(this).data('tags'),
count = tags.split(' ').length;
$(this).css({marginLeft: (20 * count)});
});
But in this way the count will be 1 for both elements with data-tags="" and data-tags="foo" since the result for split would be like this:
"".split(' '); //[""]
"foo".split(' '); //["foo"]
and length of both of these is 1.
The only way I can think of is to add a condition and do the stuff if the split result was not [""]. But it doesn't look like a good idea. Or not the best at least.
I want to know if anyone has a better idea. thanks.
You can use regexp match instead of simple split:
$('div[data-tags]').css('marginLeft', function() {
var tags = $(this).data('tags');
return (tags.match(/\w+/g) || []).length * 20;
});
Demo: http://jsfiddle.net/dqfx0wun/2/
One way is to use Array.prototype.filter(), and String.prototype.trim(), to remove empty white-space-only array-elements:
$('div[data-tags]').each(function() {
var tags = $(this).data('tags'),
count = tags.split(' ').filter(function (word) {
return word.trim().length;
}).length;
$(this).css({
marginLeft: (20 * count)
});
});
div[data] {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-tags="foo bar something else">
some text
</div>
<div data-tags="foo bar">
some text
</div>
<div data-tags="foo">
some text
</div>
<div data-tags="">
some text
</div>
Or, alternatively, test for the length of the tags variable; zero is a falsey value:
$('div[data-tags]').each(function() {
var tags = $(this).data('tags'),
count = tags.split(' ').length;
$(this).css({
marginLeft: tags.length ? (20 * count) : 0
});
});
div[data] {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-tags="foo bar something else">
some text
</div>
<div data-tags="foo bar">
some text
</div>
<div data-tags="foo">
some text
</div>
<div data-tags="">
some text
</div>
References:
Array.prototype.filter().
String.prototype.trim().

Categories