Angularjs Override ng-show ng-hide on :hover - javascript

I have a series of "icons" that I show in my template.
<div ng-repeat="data in items | orderBy:'-timestamp'">
<div class="icon">
<i>1</i>
<span>2</span>
</div>
</div>
I have the following css to show span when .icon is hovered over and hide i.
.icon:hover i { display: none; }
.icon:hover span { display: block; }
However, I also want to be able to show every single instance of span when $scope.options == true. So I added the following:
<i ng-hide="options">1</i>
<span ng-show="options">2</span>
But now, my :hover is broken and doesn't end up showing the span.
Is there a way to override the ng-show so that my css will still display:block when it is hovered?

plunker
You can skip the css and let angular handle it using ng-mouseenter/ng-mouseleave. Then use an or to have it show when a second variable goes true.
HTML:
<div ng-repeat="data in items | orderBy:'-timestamp'">
<div ng-mouseenter="options=true" ng-mouseleave="options=false" class="icon">
<i ng-hide="options || checkbox">1</i>
<span ng-show="options || checkbox">2</span>
</div>
</div>
<input type='checkbox' ng-model="checkbox" ng-click="options=!options">Show

use the $scope.options value to add a class to your .icon div, then make a more specific CSS rule to overrride the :hover event.
<div class="icon" ng-class="{ override: $scope.options == true }">
<i ng-hide="options">1</i>
<span ng-show="options">2</span>
</div>
And in your CSS:
.icon.override:hover i { display: block; }
.icon.override:hover span { display: block; }

Related

How Do I Get the Selected Value from a Dropdown to Appear at the Top and Replace the Header?

I am using a dropdown for filters and want the selected value from the dropdown to appear at the top so users can see what their selection is when the dropdown closes and they continue browsing.
In this scenario, let's say I select "Option 2", I would want the span section value of "Category" to be replaced by "Option 2". ( I tried using the HTML select and option tags but they just don't work to trigger the filter.)
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: fixed;
width: 50px;
padding: 4px;
z-index: 1;
}
.dropdown:hover .dropdown-content {
display: block;
}
p {
font-size: 16px;
}
<div class="dropdown">
<span>Category</span>
<div class="dropdown-content">
<a href="www.site.com/option1">
<p>Option 1</p>
</a>
<a href="www.site.com/option2">
<p>Option 2</p>
</a>
<a href="www.site.com/option3">
<p>Option 3</p>
</a>
</div>
</div>
Question is taggged [jQuery], therefore, without needing to change the HTML ...
$('a', '.dropdown-content').on('click', function() {
$(this).closest('.dropdown').find('span').text(this.text());
});
This expression will give all similarly constructed dropdowns on the page the required behaviour.
By traversing the DOM from the clicked element to the span element, there's no fear of cross-talk between different dropdowns.
Pretty simple stuff. To make it easier, I would add a class to each of the links and probably one to the span too for good measure. All in all, you would have something that looks like this:
<div class="dropdown">
<span class="selected-category">Category</span>
<div class="dropdown-content">
<a class="dropdown-option" href="www.site.com/option1"><p>Option 1</p></a>
<a class="dropdown-option" href="www.site.com/option2"><p>Option 2</p></a>
<a class="dropdown-option" href="www.site.com/option3"><p>Option 3</p></a>
</div>
</div>
document.querySelector('.dropdown-option').forEach(el => el.onclick = (e) => document.querySelector('.dropdown .selected-category').innerText = e.currentTarget.innerText);
if you can't add a class name, you just need to build a good selector using the element types instead.
const categorySpan = document.querySelector('.dropdown span');
const dropdownItems = document.querySelector('.dropdown div a');
then it's the same thing as with the class.
Edit: Updated based on comments from Heretic Monkey (thanks!)

CSS changing separate elements on hover while all of them are hovered

