Angular get current focused element in angular - css

I have a website I am trying to do something like this, when I click on 1, I want the background of this element to change to white and when I click on the second one the background of the first one will disappear and pass to the next one...I have been trying to do this for a long time help me I don't know how to do it
<div class="oval">1</div>
<div class="oval">2</div>
<div class="oval">3</div>

When we need make "something" exclusive we use one unique variable
selectedIndex:number=-1
If you want not unselected
<div class="oval" [class.selected]="selectedIndex==0"
(click)="selectedIndex=0">
1
</div>
<div class="oval" [class.selected]="selectedIndex==1"
(click)="selectedIndex=1">
2
</div>
<div class="oval" [class.selected]="selectedIndex==2"
(click)="selectedIndex=2">
3
</div>
If you want unselected
<div class="oval" [class.selected]="selectedIndex==0"
(click)="selectedIndex=selectedIndex==0?-1:0">
1
</div>
<div class="oval" [class.selected]="selectedIndex==1"
(click)="selectedIndex=selectedIndex==1?-1:1">
2
</div>
<div class="oval" [class.selected]="selectedIndex==2"
(click)="selectedIndex=selectedIndex==2?-1:2">
3
</div>
NOTE: I use [class.selected], so we use a .css
.selected{
background:red;
}
You can use style.background or style.background-color using (condition)?value:null, e.g., for the first div
[style.background]="selectedIndex==0?'red':null

Like #Kwright02's comment you can do it with css:
.myclass:focus {
background-color: green;
}
But important: The element must be focusable. So a div isn't, a button is as example.
Second way (add a click handler and change the background directly):
// HTML
<div (click)="onClick($event)">test</div>
// Code
onClick(event: any) {
event.target.style["background-color"] = "green";
}
Note: This is not the way to go in Angular. Here use property binding and bind a style to a condition as example.
Instead of add a click listener to each control you can use Angular's HostListener like this:
#HostListener("document:click", ["$event"])
onAllClick(event: any) {
event.target.style["background-color"] = "green";
}

Related

Flex Row with Expansion Panel spacing issue

I am having a problem with the spacing of expansionpanels inside a flex row
I have multiple Mat-Expansion-Panel inside an ngFor inside there are multiple items, and every panel has different item length.
Now when I expand one panel, the one beside it will also expand to the same height but without showing the item (since its not really expanded)
I have created a stackblitz: https://stackblitz.com/edit/mat-expansion-panel-x8qz9z
Since my panellist is a seperate component and is used multiple times with different layout, do I really need to make 2 seperate columns inside the *ngFor to make this work?
Edit1: I have tried height:max-content on the mat-expansion-panel but the problem is panel 3 should move up under panel one.
The same problem exists for align-items:baseline; on the container
Kind regards
It can only be done with 2 separate columns. You can split your array into two columns, or however many you may need like this:
columns = [
this.panels.slice(0, Math.ceil(this.panels.length / 2)),
this.panels.slice(Math.ceil(this.panels.length / 2))
];
You can use this array in your template:
<div class="panel-container">
<div class="panel-column" *ngFor="let columnPanels of columns">
<mat-expansion-panel class="panel" *ngFor="let panel of columnPanels">
<mat-expansion-panel-header>
{{panel.name}}
</mat-expansion-panel-header>
<div *ngFor="let item of panel.items">{{item}}</div>
</mat-expansion-panel>
</div>
</div>
And update your css:
.panel-container {
display:flex;
flex-direction:row;
}
.panel-column {
flex: 1;
}
.panel {
margin: 10px;
height: max-content;
}
stack

ng-show with $state.includes has blink/flickering - angular; ui-router

