Add Trailing Ellipsis To Breadcrumb Depending On Device Width - javascript

On my user interface I have a breadcrumb of which shows on the top bar. Upon the device width being below a defined width, it'll drop below the top bar and be it's own bar, however what I do not know how to do is add a trailing ellipsis upon the breadcrumb length being larger than the device width.
Example Breadcrumb:
<nav>
<ul>
<li>Home</li>
<li>>></li>
<li>User</li>
<li>>></li>
<li>Inbox</li>
<li>>></li>
<li>Mail_ID</li>
</ul>
</nav>
Note: >> represents a FontAwesome icon in an i tag
Upon the breadcrumb being larger than the device width, the best I can describe what I would like to happen is demonstrated below:
Home >> User >> Inbox >> Mail_ID
... User >> Inbox >> Mail_ID
... Inbox >> Mail_ID
... Mail_ID

This is still a partial code but might help you.
Idea
On load, call a function that checks for with of ul and its parent container.
If ul has greater width, hide first 2 visible li. Also add an li for ellipsis and make it hidden initially and make it visible only if any of other divs are hidden.
Repeat this process recursively and you will get what you are looking for.
Sample
$(function() {
$(".content").resizable();
$(".content").on("resize", function() {
var ul = $(this).find('ul');
if (ul.width() > $(this).width()) {
var lis = ul.find('li:not(.hide):not(.ellipsis)');
for (var i = 0; i < 2; i++) {
$(lis[i]).addClass("hide");
}
if ($(".ellipsis").not(":visible"))
$(".ellipsis").removeClass("hide")
}
})
});
.content {
text-align: left;
border: 1px solid gray;
width: 300px;
height: 40px;
max-height: 40px;
}
.content ul {
padding: 0px;
position: fixed;
overflow: hidden;
white-space: nowrap;
}
.content ul li {
display: inline-block;
text-decoration: none;
}
.hide {
display: none!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="content">
<ul>
<li class="hide ellipsis">...</li>
<li>Home</li>
<li>>></li>
<li>User</li>
<li>>></li>
<li>Inbox</li>
<li>>></li>
<li>Mail_ID</li>
</ul>
</div>

You can try to use the CSS-only ellipsis, but I don't know if it also works with <ul><li>. For sure it works with simple strings:
Use this HTML:
<ul class="ellipsis">
And this CSS:
ul.ellipsis
{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

Related

Converting tabs into dropdown menu (not select)

I am currently using Bootstrap to create tabs and the task is for mobile screen (800px <), it should automatically change into a "fake" dropdown. When i say fake, i mean no select box but utilising the the same ul as the tabs, it should automatically use the first item as a trigger.
I can get the tabs working fine: https://codepen.io/wizly/pen/BlKxo
What do i want to achieve?
On mobile view, when the tabs are in more of a dropdown format, i want to try and get the label for the active tab right at the top of the list.
Scenario: Mobile View Default
[ITEM 1 active >]
Scenario: Mobile view Clicked
[ITEM 1]
[ITEM 2]
[ITEM 3]
Scenario: Mobile view item 3 clicked
[ITEM 3 active >]
Scenario: Mobile view item 3 active clicked
[ITEM 1]
[ITEM 2]
[ITEM 3]
Where am i so far:
$('li a').on('click', function() {
const current = $(this);
const ul = current.parent().parent();
const li = current.parent();
if ($(window).width() < 1023.98) {
ul.toggleClass('expanded');
$('li').removeClass('active');
$('.fake-active').removeClass('fake-active');
if (ul.hasClass('expanded')) {
$('li').removeClass('active');
current.addClass('fake-active');
}
li.toggleClass('active');
// ul.prepend(current.parent());
}
});
#charset "UTF-8";
body {
padding: 10px;
}
#exTab2 h3 {
color: white;
background-color: #428bca;
padding: 5px 15px;
}
#media screen and (max-width: 800px) {
ul li {
display: block !important;
float: none !important;
}
ul li:first-child a {
text-align: left !important;
}
ul li:first-child a:after {
font-family: fontello;
content: "";
font-size: 1em;
font-weight: 400;
font-style: normal;
font-variant: normal;
line-height: 1;
min-width: 1em;
margin-left: 1em;
text-decoration: inherit;
text-transform: none;
float: right;
transform: rotate(90deg);
}
ul li:not(:first-child) {
display: none !important;
}
ul.expanded li:not(:first-child) {
display: block !important;
}
ul.expanded li:not(:first-child) a {
text-align: left !important;
}
ul.expanded li:first-child a:after {
content: "";
transform: rotate(270deg);
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/>
<div id="exTab2" class="container">
<ul class="nav nav-tabs">
<li class="active">
Overview
</li>
<li>Without clearfix
</li>
<li>Solution
</li>
</ul>
<div class="tab-content ">
<div class="tab-pane active" id="1">
<h3>Standard tab panel created on bootstrap using nav-tabs</h3>
</div>
<div class="tab-pane" id="2">
<h3>Notice the gap between the content and tab after applying a background color</h3>
</div>
<div class="tab-pane" id="3">
<h3>add clearfix to tab-content (see the css)</h3>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
I know it might be too late...
based on your source code, i used .active instead of :first-child for css selector and changed JS a little, and it seems work properly.
here's the codepen https://codepen.io/lebniz/pen/zYdLXxJ
js:
$("li a").on("click", function () {
const current = $(this);
const ul = current.parent().parent();
let tab_id = current.attr("href");
if ($(window).width() < 1023.98) {
$(tab_id).addClass("active").siblings().removeClass("active");
ul.toggleClass("expanded");
}
});

On button click show information sliding up and pushing the button upwards using jQuery

I have a foreach loop which displays a list of items using relative and absolute positioning, and on the bottom I would like to add a button (which is at the bottom of the container), which when pressed, shows/hides the given information, pushing the button with itself. I've looked at a couple of stackoverflow questions which had basically the same problem, but I couldn't find a solution which would work in my case.
Here are the codes for the problem (since I've tried a couple solutions, the style positions might not be logical, if you see anything weird please let me know):
The view:
<ul class="events>
#foreach (var events in Model)
{
//absolute positioned div-s
<li>
<div class="eventActions">
<button class="toggleBet">Place bet</button>
#Html.ActionLink("Event details", "Details", "Event", new { eventId = events.Id }, null)
<div class="betContent">#Html.Partial("_BetPartial", new BetViewModel(events))</div>
</div>
</li>
</ul>
The styles:
.events > li .eventActions {
position: absolute;
bottom: 0;
right: 0;
font-size: 24px;
height: 200px;
}
.events > li .toggleBet {
display: inline-block;
}
.events > li .betContent {
background-color: green;
margin: 0;
max-height: 0;
overflow: hidden;
transition: max-height 1s;
}
.events > li .eventActions.open .betContent {
max-height: 300px;
}
The jQuery:
$(".toggleBet").on("click",function(e) {
$(this.parentNode).toggleClass("open");
});
Here is a fiddle which shows what I would like to achieve: http://jsfiddle.net/yeyene/fpPJz/3/ (credits to user yeyene, from this question)
And here is the picture of my project so far (I would like to extend the list items height, move the links lower and make them move up when clicked)
Thank you in advance!
I would suggest forgetting about the .slideToggle method and just using a CSS class on the parent container, then use the max-height property to toggle between open and closed (or just height if you already know exactly how big the container should be when opened).
Here's a simple fiddle showing how you can do this with "pure" CSS by just adding a class to a container: https://jsfiddle.net/8ea3drce/
For good measure, below is the code used in the above JS fiddle:
HTML
<div class="container">
<a class="trigger">Trigger</a>
<ol class="content">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ol>
</div>
CSS
.container {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.container .trigger {
display: inline-block;
background-color: red;
color: white;
cursor: pointer;
padding: 1em;
}
.container .content {
background-color: lightblue;
margin: 0;
max-height: 0; // This suppresses the element's height.
overflow: hidden; // This keeps internal elements from being visible when height is suppressed.
transition: max-height .5s; // This animates the motion when max-height is released. This isn't usually perfect. The closer max-height comes to be with the actual height of the element, the better. Fixed heights might be ideal.
}
.container.open .content {
max-height: 300px; // This releases the element's height to be as large as it would naturally be, up to 500px.
}
Javascript/jQuery
$('.trigger').on('click', function(e) {
$(this.parentNode).toggleClass('open');
})
Using the idea of classtoggling as shown in Dom's answer, setting the absolute position's anchors correctly and deleting the interfering height attribute solved the problem!

Center any element on a sliding horizontal line

I have a horizontally sliding line of elements within a fixed width, so you have to scroll left an right to see all the elements. See JS Fiddle and text-only example below.
Hi | Hello | How do you do | Fine thanks | Good weather this time of year
My question is: How can I center any given element horizonally? Eg. Put the horizontal center of element number 3 in the horizontal center of the surrounding div.
If the element can't be centered because it is at the beginning of the line for example, that's OK, then the H-position should simply be 0. It should only be centered as much as it can be.
So something like this? You can use a combination of the following native properties scrollLeft, offsetLeft, and offsetWidth.
var items = document.querySelectorAll('.wrapper ul li');
function centerItems(which) {
var wrapper = items[which].offsetParent;
wrapper.scrollLeft =
(items[which].offsetLeft + items[which].offsetWidth / 2)
- wrapper.offsetWidth / 2;
}
html {
background: #eee;
}
body {
width: 320px;
background: white;
font-family: sans-serif;
}
.wrapper {
overflow-x: scroll;
position: relative;
}
ul {
white-space: nowrap;
}
li {
display: inline-block;
color: #898;
background: #efe;
padding: 8px;
}
<p>Hello!</p>
<button onclick="centerItems(0)">1</button>
<button onclick="centerItems(1)">2</button>
<button onclick="centerItems(2)">3</button>
<button onclick="centerItems(3)">4</button>
<button onclick="centerItems(4)">5</button>
<div class="wrapper">
<ul>
<li>Short</li>
<li>Very long line here</li>
<li>Medium line</li>
<li>Another one Another one Another one</li>
<li>Yet another</li>
</ul>
</div>
<p>Goodbye!</p>

Multiple images depending on mouse location when hovering over div

I am trying to do an overview page on my website so that when I hover over a div on the overview page different sections of that div show different images. Essentially a slideshow but the image changes depending on where the cursor is.
I have managed to find some code that does what I want but it uses an a href to pull in the images which means if you click it, it goes to the link of the image.
Currently I just have placeholder images in but when finished each one will have specific project images in. As each div will just be one project the whole div should go to one html link and not just a specific image link of the image the user is hovering over.
All I want is the user to click and it go to a html link and not an img link.
Here is the code I am using:
The coding savvy people out there will probably have a much better solution for what I would like to achieve, I am interested to see any better solutions.
HTML
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="imgcontent">
<ul class="rotator-icons fifth">
<span class="img1 active"></span>
<span class="img2"></span>
<span class="img3"></span>
<span class="img4"></span>
<span class="img5"></span>
</ul>
<img src="/img/FoI.jpg" class="currentimg">
</div>
</div>
CSS
.multi {
display: block;
float:left;
position: relative;
width: 30.8%;
height: 20%;
padding: 0px;
margin:0% 1% 2% 1%;
overflow: hidden;
}
.multi .imgcontent {
display: block;
position: absolute;
top: 0px;
}
.imgcontent img {
display:block;
width: 100%;
height: auto;
margin-left: auto;
margin-right: auto;
}
.rotator-nav {
display: block;
position: relative;
width: 100%;
height: 100%;
z-index: 9;
}
.rotator-nav li {
display: block;
float: left;
height: 100%;
}
.rotator-nav.fourth li {
width: 25%;
}
.rotator-nav.fifth li {
width: 20%;
}
.rotator-nav li a {
display: block;
float: left;
width: 100%;
height: 100%;
border-bottom:0px solid #fff
}
.clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }
.clearfix { display: inline-block; }
html[xmlns] .clearfix { display: block; }
* html .clearfix { height: 1%; }
JS
$(function(){
var $rotators = $('.multi');
var $imglinks = $('.rotator-nav a');
$imglinks.on('mouseenter', function(e){
var imgclass = '.'+$(this).attr('class');
var imglink = $(this).attr('href');
// update main image src
$(this).parent().parent().parent().find('.currentimg').attr('src',imglink);
// update current rotator icon
var $rotators = $(this).parent().parent().parent().find('.rotator-icons');
if($rotators.children(imgclass).hasClass('active')) {
// already active icon -- do nothing
} else {
// remove active class then add to new icon
$rotators.children('span').removeClass('active');
$rotators.children(imgclass).addClass('active');
}
});
});
Any help would be greatly appreciated!
Thanks,
Mark
I think you could best use a data attribute for this instead (if I understand the intention correctly) :
var imglink = $(this).data('image');
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li>
<a data-image="/img/FoI.jpg" href="#" class="img1"></a>
</li>
<li>
<a data-image="/images/card.jpg" href="#" class="img2"></a>
</li>
<li>
<a data-image="/images/amareal.jpg" href="#" class="img3"></a>
</li>
<li>
<a data-image="/images/edeva.jpg" href="#" class="img4"></a>
</li>
<li>
<a data-image="/images/amacover2.gif" href="#" class="img5"></a>
</li>
</ul>
...
If you'd still like to see the image over the original div, a pseudo element could be used. Advantage there is that they are not actual DOM elements and will not register clicks :
Demo
Now it would be great if the data attribute could be directly used for the content of the pseudo element as well but that doesn't seem possible. And you can't target them with JavaScript so each image would have to be defined with nth-of-type() in the stylesheet additionally.
You don't need to use .parent().parent()
Just use the parent's class to find the item.
Your $(this).parent() * 3 is the $(".multi")
So your $rotators can't find .rotator-icons,
you need to use one more parent or use siblings
And I suggest do not use class if there are no need to do one thing to lots of items.

How to stick two unrelated elements together?

I'm working on an interface and I require something that would stick two unrelated elements together. Well, the most important element will be the "boss" and the other element called "employee" will follow the "boss" around and will change it's position accordingly.
This is the markup:
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
This is the jQuery I wrote:
$('.boss').each(function( i, obj ){
var Pos = $(this).position();
var ModuleWidth = $(this).outerWidth();
$(this).next('.employee').position({
my: 'right top',
at: 'right top',
of: $(this)
});
});
So I'm iterating through all the .boss classes and aligning all .employees to the right top of boss. They are supposed to always stick. But if I edit the html from the boss within chrome Developer Tools the .boss element will become smaller and larger and the .employee will not re-position its self accordingly. I would like to make .employee always reposition its self.
Later Update:
This http://screencast.com/t/F0RO7ODF is the kind of behavior i'm looking for. The gray box is the BOSS and the orange box is the EMPLOYEE. These 2 element's have a wrapper and i'm actually moving the wrapper. But i'd like a solution without a wrapper. Note: The organge box's position is irelevant.
I know this has been answered already, but here is an alternative which does not use any hierarchy between the two elements (even though that might not be the best practice):
HTML:
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
JS:
$.fn.invisible = function() {
return this.css("visibility", "hidden");
};
$.fn.visible = function() {
return this.css("visibility", "visible");
};
$(".boss").draggable({
stop:function(e) {
var employee_horizontal_position= $(this).offset().left+$(this).width();
var employee_vertical_position= $(this).offset().top-$(this).height();
$(this).next().visible();
$(this).next().offset({top: employee_vertical_position, left: employee_horizontal_position});
}
});
$(".boss").on("drag", function(e){
$(this).next().invisible();
});
CSS:
.boss{
height: 100px;
width: 300px;
background-color: grey;
float:left;
margin-top:100px;
}
.boss:hover{
cursor:pointer;
}
.employee{
height: 300px;
width: 100px;
background-color: orange;
float:left;
}
JSFIDDLE EXAMPLE: http://jsfiddle.net/ktxo4f6s/2/
I tried to make the employee hidden while the boss is being dragged as shown in your screencast.
n general when wanting elements to be in relation with each other they should be grouped together within an element.
To represent hierarchies it is best to also develop your html to honor the hierarchy you wish to represent.
This will force the behavior as you displayed in the video when moving the boss element.
For this particular example it may also be expanded upon with departments or roles.
See JSFiddle for example: http://jsfiddle.net/9dw5dvqw/
Updated: http://jsfiddle.net/en85bm9h/
HTML
<ul class="bosses">
<li class="boss">
<span class="boss-name"></span>
<ul class="employees">
<li class="employee">
<span class="employee-name"></span>
</li>
<li class="employee">
<span class="employee-name"></span>
</li>
</ul>
</li>
<li class="boss">
<span class="boss-name"></span>
<ul class="employees">
<li class="employee">
<span class="employee-name"></span>
</li>
<li class="employee">
<span class="employee-name"></span>
</li>
</ul>
</li>
</ul>
CSS
*{ margin: 0; padding: 0; }
body,
html{ height: 100%; }
ul{ list-style: none; overflow: hidden; float: left; }
li{ overflow: hidden; }
.bosses{ width: 100%; height: 100%; }
.boss{ margin: 20px 5px 20px 0; float: left; }
.boss-name{ display: block; background-color: #eee; float: left; width: 120px; height: 80px; cursor: move; }
.employees{ float: left; width: 50px; height: 120px; background-color: red; }

Categories

Resources