change text color from directive when innerHTML matches - angularjs

I have a page where I am rendering many columns with the help of the ng-repeat.
HTML
<div ng-repeat="col in selectedColumn" class="cellHldr ng-status-color">{{lead[col.name]}}</div>
Now I have made a directive ngStatusColor
.directive('ngStatusColor', function () {
return {
restrict: "C",
compile: function (tElement, tAttributes) {
return {
post: function postLink( scope, element, attributes ) {
console.log("element",element[0].innerHTML );
if(element[0].innerHTML=='Open'){
console.log("hellooo");
}
}
}
}
}
});
I need to color the text of that column which has the {{lead[col.name]}}like 'open','closed'. Rest should be left as it is

Since you are going the innerHtml way , you can just add a font tag to the inner html to change the color :
if(element[0].innerHTML=='Open'){
element[0].innerHTML="<font color='red'>"+element[0].innerHTML+"</font>";
}
The angular way to do this would be using ng-class.On your div which put the following :
ng-class="{ 'red': lead[col.name]=='Open', blue: lead[col.name]=='close' }"
And create two css classes red and blue:
.red {
color: red;
}
.blue {
color: blue;
}
What this will do this is when it will assign red class to your element if the value of lead[col.name] becomes 'Open' , Blue if 'Close'.
If you want to get more info about ng-class , I would recommend you to go through this link :ng-class uses

Use ng-class for the same.
CSS
.colorChange {
color: green;
}
HTML
<div ng-repeat="col in selectedColumn" class="cellHldr ng-status-color" ng-class="lead[col.name] === 'open' ? 'colorChange': 'normalStyle'">{{lead[col.name]}}</div>
Will this approach work ?

if(element[0].innerHTML=='Open'){
element[0].style.color = "red";
}

Related

Vue - Update rendered elements from a v-for with :style that uses their values [duplicate]