As described here How to ng-hide and ng-show views using angular ui router, I have the following markup:
<div class='container'>
<div ng-show='$state.includes('state1')></div>
<div ng-show='$state.includes('state2')></div>
</div>
Using flex-box in css:
.container {
display: flex;
flex-direction: column;
}
Now it when I switch between the two states both divs are displayed for a blink of an eye resulting in an ugly blink effect.
I tried ng-cloak from Angularjs - ng-cloak/ng-show elements blink, but without any success.
I can't use ng-if since I use 'Sticky State' from ui-router-extras, which requires the DOM to persist.
$state won't be available to use in HTML so
1) you can do something like this in Ctrl
$scope.state = $state;
but i won't recommend this
2) In HTML
<div class='container'>
<div ng-show="showThis('state1')"></div>
<div ng-show="showThis('state2')"></div>
</div>
In Controller
$scope.showThis = function(type){
return $state.includes(type);
}
Even though you already mentioned that you have tried ng-cloak, I think that the right answer to your issue is indeed ng-cloak with the:
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}
style configuration. I have made an example on CodePen.io that show exaclty this solution working with Angular UI Router. As you can see in the example, the whole view blinks as you mentioned but, if you add the 'ng-cloak' directive to the:
<div ng-app="myApp">
which will then become:
<div ng-app="myApp" ng-cloak>
you will see that Angular protects the view from being showed (blinking). And that is exactly the purpose of the of the 'ng-cloak' directive.
Hope this example help you solving you issue.
You can use ng-style to remove the flicker effect.
<div class='container'>
<div ng-style="{'display': $state.includes('state1') ? 'block' : 'none'}"></div>
<div ng-style="{'display': $state.includes('state2') ? 'block' : 'none'}"></div>
</div>
I'm not sure why ng-show triggers a flicker effect with sticky states, but this workaround fixes the issue.

select elements which have a special css attribute with jquery

I have the following structure:
<div class="main">
<div class="submain">
.....
<div class="sub..submain">
</div>
.....
</div>
<div class="submain">
</div>
</div>
Some of the subelements have the css property float:right;, and I dont know how many levels there are.
How can I select all elements with this css property using the selector $('.main')?
I have an idea, but I am trying to find an easier way to do it:
var elemsArray=[];
function findNeededChildren(elem){
var hasChildren = elem.children().length>0?true:false;
if(hasChildren ){
$.each(elem.children(),function(){
if($(this).css('float')=='right')elemsArray.push($(this));
findNeededChildren($(this));
});
}
}
findNeededChildren($('.main'));
You can select elements by an attribute, so you could try
$('div[style="float:right"]')
This should select all the divs with that attribute. But I am not sure if it will also select something with more than this one style.
Edit:
I just remembered that some people here where I work use classes for this sort of thing. It makes maintainability easier. Make a css rule that says:
.floatRight {
float:right
}
Then just assign this class to everything that needs floating. These should be even easier to select.
You can do something like
$(document).ready(function(){
$(".main").find("div").each(function(){
if($(this).css("float") == "right") {
// This is the required div
}
});
})
And if you don't know that children of .main are divs or other tags then use
$(document).ready(function(){
$(".main").children().each(function(){
if($(this).css("float") == "right") {
// This is the required element with float: right property
}
});
})

select all ids where the only difference is the number in the ID name