I was looking for the solution over stackoverflow, but didn't find anything.
I have a set of icons. By default they're grey and only 4 out of 7 are visible.
When I hover on div with icons I want 7 of 7 to be visible and grey.
And while hovering them, I want every separate icon, that is hovered, to be changed with the same icon of different color ( I have 2 different SVGs for every icon - grey and blue one)
.card-list .social span img {
height: 13px;
margin-top: -2px;
}
.card-list .social:hover>.hidden {
display: inline;
}
.card-list .social:hover>.visible {
display: none;
}
.card-list .social .hidden span:hover {}
<div class="align-self-center social col-8 col-md-2 px-0">
<div class="visible mx-0 px-0">
<span class="visible"><img src="images/email-normal.svg"></span>
<span class="visible"><img src="images/telegram_normal.svg"></span>
<span class="visible"><img src="images/twitter_normal.svg"></span>
<span class="visible"><img src="images/facebook-normal.svg"></span>
</div>
<div class="hidden mx-0 px-0">
<span class=""><img src="images/more_normal.svg"></span>
<span class=""><img src="images/email-normal.svg"></span>
<span class=" "><img src="images/telegram_normal.svg"></span>
<span class=""><img src="images/phone-normal.svg"></span>
<span class=""><img src="images/twitter_normal.svg"></span>
<span class=""><img src="images/facebook-normal.svg"></span>
<span class=""><img src="images/bitcoin_normal.svg"></span>
</div>
</div>
So if I write something in the last selector it screws up in html on hover, as I guess one hover overlays other and it goes wild)
Will be happy for any suggestions (JS and JQuery too), because I am a little bit puzzled)
You shouldn't use seperate DIV elements for this. Instead, you can simply use a single div element and show / hide the icons on hover. I don't have your images here, so I'll just use Google's Material Icons to show you an example:
.hidden {
display: none;
}
.icons:hover .hidden{
display: inline;
}
span:hover {
color: red;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class='icons'>
<span><i class="material-icons">accessibility</i></span><br/>
<span><i class="material-icons">face</i></span><br/>
<span class='hidden'><i class="material-icons">android</i></span><br/>
<span class='hidden'><i class="material-icons">autorenew</i></span>
</div>
The span elements with class hidden will be shown when the div is hovered. When you hover an icon, its color will be changed to red. The same idea would apply to your images. Instead of using <img/> elements, use <div/> elements and use CSS to set the image as the background of that div. That will allow you to use CSS to set the background image to another one on hover.

a robust way to toggle item display in Jquery

I want to toggle whether to display an item I should do the following:
$(item).css("display", "none")
$(item).css("display", "block")
But this method is not robust enough, given that the item might be "display: flex" or "display: table".
I think in react, I can just delete that element and re-render it when I need to, but is there any simple way to do that using jQuery besides directly modify the html to delete that element?
Thanks.
you should use toggleClass() in case you are working with flex then it would be a better approach to keep the flex properties in a separate class and add/remove or in easy words toggle the flex class if you want to hide or show that container with defaults set to display:none in a separate class, in this way either the container is flex or table it works either ways see the example below
$(".show").on('click', function() {
if ($(this).siblings('.my-item').css('display') == 'flex') {
$(this).siblings('.my-item').toggleClass('myflex');
} else {
$(this).siblings('.my-item').toggleClass('myTable');
}
})
.my-item {
display: none;
}
.myflex {
display: flex;
background-color: #f8f8f8;
}
.myTable {
display: block;
background-color: #d8d8d8;
}
.container {
margin-top: 10px;
border: 5px dashed #c8c8c8;
}
.show {
padding: 10px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<a class="show">TOGLLE THIS ITEM</a>
<div class="my-item myflex">1
</div>
</div>
<div class="container">
<a class="show">TOGLLE THIS ITEM</a>
<div class="my-item myflex">2
</div>
</div>
<div class="container">
<a class="show">TOGLLE THIS ITEM</a>
<div class="my-item myTable">TABLE DISPLAY
</div>
</div>
<div class="container">
<a class="show">TOGLLE THIS ITEM</a>
<div class="my-item myflex">3
</div>
</div>
<div class="container">
<a class="show">TOGLLE THIS ITEM</a>
<div class="my-item myflex">4
</div>
</div>
<div class="container">
<a class="show">TOGLLE THIS ITEM</a>
<div class="my-item myflex">5
</div>
</div>
You could also add a custom css class and switch them using below. This would also give a bit more control over styling.
$(item).addClass('display-none');
$(item).removeClass('display-none');
$(item).removeClass('display-none display-flex'); // For removing multiple classes
and for example the css properties would be like
.display-none{
display: none !important;
}
Why not just use jQuery's show/hide functions?
$(item).hide();
$(item).show();
hide function is roughly equivalent to calling .css( "display", "none" ), except that the value of the display property is saved in jQuery's data cache so that display can later be restored to its initial value. (from jQuery documentation)
$('#btnToggle').click(function(){
if($('#item').is(':visible'))
{
$('#item').hide();
}
else
{
$('#item').show();
}
$('#log').html("Current display state: " + $('#item').css('display'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btnToggle">toggle</button>
<div id="item" style="display: flex;">
flex div
</div>
<div id="log">
</div>
You can do a
$(item).css("display", "none")
and assign the flex or table value of the display property to any custom attribute, e.g. $(item).attr("disp_prop","flex") and on returning back to display you can do a simple.
$(item).css("display", $(item).attr("disp_prop"))

Change SPAN class with any animation

I have two dimensional array in my controller which I display using this code:
<div class="line"
ng-repeat="line in grid.cells track by $index">
<span class="cell"
ng-class="{c0:(cell==0),c2:(cell==2),c4:(cell==4),c8:(cell==8),c16:(cell==16),c32:(cell==32),c64:(cell==64),c128:(cell==128),c256:(cell==256),c512:(cell==512)}"
ng-repeat="cell in line track by $index">
{{ display_value(cell); }}
</span>
</div>
Here I am changing class of SPAN using ng-class.
Here is a part of CSS:
span.c0 {
background-color: #ccc0b3;
color: #776e65;
}
span.c2 {
background-color: #eee4da;
color: #776e65;
}
User press the button and change the array in the Controller and View is updated automatically: cell value change -> span class change -> color of SPAN change. But this changes are very quickly
How can I use some animation to slow the change in this case? For example, something like this: http://gabrielecirulli.github.io/2048/ . Or some fade-in, fade-out effects. Do I need to use angular's directives or it is the matter of CSS ?
If i understand you right, you will just need css transitions for this.
Here is some example css:
.item
{
transition-property: background-color;
transition-duration: 1s;
}
.item.c1
{
background-color: green;
}
.item.c2
{
background-color: blue;
}
Such HTML:
<div class="row">
<div class="item c1"></div>
<div class="item c1"></div>
<div class="item c1"></div>
<div class="item c1"></div>
</div>
Here is just some sample js to toggle the class change
var elements = document.querySelectorAll(".row .item");
setInterval(function(){
for(var a=0; a<elements.length; a++){
elements[a].classList.toggle("c1");
elements[a].classList.toggle("c2");
}
}, 2500);
And here is a jsFiddle Demo: http://jsfiddle.net/ychk4g7h/

How can I toggle two elements without removing in javascript

I have this html
<div>
<span data-disabled class="myclass"> like </span>
<span class="myclass"> unlike </span>
</div>
scss is like this
myclass{
visibility: visible;
cursor: pointer;
&[data-disabled] {
visibility: hidden;
}
}
and based on click I am doing this
this.select('like').attr('data-disabled', true);
this.select('unlike').removeAttr('data-disabled');
It is working fine but my like and unlike are shown next to each other and they hide and become visible at their original position.
Is there any way to have same position and when I hide and unhide then they overwrite each other.
The problem is with the visibilty property you are using. You have to use display:none so that the item will not consume the space when hidden.
instead of
visibility: hidden;
use
display: none;
You can read more about it here.
Try JQuery Toggle function to achieve this task:
$(function(){
$(".myclass").click(function () {
$(".myclass").toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="myclass"> like </span>
<span class="myclass" style="display:none"> unlike </span>
</div>

Categories

Resources