This question already has answers here:
Ellipsis in the middle of a text (Mac style)
(16 answers)
Closed 7 years ago.
Hi I have list of title in a drop-down as string ex:
"Bharat Untitled offer #564", "Bharat Untitled offer #563"
respectively.
Its title is long so, We want title should show first eight character, then '...' and last 4 character.
I used css rules:
.title{
max-width: 100px;
min-width: 100px;
overflow: hidden;
text-overflow:ellipsis;
}
And get output like:
Bharat Unt...
I want out put like:
Bharat Untitled...ffer
Any ideas how to do this?
Try this:
var charAtBeginning = 10;
var charAtEnd = 7;
var myStr = "I have list of title in a drop-down as string example";
var finalOutput = "";
if (myStr.length > (charAtBeginning + charAtEnd)) {
finalOutput = myStr.substring(0, charAtBeginning) + '..' + myStr.substring((myStr.length - charAtEnd), myStr.length);
}
alert(finalOutput);
if you want to do it with javascript or jquery then there are certain possible ways to do this thing, i am going to illustrate on menthod here.
function processName(ret){
ret = ret.substr(0,8) + "..."+ret.substr(ret.length - 5);
return ret;
}
now All you need to do is to pass each and every value to this function, i assume you know how to do it. good luck.
https://jsfiddle.net/8ye6df9p/
I made this little thing.. i used a monospace font.. hopes it make you bit wiser..
span {
font-family: "Lucida Console", Monaco, monospace;
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 6em;
font-size: 1em;
}
<span>dog eatsdodddddddddgsdfghjkghersdddgsdfghjkghersdddgsdfghjkghersdddgsdfghjkgherstyfghurefyghujrttgyhujrttgyhjretghrtgh</span>
<span>dogfgggyfg ff tgyhujrttgyhjretghrtgh</span>
<span>dog </span>
<span>brainatgs200 </span>
Related
I am new to JavaScript and I learnt how to use JSX to render HTML code. I am passing a string in the Span element in HTML however I want only the last 6 characters of the information to show up on the webpage. So I am trying to use Ellipsis property to do but the number of characters is not reducing. I need the data.id to be only the last 6 characters of the passed string. How can I do this? Can I do this using the ellipsis property or should I use some JavaScript function inside the JSX? I am not sure why the CSS is not working. Can anyone please help?
.branchText {
color: var(--secondaryHeader);
max-width: calc(100% - 16px);
overflow: auto;
white-space: pre-wrap;
word-break: break-word;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
<span className={styles.branchInfoWrapper}>
<span className={styles.branchName}>Master :</span>
<span
className={classNames(styles.branchText)}
ellipsisText
title={data.get('id')}
>
{data.get('id')}
</span>
</span>
data.id is what I need to display next to the Master: text. It needs to be only the last 6 characters.
Not sure if you can show only 6 last characters with CSS, it's normally based on width, so you can use JavaScript:
This will only show last 6 characters:
<span>
{data.get('id').substr(data.get('id').length - 6)}
</span>
Using a ternary operator if statement, it will add ellipsis if id has more than 6 characters.
<span>
{data.get('id').length > 6 ? "..." + data.get('id').substr(data.get('id').length - 6) : data.get('id')}
</span>
Just do npm i react-lines-ellipsis --save and use like this
import LinesEllipsis from 'react-lines-ellipsis'
<LinesEllipsis
text='long long text'
maxLine='3'
ellipsis='...'
trimRight
basedOn='letters'
/>
This question already has answers here:
Setting a max character length in CSS
(15 answers)
Closed 2 years ago.
I have the following mark-up:
<h5>
I am a very long title and I need to be shortened
</h5>
How can I make it so that if the h5 text is above a certain number of characters, I get rid of the other characters and replace them with a "..."?
This should work. You have to display the inline element as a block.
Edit: Just realized you want to add dots if the H5 exceeds a number of characters, not if it exceeds a width. I think to do that you will need to use JS - check out the other answer for that.
h5 {
display: block;
white-space: nowrap;
width: 12em;
overflow: hidden;
text-overflow: ellipsis;
color: red; /* This needs to match the color of the anchor tag */
}
a:link {
color: red;
}
<h5>
I am a very long title and I need to be shortened
</h5>
You can do this:
var name = $('a').text();
if (name.length > 20) {
var shortname = name.substring(0, 20) + " ...";
$('a').replaceWith(shortname);
}
If you want to use javascript, you can extend String object by prototyping:
String.prototype.limit = function(length) {
return this.length > length ? (this.substring(0, length) + '...') : this;
}
var str = 'qwertyuiop';
console.log(str.limit(5)); // qwert...
<h5 id="expansion">
<a id="myLink" href="javascript:void(0);">I am a very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a>
</h5>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
if($('#myLink').text().length > 20){
var linkText = $('#myLink').text();
$('#myLink').html(linkText.substring(0,20)+"...")
$('#myLink').on("click",function(){
console.log("linkText :: ",linkText);
$('#myLink').html(linkText);
});
}
</script>
This one is working
<h5>
<a class ="one" href="javascript:void(0);">I am a very long title and I need to be shortened</a>
</h5>
<style>
.one
{
white-space: nowrap;
overflow:hidden;
text-overflow: ellipsis;
display:inline-block;
width : 100px;
}
</style>
set the width according to your website design
Problem and source code
I'm trying to create <div>s within another <div> at the click of a button. When the button is clicked, a new inner <div> is created (within the outer <div>) with a unique id. I have this part working but here's where I'm running into an issue: I want each inner <div> to have a random margin-top.
Javascript
function pressButton() {
number += 1;
makeDiv(number);
};
function makeDiv(x) {
var innerDiv = document.createElement("innerDiv" + x);
outer.appendChild(innerDiv);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + ";display:inline-block;width:48px;height:48px;background-color:#000;");
};
CSS:
#outer {
position:absolute;
white-space:nowrap;
height:118px;
overflow:auto;
width:100%;
padding:2px;
}
Result (after button is clicked 4 times)
<div id="outer">
<innerDiv1 style="margin-top:15;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv1>
<innerDiv2 style="margin-top:23;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv2>
<innerDiv3 style="margin-top:37;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv3>
<innerDiv4 style="margin-top:0;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv4>
</div>
The result (which I got from inspecting the inner elements in my browser) looks like everything worked - all the margin-tops are random like I wanted. However, the visual result is this:
As you can see, the black inner <div>s all have the same margin-top. What am I doing wrong? How can I make the created <div>s all have random margin-tops?
The CSS spec requires that a length (other than zero) that is missing a unit be treated as an error (and thus ignored). Therefore, add px to the end of your generated margin number, and all should be well.
Live Demo
Description
This happens, because you set the display:inline-block; property. This makes them all to be in one line, so they will allign to the innerDivx that has the highest margin-top.
Delete the display:inline-block; property and give them float:left;. If you want to keep the gap between them, also add margin-left:5px;. And don't forget that margin-top's value needs a unit. I think you wanted to use px.
Also <innerDivx> is not a valid HTML tag. You should change them to a <div> and use innerDivx as an id attribute. Also your tags use almost the same CSS styles so you should put the same ones to a class and add the class instead.
Full solution code
HTML
<button id="button1">Add box</button>
<div id="outer"></div>
JavaScript
var number = 0;
document.getElementById("button1").addEventListener("click", pressButton, false);
function pressButton() {
++number;
makeDiv(number);
};
function makeDiv(x) {
var innerDiv = document.createElement("div");
outer.appendChild(innerDiv);
innerDiv.className += " box";
innerDiv.setAttribute("id", "innerDiv" + x);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + "px;");
};
CSS
#outer {
position: absolute;
white-space: nowrap;
height: 118px;
overflow: auto;
width: 100%;
padding: 2px;
}
.box {
float: left;
width: 48px;
height: 48px;
background-color: #000;
margin-left: 5px;
}
This is likely caused by the position model used for inline-block elements - they're all being vertically-aligned at their bottom line in a row.
I suggest that you simplify this and use position: block with float: left
http://jsfiddle.net/2y5bJ/4/
I also suggest that you stick to standard elements to ensure cross-browser compatibility - don't create your own elements called innerDiv1 etc, but use div elements with unique IDs.
function makeDiv(x) {
var innerDiv = document.createElement("div");
outer.appendChild(div);
innerDiv.setAttribute('id', 'innerDiv' + x);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + "px;");
};
I think there is no tag available with name
<innerDiv1>
This may be the cause.
This question already has answers here:
Creating a textarea with auto-resize
(50 answers)
Closed 8 years ago.
On one of my pages, I have a text area html tag for users to write a letter in. I want the content below the text area to shift down, or in other words, I want the text area to resize vertically with each line added to the text area and to have the content below simply be positioned in relation to the bottom of the text area.
What I am hoping is that javascript/jquery has a way to detect when the words wrap, or when a new line is added and based on that do a resize of the text area container.
My goal is to make the content below the text area stay the same distance from the bottom of the text no matter how much a user writes.
The text area creates a scroll bar when the text overflows.
Since I wasn't too happy with several solutions I found on the web, here's my take on it.
Respects min-height, max-height.
Avoids jumping around and flashing the scrollbar by adding a buffer to the height (currently 20, may replace by line-height). However still shows scrollbar when max-height is reached.
Avoids resetting the container scroll position by incrementally reducing the textarea height instead of setting it to 0. Will thusly also remove all deleted rows at once. Works in IE and Chrome without browser sniffing.
http://jsfiddle.net/Nd6B3/4/
<textarea id="ta"></textarea>
#ta {
width:250px;
min-height:116px;
max-height:300px;
resize:none;
}
$("#ta").keyup(function (e) {
autoheight(this);
});
function autoheight(a) {
if (!$(a).prop('scrollTop')) {
do {
var b = $(a).prop('scrollHeight');
var h = $(a).height();
$(a).height(h - 5);
}
while (b && (b != $(a).prop('scrollHeight')));
};
$(a).height($(a).prop('scrollHeight') + 20);
}
autoheight($("#ta"));
http://www.jacklmoore.com/autosize/
Download the plugin first:
Step 1: Put "jquery.autoresize.min.js" where you keep your jquery plugins.
Step 2: Link the file in HTML -> <script src="jquery.autosize.min.js" type="text/javascript" ></script> Be sure that this link comes after your jquery link, and before your own javascript/jquery code links.
Step 3: In your javascript code file simply add $('#containerToBeResized').autosize();
$('textarea').keyup(function (e) {
var rows = $(this).val().split("\n");
$(this).prop('rows', rows.length);
});
this work sample.
See this Fiddle from this answer. That increases the height of the textarea based on the number of lines.
I think that's what you're asking for.
Copied the code from the answer below:
HTML
<p>Code explanation: Textarea Auto Resize</p>
<textarea id="comments" placeholder="Type many lines of texts in here and you will see magic stuff" class="common"></textarea>
JS
/*global document:false, $:false */
var txt = $('#comments'),
hiddenDiv = $(document.createElement('div')),
content = null;
txt.addClass('txtstuff');
hiddenDiv.addClass('hiddendiv common');
$('body').append(hiddenDiv);
txt.on('keyup', function () {
content = $(this).val();
content = content.replace(/\n/g, '<br>');
hiddenDiv.html(content + '<br class="lbr">');
$(this).css('height', hiddenDiv.height());
});
CSS
body {
margin: 20px;
}
p {
margin-bottom: 14px;
}
textarea {
color: #444;
padding: 5px;
}
.txtstuff {
resize: none; /* remove this if you want the user to be able to resize it in modern browsers */
overflow: hidden;
}
.hiddendiv {
display: none;
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word; /* future version of deprecated 'word-wrap' */
}
/* the styles for 'commmon' are applied to both the textarea and the hidden clone */
/* these must be the same for both */
.common {
width: 500px;
min-height: 50px;
font-family: Arial, sans-serif;
font-size: 13px;
overflow: hidden;
}
.lbr {
line-height: 3px;
}
I have a list of paths (for lack of a better word, maybe bread crumb trails describes them better). Some of the values are too long to display in their parent so I'm using text-overflow: ellipsis. The problem is that the important information is on the right, so I'd like the ellipsis to appear on the left. Something like this this ascii art:
----------------------------
|first > second > third |
|...second > third > fourth|
|...fifth > sixth > seventh|
----------------------------
Notice that the first row is short enough so it remains left aligned, but the other two are too long so the ellipsis appears on the left hand side.
I'd prefer a CSS only solution, but JS is fine if it can't be avoided. It's ok if the solution only works in Firefox and Chrome.
EDIT: At this point I'm looking for a work around for the bugs in Chrome that prevent it from rendering properly when a document is mixed RTL and LTR. That was all I really needed from the outset, I just didn't realize it.
How about something like this jsFiddle? It uses the direction, text-align, and text-overflow to get the ellipsis on the left. According to MDN, there may be the possibility of specifying the ellipsis on the left in the future with the left-overflow-type value however it's considered to still be experimental.
p {
white-space: nowrap;
overflow: hidden;
/* "overflow" value must be different from "visible" */
text-overflow: ellipsis;
width: 170px;
border: 1px solid #999;
direction: rtl;
text-align: left;
}
<p>first > second > third<br /> second > third > fourth > fifth > sixth<br /> fifth > sixth > seventh > eighth > ninth</p>
I finally had to crack and do something in JavaScript. I was hoping that someone would come up with a hail-mary CSS solution but people seem to just be up-voting the answer that should be correct if it weren't for the Chrome bugs. j08691 can have the bounty for his work.
<html>
<head>
<style>
#container {
width: 200px;
border: 1px solid blue;
}
#container div {
width: 100%;
overflow: hidden;
white-space: nowrap;
}
</style>
<script>
function trimRows() {
var rows = document.getElementById('container').childNodes;
for (var i=0, row; row = rows[i]; i++) {
if (row.scrollWidth > row.offsetWidth) {
var textNode = row.firstChild;
var value = '...' + textNode.nodeValue;
do {
value = '...' + value.substr(4);
textNode.nodeValue = value;
} while (row.scrollWidth > row.offsetWidth);
}
}
}
</script>
</head>
<body onload='trimRows();'>
<div id="container" >
<div>first > second > third</div>
<div>second > third > fourth > fifth > sixth</div>
<div>fifth > sixth > seventh > eighth > ninth</div>
</div>
</body>
</html>
Fiddle
Why not just using direction:rtl;
It's a little buggy, but maybe a point in the right direction
http://jsfiddle.net/HerrSerker/ZfbaD/50/
$('.container')
.animate({'width': 450}, 4000)
.animate({'width': 100}, 4000)
.animate({'width': 170}, 4000)
.container {
white-space: nowrap;
overflow: hidden; /* "overflow" value must be different from "visible" */
text-overflow: ellipsis;
width:170px;
border:1px solid #999;
direction:rtl;
}
.container .part {
direction:ltr;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<span class="part">second</span>
<span class="part">></span>
<span class="part">third</span>
<span class="part">></span>
<span class="part">fourth</span>
<span class="part">></span>
<span class="part">fifth</span>
<span class="part">></span>
<span class="part">sixth</span>
</div>
These solutions solve the problem with misinterpreted preceding or trailing weak or neutral BiDi characters such as /, \, ~, ., etc. (basically any punctuation or special characters).
CSS Solution
Use a combination of:
direction: rtl & ltr
unicode-bidi: bidi-override
p {
direction: rtl;
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* or pre (e.g. preserve multiple spaces) */
}
span {
direction: ltr;
unicode-bidi: bidi-override; /* or isolate, isolate-override, embed */
}
<p><span>/path/to/a/very/long/file.name</span></p>
<bdo> Solution
Another possibility uses the <bdo> Bidirectional Text Override element:
p {
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* or pre (e.g. preserve multiple spaces) */
}
<bdo dir="rtl">
<p>
<bdo dir="ltr">/path/to/a/very/long/file.name</bdo>
</p>
</bdo>
Using #Hemlocks, #Brian Mortenson and #Jimbo's solutions, I've built a jQuery plugin to solve this problem.
I've also added support to return the initial value using .html() rather than having it return the current innerHTML. Hopefully it will be useful to someone...
(function($) {
$.trimLeft = function(element, options) {
var trim = this;
var $element = $(element), // reference to the jQuery version of DOM element
element = element; // reference to the actual DOM element
var initialText = element.innerHTML;
trim.init = function() {
overrideNodeMethod("html", function(){ return initialText; });
trimContents(element, element);
return trim;
};
trim.reset = function(){
element.innerHTML = initialText;
return trim;
};
//Overide .html() to return initialText.
var overrideNodeMethod = function(methodName, action) {
var originalVal = $.fn[methodName];
var thisNode = $element;
$.fn[methodName] = function() {
if (this[0]==thisNode[0]) {
return action.apply(this, arguments);
} else {
return originalVal.apply(this, arguments);
}
};
};
var trimContents = function(row, node){
while (row.scrollWidth > row.offsetWidth) {
var childNode = node.firstChild;
if (!childNode)
return true;
if (childNode.nodeType == document.TEXT_NODE){
trimText(row, node, childNode);
}
else {
var empty = trimContents(row, childNode);
if (empty){
node.removeChild(childNode);
}
}
};
};
var trimText = function(row, node, textNode){
var value = '\u2026' + textNode.nodeValue;
do {
value = '\u2026' + value.substr(4);
textNode.nodeValue = value;
if (value == '\u2026'){
node.removeChild(textNode);
return;
}
}
while (row.scrollWidth > row.offsetWidth);
};
trim.init();
};
$.fn.trimLeft = (function(options){
var othat = this;
var single = function(that){
if (undefined == $(that).data('trim')) {
var trim = new $.trimLeft(that, options);
$(that).data('trim', trim);
$(window).resize(function(){
$(that).each(function(){
trim.reset().init();
});
});
}
};
var multiple = function(){
$(othat).each(function() {
single(this);
});
};
if($(othat).length>1)
multiple(othat);
else
single(othat);
//-----------
return this;
});
})(jQuery);
Initiate using:
//Call on elements with overflow: hidden and white-space: nowrap
$('#container>div').trimLeft();
//Returns the original innerHTML
console.log($('#test').html());
fiddle
Using a slightly more complex markup (using the bdi-tag and an extra span for the ellipsis), we can solve the problem fully in CSS, no JS required at all -- cross browser (IE, FF, Chrome) and including keeping punctuation marks to the right:
http://jsbin.com/dodijuwebe/1/edit?html,css,output
Granted, this is something of a hack, involving pseudo-element goodness. However, our team has been using this code in production and we haven't had any issues whatsoever.
The only caveats are: The height of the line needs to be fixed and the background color needs to be known explicitly (inherit won't work).
If you don't care the indexing of those texts, you could use this method (it reverses the text lines):
If you have in your texts other HTML elements besides <br> you need to make some arrangements to use this method.
HTML code:
<p>first > second > third<br/>
second > third > fourth <br>
fifth > sixth > seventh</p>
CSS code:
p{
overflow: hidden;
text-overflow: ellipsis;
unicode-bidi: bidi-override;
direction: rtl;
text-align: left;
white-space: nowrap;
width: 140px;
}
JavaScript code
[].forEach.call(document.getElementsByTagName("p"), function(item) {
var str = item.innerText;
//Change the operators
str = str.replace(/[<>]/g, function(char){ return ({"<" : ">", ">" : "<"})[char] });
//Get lines
var lines = str.split(/\n/);
//Reverse the lines
lines = lines.map(function(l){ return l.split("").reverse().join("") });
//Join the lines
str = lines.join("<br>");
item.innerHTML = str;
});
jsfiddle
Based on your edit:
At this point I'm looking for a work around for the bugs in Chrome
that prevent it from rendering properly when a document is mixed RTL
and LTR. That was all I really needed from the outset, I just didn't
realize it.
Have you looked into the unicode-bidi css property (see Sitepoint or W3C)? I actually just learned about this myself on another recent post. My guess is you would want to use the embed value for those pieces going the opposite direction to the main site. So in j08691's answer where it is direction: rtl add unicode-bidi: embed to the CSS. This should solve "mixed RTL and LTR" issues you are having.
I put some JavaScript together to regex out three items and add the ellipsis in where necessary. This does not explicitly look at how much text will fit in the box but if the box is fixed this may not be an issue.
<style>
p {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width:170px;
border:1px solid #999;
direction:rtl;
text-align:left;
}
</style>
<p>first > second > third<br />
second > third > fourth > fifth > sixth<br />
fifth < sixth < seventh < eighth < ninth</p>
<script>
var text = $( 'p' ).text(),
split = text.split( '\n' ),
finalStr = '';
for( i in split ){
finalStr = finalStr.length > 0 ? finalStr + '<br />' : finalStr;
var match = /(\w+\s?(<|>)?\s?){3}$/.exec( split[i] );
finalStr = finalStr + ( split[i].length > match[0].length ? '...' : '' ) + match[0];
}
$( 'p' ).empty().html( finalStr );
</script>