I have all these divs with an identical ID name except for the fact that they all have a different number at the end.
I know I can use a class but it must be an ID.
<div id="myid1">text</div>
<div id="myid2">text</div>
<div id="myid3">text</div>
<div id="myid4">text</div>
<div id="test1">text</div>
<div id="test2">text</div>
My question is using css how can I select them all but shorter than this .
#myid1,#myid2,#myid3,#myid4{
color:red;
}
Does this type of thing exist and if so how do you write it?
myid1[*]{
color:red;
}
Just use the prefix attribute selector
[id^="myid"] {
}
This selector targets any element with an ID attribute that has the prefix "myid" - quotes around the value are optional. This selector works in IE7 & above as well.
you can use begins with this attr selector.
[id^=myid] {
color:red;
}
DEMO
CSS3 should help here:
div[id^="myid"]
AND
div[id^="test"]
Yes, there's a way
<div id="myid1" class="foo">text</div>
<div id="myid2" class="foo">text</div>
<div id="myid3" class="foo">text</div>
<div id="myid4" class="foo">text</div>
<div id="test1">text</div>
<div id="test2">text</div>
and css
.foo { color:red; }
UPDATE
If those have to be IDs, try with [id^=myid]
I think it would work a lot better for you to use classes as incremental ids goes against HTML and general programming principles. You could rewrite it like so:
<div class="myid" data-id="1">text</div>
<div class="myid" data-id="2">text</div>
However, if you must keep the ids as they are, you can use the attribute selector:
[id^=myid] {
color: red;
}
In your case this would do it:
[id=^"myid"] {
//your rules
}
That selects all elements whose id attribute begins with "myid".
You're not limited to the id attribute though. In fact, you could use any other html element's attribute.
Let's say you wanted to select all <a> tags whose "href" attribute begun with "http://stackoverflow.com". The following would do it:
a[href=^"http://stackoverflow.com"] {}
There's really a ton of options. Instead of pointing them out myself I'll you link to the w3 page where all of it is detailed: http://www.w3.org/TR/selectors/#attribute-selectors
use classes in addition to the ids (if you really need the ids):
<div class="mytext" id="myid1">text</div>
<div class="mytext" id="myid2">text</div>
<div class="mytext" id="myid3">text</div>
<div class="mytext" id="myid4">text</div>
<div id="test1">text</div>
<div id="test2">text</div>
then the CSS is simple:
div.mytext {
color: red;
}

If condition , in case id="prog_bg" is present then execute the remaining code

I want to put an if condition, when id="prog_bg" or class="progress_box_bg" is present then execute the remaining code. DOM is as below,
<div id="wizard">
<div class="quote_header">
<div class="items">
<div id="top-line" style="display: block;">
<div class="back_box">
<div class="progress_box">
<div id="prog_bg" class="progress_box_bg" style="width: 75px;"></div>
</div>
</div>
<div id="service-div" class="page" style="padding-top:45px; >">
<div id="propertytype-div" class="page">
I tried with lots of option but it won't work . Guys let me know how do it?
if (var.equals(driver.findElement(By.tagName("body")).getText().contains("prog_bg")))
try { if (selenium.getHtmlSource().matches("^[\\s\\S]*prog_bg[\\s\\S]*$")) break; } catch (Exception e) {};
if(driver.getPageSource().matches("^[\\s\\S]*prog_bg[\\s\\S]*$"))
if(driver.findElement(By.id("prog_bg")).isDisplayed())
if (driver.findElement(By.className("progress_box_bg")).isDisplayed())
Thanks,
Sachin
You could also try something like this.
// Find element by id
boolean isElementPresent = driver.findElement(By.id("prog_id"));
// Find element by class
boolean isElementPresent = driver.findElement(By.className("progress_box_bg"));
//This writes out an errormessage if isElementPresent equals false, good for reports!
Assert.assertTrue("Could not find the element", isElementPresent);
Could you try something like this? You can replace Assert with if()
boolean ispresent= driver.findElement(By.cssSelector("BODY")).getText().matches("^[\\s\\S]*prog_bg:[\\s\\S]*$");//TODO: Make this dynamic
Assert.assertEquals(true, ispresent);
boolean ispresent= driver.findElement(By.id("prog_id"))
Assert.assertEquals(true, ispresent);
Numbers 4 and 5 are on the right track. However, you should not be calling isDisplayed() if you just want to check its presence in the DOM. isDisplayed() checks the element presence in the DOM and then checks to see if the element is visible to the user.
Instead, you should just try to find the element itself:
if(driver.findElement(By.id("prog_bg")) || driver.findElement(By.className("progress_box_bg")) {
/*Execute code here*/
}
Also, please note that element attributes do not appear in the text of the page's body, the only appear in the DOM. Any attempts to find these elements like you do in numbers 1, 2, and 3 are completely futile.

Resources