I'm looping through elements and I'm positioning div using top and left CSS properties:
<div
v-for="coord in coords"
:style="{ top: coord.y + 'px', left: coord.x + 'px' }"
></div>
Sometimes instead of top property I need to use bottom (this depends on one of my Vuex store values). How can I dynamically define if I should use top or bottom CSS property?
I tried to used computed prop isTopOrBottom which would return 'top' or 'bottom: :style="{ isTopOrBottom: coord.y + 'px', left: coord.x + 'px' }". But this is not working in Vue.
You can use the ternary operator (in case computed properties are not working)
For example:
<span
class="description"
:class="darkMode ? 'dark-theme' : 'light-theme'"
>
Hope this help.
It should be like JavaScript string concatenation
<div
v-for="coord in coords"
:style="'top: '+coord.y + 'px;left: '+coord.x + 'px'"
></div>
Vue.config.productionTip = false;
Vue.config.devtools=false;
var app = new Vue({
el: '#app',
data:{
coords:[{y:10,x:10},{y:20,x:20},{y:30,x:30}]
}
});
.border-line{
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<div id="app">
<div class="border-line"
v-for="coord in coords"
:style="'margin-top: '+coord.y + 'px;margin-left: '+coord.x + 'px'"
>Test</div>
</div>
You could do something like this:
:class="{ is-top: isTop, is-bottom: isBottom }"
And in your script:
computed() {
isTop() {
// return top condition
},
isBottom() {
// return bottom condition
}
}
Handle css:
.is-top {
...
}
.is-bottom {
...
}
You can also use a Vuejs custom directive for this! https://v2.vuejs.org/v2/guide/custom-directive.html
Check this out:
In your template:
<p v-position="expressionThatMakesItTop" v-if="isSignedIn">Welcome back {{user.email}}</p>
If you want to register a directive locally, components also accept a directives option, check that out on the documentation I linked.
I am going to show you how to do it globally so in your main.js file, before constructing the Vue instance of course:
I left the console.log that displays the objects that you can use in your directive so you can explore them on your console and tailor this to your needs.
Vue.directive("position", {
bind: function(el, binding, vnode) {
console.log(el, binding, vnode);
el.style.left = `${vnode.context.coord.x}px`;
if (binding.value) {
el.style.top = `${vnode.context.coord.y}px`;
return;
}
el.style.bottom = `${vnode.context.coord.y}px`;
}
});

Apply style conditionally on a React component with json-style definitions

I have a component where style is applied in form of json and I need to override styles conditionally.
See style definitions:
const classes = {
txt: {
color: 'green',
...
},
txtBlue:{
color: 'blue',
..
},
};
See template:
<div style={classes.txt + (this.state.goBlue ? classes.txtBlue)}></div>
The + (this.state.goBlue ? classes.txtBlue) I have written above is not working and it is just to show what I need to understand and make work.
When this.state.goBlue is true, I want both classes.txt and classes.txtBlue to apply to the div.
Thanks
You didn't use the ternary operator correctly, you can do something like this:
<div style={ this.state.goBlue ? { ...classes.txt, ...classes.txtBlue } : classes.txt }></div>
This will apply both styles if this.state.goBlue is truthy, otherwise it will only apply classes.txt.
Found the solution!
By adding this to the render() function:
const txtStyle =
this.state.goBlue ?
Object.assign({}, classes.txt, classes.txtBlue) :
Object.assign({}, classes.txt);
And this to the template:
<div style={txtStyle}></div>
I was able to achieve what I wanted.

ng-repeat active class with different style

I am creating a list of offers with ng-repeat. Depending of each offer status, they should have different colors and, when active, it should have a different specific status as well. The active logic works well, but what is happening now, is that they all render as true, so they're all the same color. Feel free if you have any other ideas of doing this.
This is what I see when I inspect, after it renders:
ng-class="{'offer card-active-false card row text-left': currentOfferId === offer.id, 'offer card card-false row text-left': currentOfferId !== offer.id}" class="offer card card-true row text-left"
Here is what I have on HTML:
<div ng-repeat="offer in $parent.offersList track by $index">
<button ng-click="$ctrl.setCurrentOffer(offer)">
<div ng-if="" ng-class="{'offer card-active-{{offer.status}} card row text-left': currentOfferId === offer.id, 'offer card card-{{offer.status}} row text-left': currentOfferId !== offer.id}">
//then I have my divs
</div>
</button>
</div>
CCS:
.card-true {
background-color: #00FF44;
}
.card-false {
background-color: #C4C4CC;
}
.card- {
background-color: yellow;
}
.card-active-true {
background-color: #fff!important;
border-color: #00FF44;
}
.card-active-false {
background-color: #fff!important;
border-color: gray;
}
.card-active- {
background-color: #fff!important;
border-color: yellow;
}
thanks!
Put classes that always need to be present in a normal class attribute.
Then simplify the classes you need and separate them so you don't have to over-complicate the logic. My suggestions may be off, but it should look something like this:
card-status-... - driven by offer.status
card-active - driven by `currentOfferId === offer.id'
Then you could easily put the logic in ngClass, which lets you specify an array whose members can be strings that represent class names or objects whose keys are class names and whose boolean values indicate whether the class should be included. Like so:
<div class="offer card row text-left"
ng-class="[
'card-status-' + offer.status,
{'card-active' : currentOfferId === offer.id}
]">
Now in your CSS you can set up those classes by combining selectors:
.card {
background-color: yellow;
}
.card-status-true {
background-color: #00FF44;
}
.card-status-false {
background-color: #C4C4CC;
}
.card.card-active {
background-color: #fff !important;
border-color: yellow;
}
.card.card-active.card-status-true {
background-color: #fff !important;
border-color: #00FF44;
}
.card.card-active.card-status-false {
background-color: #fff !important;
border-color: gray;
}
Here is my solution, remove the complicated logic, which is obviously not binding properly inside the ng-class, it will only confuse and its not worth the time.
Note: I have used $scope variables instead of this, please use the GIST of the JSFiddle I'm sharing and try to build your code, I am unsure of the color requirements, please check and tell me if the code resolves your issue.
JSFiddle Demo
CODE:
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
$scope.offersList = [{id:1, status: false}, {id:2, status: false}, {id:3, status: false}, {id:4, status: false}];
$scope.currentOfferId = 0;
$scope.setCurrentOffer=function(index){
$scope.currentOfferId = $scope.offersList[index].id;
$scope.offersList[index].status = !$scope.offersList[index].status;
}
$scope.filterClass = function(offer){
var bool = offer.status ? 'true' : 'false';
if($scope.currentOfferId === offer.id){
return 'offer card-active-'+bool;
}else{
return 'offer card card-'+bool;
}
}
});
It's not completely clear which classes you want applied to which situation. You need to hand ng-class an array with each separate condition, this was probably the root of your problem.
You can also use ternary for this (angular v.1.1.4+ introduced support for ternary operator) which makes things look a little neater:
<div ng-class="[offer.id ===currentOfferId ? 'card-active-true' : 'card-active-false',
offer.status ? 'card-active-true' : 'card-false' ]"
class="offer card row text-left" >

ExtJS FontAwesome change Glyph Color

I just added FontAwesome to my ExtJS application.
I added a Glyph to my tab:
items: [
{
title: 'Dashboard',
glyph: 0xf009,
padding: '5',
I would like to change the Glyph color, is that possible?
This should work:
.x-panel-header .x-panel-header-glyph {
opacity: 1;
color: red;
}
You can see it in action here: http://extjs.eu/examples/#complex-data-binding
I tried the Saki way
.x-panel-header .x-panel-header-glyph {
opacity: 1;
color: red; }
but then you don't have the control to change attributes for specific glyph and if I want to set it for individual glyph I will need to work harder.
I use a simple way:
Step 1: add a link to the css file
link rel="stylesheet"
href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"
Step: 2:
use iconCls
iconCls: "fa fa-lg fa-futbol-o glyph"
here I used the awesome classes "fa fa-lg-fa-futbol-o" but I added "glyph" so it will looks better than without.
Step 3:
define "glyph" in your css file.
.glyph { margin-top: 3px; }
Step 4:
define any css you can apply to the glyph like color.
The result:
in css file:
.glyph { margin-top: 3px; }
.youname { color: #15498B; }
in js ( every where you have config iconCls )
iconCls: "fa fa-lg fa-futbol-o glyph youname"
I know this is a little late but for anyone else in the future who wants change Glyph icons when using custom fonts with Exts.
I used the reference to the button in my controller passed in during the event. I then got the buttons ID then target the button using the get method and concatenating "-btnIconEl" to the the button ID as any glyph/icon will have that CSS.
'button[action=displayGrids]' : {
click: function(button) {
Ext.get(button.id + '-btnIconEl').setStyle('color', '#ffffff');
}
}

angularjs bootstrap collapse horizontally

How can I make angular bootstrap collapse, collapsing horizontally?
Something like here?
You are going to need to either modify the collapse directive or create a new directive based on that to handle collapsing the width only. I would suggest the latter unless you want all of the collapse directives in your app to collapse horizontally.
Please see the Plunk here demonstrating the use of a collapse-with directive based on the bootstrap collapse directive.
On top of changing the directive you will need to add new classes to handle the transition and set a width for the element you want to collapse (you could also change the directive to collapse to and from 100% width, not sure on your use case but hopefully you get the idea):
.well {
width: 400px;
}
.collapsing-width {
position: relative;
overflow: hidden;
-webkit-transition: width 0.35s ease;
-moz-transition: width 0.35s ease;
-o-transition: width 0.35s ease;
transition: width 0.35s ease;
}
And the directive just requires a few changes to the expand, expandDone, collapse and collapseDone functions and adding/removing the css class above as follows:
.directive('collapseWidth', ['$transition', function ($transition, $timeout) {
return {
link: function (scope, element, attrs) {
var initialAnimSkip = true;
var currentTransition;
function doTransition(change) {
var newTransition = $transition(element, change);
if (currentTransition) {
currentTransition.cancel();
}
currentTransition = newTransition;
newTransition.then(newTransitionDone, newTransitionDone);
return newTransition;
function newTransitionDone() {
// Make sure it's this transition, otherwise, leave it alone.
if (currentTransition === newTransition) {
currentTransition = undefined;
}
}
}
function expand() {
if (initialAnimSkip) {
initialAnimSkip = false;
expandDone();
} else {
element.removeClass('collapse').addClass('collapsing-width');
doTransition({ width: element[0].scrollWidth + 'px' }).then(expandDone);
}
}
function expandDone() {
element.removeClass('collapsing-width');
element.addClass('collapse in');
element.css({width: 'auto'});
}
function collapse() {
if (initialAnimSkip) {
initialAnimSkip = false;
collapseDone();
element.css({width: 0});
} else {
// CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
element.css({ width: element[0].scrollWidth + 'px' });
//trigger reflow so a browser realizes that height was updated from auto to a specific value
var x = element[0].offsetHeight;
element.removeClass('collapse in').addClass('collapsing-width');
doTransition({ width: 0 }).then(collapseDone);
}
}
function collapseDone() {
element.removeClass('collapsing-width');
element.addClass('collapse');
}
scope.$watch(attrs.collapseWidth, function (shouldCollapse) {
if (shouldCollapse) {
collapse();
} else {
expand();
}
});
}
};
}]);
You may need to tweak the css a little to ensure the spacing and margins are consistent with your use cases but hopefully that helps.

Resources