Text wrap inside <li> tag - javascript

I have the following structure on a div:
<div class="box1" id="infobox">
<h2> Point characteristics: </h2>
<div style="padding-left:30px" align="left">
<ul>
<li class="infobox_list"><b>X value: </b><span class="clsshorted infobox_text" id="infobox_xvalue"> </span></li>
<li class="infobox_list"><b>Y value: </b><span class="clsshorted infobox_text" id="infobox_yvalue"> </span></li>
<li class="infobox_list"><b>Description: </b><span class="clsshorted infobox_text" id="infobox_description"> </span></li>
</ul>
Where the class "infobox_list" contains the following CSS:
.infobox_list {
padding: 0px 0px 10px 0px;
width: 500px;
}
The class "clsshorted" contains the following CSS:
span.clsshorted {
vertical-align: bottom;
overflow: hidden;
white-space: nowrap;
display: inline-block;
text-overflow: ellipsis;
width: 300px;
}
And the class "infobox_text" contains the following CSS:
.infobox_text {
overflow: auto;
white-space: nowrap;
word-wrap:break-word;
}
Example can be seen at: https://jsfiddle.net/nowv94yz/
I have been encountering two problems which I don't know how to deal with them:
The first problem I have been encountering is that I toggle, by using the "toggleClass()" function from JQuery, the class "clsshorted". When the clsshorted class is active I would like that the "ellipsised" text from the "text-overflow" property is ellipted at the end of the <li> tag (which as it can be seen at the CSS is 500px width) instead than on the 300px that I input. The thing is that as the string is so long (and with no spaces) that if I do not input that 300px it does not ellipsisate the text or it does outside the box size... (check jsfiddle avobe to see the problem)
The second problem I have been encountering is that when the "clsshort" class is not active, and thus only the "infobox_text" class is active, I would like this large string without spaces to appear completely displayed, but respecting the borders of the <li> tag. This means that if the <li> tag is 500px width, and the string would need 1501px to be displayed, 4 justified rows appear containing the string cutted on those part where the word reaches the end of the content of the box (500px)
Any ideas on how to do this?
Thank you in advance!

For the second problem, you just need to remove white-space: nowrap; from .infobox_text.

Related

How do I align the content of two divs when the data in those divs may change?

I've got two Divs, one holds temperature information, the other humidity.
<div class="weatherwrap">
<div class="tempwrap" title="Current Temperature">
<span id=tempinfo><javascript injected data></span>
</div>
<div class="humidwrap" title="Current Humidity">
<span id="humidinfo"><javascript injected data></i></span>
</div>
</div>
Right now, they render like this:
I'd really prefer it if they always aligned by the decimal point (.), as this consistently creates the most pleasing visual.
However, if the number changes, say - the temperature raises into the positive, or humidity drops by a half percentage point, these two divs will be aligned differently, again. How can I ensure that these two divs will align themselves the most optimal way, even if the length of the information inside them is to change?
I've tried hard coding it, and wrote some very bad JavaScript that adds padding to one based on the length of the other, but I'm not satisfied of the reliability of either solutions.
You can align on the period. Use something like below:
#container {
display: flex;
flex-flow: column nowrap;
outline: 1px black dotted;
}
#container > div {
display: flex;
}
.a {
width: 48px;
text-align:right;
}
.b {
}
.c {
width: 48px;
}
<div id=container>
<div>
<div class=a>12</div><div class=b>.</div><div class=c>12</div>
</div>
<div>
<div class=a>1234</div><div class=b>.</div><div class=c>12</div>
</div>
<div>
<div class=a>12</div><div class=b>.</div><div class=c>1234</div>
</div>
<div>
<div class=a>123456</div><div class=b>.</div><div class=c>12</div>
</div>
</div>

Qualtrics JavaScript: Append an image over matrix text boxes

In Qualtrics, I am trying to create something like this:
https://dl.dropboxusercontent.com/u/8114735/Screen%20Shot%202015-05-12%20at%2017.49.17.png
The only way to have text boxes both next to and on top of each other is by using a matrix table with text entry. However, this only gives you the text boxes, without a space above the text entry box to insert an image. So I'm now trying to append these images using javascript. The ID of the text boxes is in the format of QR~QID17~3~2~TEXT (for the box on row 3, column 2).
Here is a sample I made of the text boxes in a 3x3 matrix.
https://eu.qualtrics.com/WRQualtricsSurveyEngine/?SID=SV_b30tGcjTmJWTlYN&SVID=&Preview=Block&ID=BL_enEP0YjUHaK5yPX&Q_DONT_SAVE=1
Does anyone know how you can append an image on top of these boxes? Thanks.
I will start with a working example:
Working Example
This uses numbers, in place of images, but is still a valid example.
First, you will select the "Position text above" option, and in the rows of text you will place the following code:
<td class="c4">1</td><td class="c5">2</td><td class="c6 last">3</td>
replacing 1,2,and 3 with the images for that row(you will have to use an image tag to get this to work in a friendly way).
Once you have setup all three of your rows, add the following to the question javascript:
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place Your Javascript Below This Line*/
$$('.c1').each(
function (e) {
e.remove();
}
);
});
This hides a placeholder inserted by qualtrics and allows your rows to line up nicely!
Enjoy! Note though that this will likely require the images to be sized properly(I havent tested images)
How about using DIV container?
HTML
<div class="container">
<div class="box">
<div class="box-image">
<img src="http://lorempixel.com/output/city-h-c-150-230-4.jpg" />
</div>
<div class="box-input">
<input type="text" />
</div>
</div>
</div>
CSS
.box {
float: left;
width: 200px;
margin: 5px;
}
.container {
max-width:420px;
background:#CCCCCC;
overflow: hidden;
}
.box-image, .box-input {
text-align: center;
width: 100%;
}
.box-image {
background: #FFFFFF;
}
.box-input input{
margin-top: 2px;
width: 200px;
border: 1px solid #AAAAAA;
}
FIDDLE

Can li class be swapped with css only

Been made aware you cant swap classes unless its a sibling. so instead of putting the class in a new div im trying to put it into the same list but give it a class to hide, then be visible when another li is hovered.
http://jsfiddle.net/e79g4p1p/13/
<div class="bodyfooter_block bbshadowb">
<p class="typotitle_sml"><?php echo $var_furtherinfotitle; ?></p>
<p class="typosubtitle_sml"><?php echo $var_furtherinfoheading; ?></p>
<p class="typotext" style="padding-top:16px;">
<ul class="blocklist">
<li>text hidden</li>
<li>text</li>
<li>yugiugugu</li>
<li>ugiugguiug</li>
<li>ygguiguig</li>
<li>uihoihoihoih</li>
<li>uhgiuhiuhuh</li>
<p>po</p>
<li class="bodyfooter_text1" id="bodyfooter_text1">hidden</li>
</ul>
</p>
</div>
css
.hover_text1 {
}
.bodyfooter_text1 {
list-style-type: none;
visibility: hidden;
}
.hover_text1:hover > #bodyfooter_text1 {
list-style-type: none;
width:260px;
height:102px;
background: #222222;
color: #CCCCCC;
padding:12px;
padding-top:6px;
border-radius: 6px;
visibility: visible;
}
Tried with js but doesnt work:
$("#hover_text1").hover(function() {
$(".bodyfooter_text1").addClass("bodyfooter_text1_hover");
});
http://jsfiddle.net/e79g4p1p/23/
I strongly suggest you go over the basics of CSS once again.
The problem you face can be overcome using pure CSS - we need a selector called the General Sibling Combinator:
CSS
.hover_text1:hover ~ #bodyfooter_text1 {
display: block;
}
This, however, requires you to restructure your markup by a marginal amount, so the "preceded by element" rule works correctly - the selector we use requires both the preceding and the targeted element to share the same parent:
HTML
<ul class="blocklist">
<li class="hover_text1">text hidden</li>
<li>text</li>
<!-- ... -->
<li class="bodyfooter_text1" id="bodyfooter_text1">hidden</li>
</ul>
Working example on JSFiddle.
The fiddle I've linked is a very simplified version of your code, modified only to highlight the selectors working and nothing else.

dynamic or adaptable class in css

I have a problem where I will be displaying a variable number of items displayed, and they will have a margin setting which is updated uniformly over the set.
So basically to put it simple if I have a set that is [1,2,3,4,5] it might be something like:
1 2 3 4 5
while if the number of number were to double they would require the same amount of space:
1 2 3 4 5 6 7 8 9 10
I have some solutions for this but what hit me was that if I have an css-class (as the margin is uniform over the given set) I could share the layout. So I would have liked it if it were possible to update the class dynamically if that makes sense I haven't found any information of that being possible to do, so if we assume that in the first example the margin is something like margin-right: 10px; then if I could change the class, (similar to how I set style on an element I guess is how I am thinking, but for the whole class), it would be really smooth. So let's assume a functionality to do this I could have a class:
.myclass {
margin-right: 10px;
}
and through our magic function .myclass.setProperty('margin-right', '5px'); (or whatever the syntax would be :P). It would act as if i had defined the class:
.myclass {
margin-right: 5px;
}
I hope that is enough to grasp my ideas and problem thus far. The way I am going about it at the moment is that I use a class for all shared behavior and set style for each element. However this is a bit tedious as it become something like:
for (var i in mynumbers) {
mynumbers.style.marginRight = new_margin;
}
Where new_margin is calculated based on a scale (i.e. it could change many times in a short period of time).
So to the question-part. Is there perhaps a way to achieve something like the first part (a way to dynamically change a class), or any thoughts or ideas how to implement it if the way I am doing it feels like a bad idea or if you feel there are better ways of handling this.
Thanks for reading and hope you find the problem interesting.
Ah, just another typical use case of flex layout:
.container {
display: flex;
border: 1px solid;
justify-content: space-between;
}
<h2>5 elements in a line with equal width gaps</h2>
<div class="container">
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span>
</div>
<h2>10 elements in a line with equal width gaps</h2>
<div class="container">
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span>
<span>6</span><span>7</span><span>8</span><span>9</span><span>10</span>
</div>
If your browser supports the feature, you would see something like this:
Here for browser compatibility.
EDIT: another interesting use case, although OP didn't ask about:
.container {
display: flex;
border: 1px solid;
justify-content: space-between;
}
.container:before, .container:after {
content: '';
width: 0;
}
<h2>5 elements in a line with equal width gaps</h2>
<div class="container">
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span>
</div>
<h2>10 elements in a line with equal width gaps</h2>
<div class="container">
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span>
<span>6</span><span>7</span><span>8</span><span>9</span><span>10</span>
</div>
If your browser supports the feature, you would see something like this:
Space is divided equally not only between elements, but also include both ends of the container. And you could see how simple the code is!
This sounds like a job for table-layout: fixed. Your browser computes the width of each "column" (element) in the first "table-row" based on the number of columns in the "table".
.table {
display: table;
table-layout: fixed;
width: 100%;
}
.table > span {
display: table-cell;
text-align: center;
}
<div class="table">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
</div>
<div class="table">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>
Yes. This is possible. One thing to be aware of is that changing a class's property may cause the browser's renderer to recalculate the entire page's layout (it needs to figure out how your class change affects the overall layout). So if you plan on changing your margin-right in a way to animate the change, it's not going to perform very well depending on the complexity of your page. That said, here is a quick and dirty implementation that should work on everything IE9+:
<html>
<head>
<style>
.thing {
display: inline-block;
width: 20px;
height: 20px;
background: #f00;
}
</style>
</head>
<body>
<div>
<div class="thing myClass"></div>
<div class="thing myClass"></div>
<div class="thing myClass"></div>
<div class="thing myClass"></div>
<div class="thing myClass"></div>
<div class="thing myClass"></div>
</div>
<div>
<button id="doit">Make bigger</button>
</div>
</body>
<script>
var styleTag = document.createElement("style"),
styleSheet, index, cssRule, style;
// Create a <style> tag that will hold our CSS rule
document.head.appendChild(styleTag);
styleSheet = styleTag.sheet;
// Insert an empty .myClass rule into the style sheet
index = styleSheet.insertRule(".myClass {}", styleSheet.cssRules.length);
// Get the 'style' object from the rule. This is nearly identical to elem.style
cssRule = styleSheet.cssRules[index];
style = cssRule.style;
// Sets .myClass { margin-right: 5px; }
style.marginRight = "5px";
// Demo to show that it works when you click a button
document.querySelector("#doit").addEventListener("click", function() {
style.marginRight = "20px";
});
</script>
</html>

Moving html element containing contentEditable to another branch in dom without losing focus

I hope you can help with this problem.
I have the following html structure (simplified) which represents two fixed-height pages in a document with headers, footers, a body and a number of "DataItems" (3 readonly, 1 editable) within that body. There are also a "Summary" and "Add New" DataItems.
I need to be able to move a DataItem's block of html (that may contain a contentEditable element) into another position in the document. However, I need to do so without losing focus to the contentEditable element if it is that which is being moved.
This action is triggered whilst the user is typing into the contentEditable HTML Editor and the DataItem that they are typing into gets taller. As it does so, when the bottom DataItem starts to overlap the footer, it gets pushed down to the next page. A bit like typing into a table cell in MS Word that isn't allowed to break across pages.
I can get a partial solution working with jQuery. This moves next sibling DataItems from the first page to the second page as a previous sibling grows in height, but the problem with this is that when I then go to move the DataItem which has focus, it loses focus and breaks the user's flow of typing. I have tried putting focus back to the contentEditable div after moving it, but issues with selection and range and not being able to find the cursor position plus issues with the scrollbars jumping despite them being reset back have proved that solution to be too unreliable.
I therefore tried a different approach which was to move all html content between the last DataItem of the first page and the first DataItem (if any) of the next page to a position before the last data item, in the hope that doing so would prevent the html content editor from losing focus, but still give the impression that the DataItem has moved down to the second page.
The functionality I've tried (and failed) to achieve is to cut the html between the "start-here" and "end-here" divs and move it to the "paste-here" div. The divs are just there as placeholders to show what should be moved.
However, despite trying various methods using jQuery dom manipulation and RegEx string replacement I can't seem to come up with a solution that doesn't involve replacing the common ancestor - which is the "Pages" div - and hence having to replace the current contentEditable - and hence losing focus.
Does anyone have an idea of how I could do this and retain focus so the user can continue typing uninterrupted?
Regards,
Jeremy :)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
.Document
{
text-align:left;
margin: 0px auto;
display:inline-block;
position:relative;
/*border: 1px solid blue;*/
}
.Pages
{
margin: 0px auto;
position:relative;
display:inline-block;
/*border: 1px solid yellow;*/
}
.PortraitPage
{
height:29.7cm;
width:21cm;
background: #ffffff;
position:relative;
}
.FirstPage
{
border: 1px dotted black;
}
.ExtraPage
{
margin-top:10px;
margin-bottom:10px;
border: 1px dotted black;
}
.PageHeader
{
border: 0px dotted #e2e2e2;
position:absolute;
top:0px;
width: 18cm;
left:0cm;
}
.PageBody
{
border: 1px dotted #c2c2c2;
position:absolute;
top:4.5cm; /* this needs to be whatever the height of the header is */
width: 18cm;
left:1.5cm;
/*min-height:22cm;*/
}
.PageFooter
{
border: 1px dotted #e2e2e2;
position:absolute;
bottom:0px;
width: 18cm;
left:1.5cm;
}
.PageSeparator
{
background: #999999;
height: 1cm;
width: 21cm;
}
.InvoiceItemsForm
{
position: relative;
/*top: 2.5cm;*/
}
/* This prevents the space added in contentcell divs in the html entry cell just for the PageEditor */
.InvoiceItemsForm div
{
margin-bottom: 0px;
}
.LineItem_Panel_ReadOnly
{
position:relative;
border: 1px solid transparent;
}
.LineItem_Panel_ReadOnly_Hover
{
position:relative;
border: 1px solid #C2C2C2;
background-color:#ffffff;
}
.LineItem_Panel_Edit
{
position:relative;
border: 1px solid #C2C2C2;
}
.LineItem_Panel_Insert
{
position:relative;
border: 1px solid green;
}
</style>
</head>
<body>
<div id="ctl00_phContent_pnlInvoicePage" class="Page FirstPage PortraitPage">
<div class="FirstHeader PageHeader">
First Page Header
</div>
<div class="ExtraHeader HiddenExtraPageSection">
Hidden ExtraPage Header that is copied when a new page is created
</div>
<div id="ctl00_phContent_pnlInvoicePageBody" class="PageSection Body PageBody">
<div id="ctl00_phContent_pnlInvoiceItemsForm" class="InvoiceItemsForm DataSection">
<div id="ctl00_phContent_lvLineItems_ctrl0_pnlLineItemReadOnly" class="DataItem LineItem_Panel_ReadOnly InvoiceLineItem">
<div class="LineItem_Panel_HTMLContent">
<span id="ctl00_phContent_lvLineItems_ctrl0_lblHTMLContent">
<p>
aaaaaaaaaaaaaaa</p>
<p>
aaaaaaaaaaaaaa</p>
</span>
</div>
</div>
<div id="ctl00_phContent_lvLineItems_ctrl1_pnlLineItemReadOnly" class="DataItem LineItem_Panel_ReadOnly InvoiceLineItem">
<div class="LineItem_Panel_HTMLContent">
<span id="ctl00_phContent_lvLineItems_ctrl1_lblHTMLContent">
<p>
bbbbbbbbbbbbbbb</p>
<p>
bbbbbbbbbb</p>
</span>
</div>
</div>
<div id="ctl00_phContent_lvLineItems_ctrl2_pnlLineItemReadOnly" class="DataItem LineItem_Panel_ReadOnly InvoiceLineItem">
<div class="LineItem_Panel_HTMLContent">
<span id="ctl00_phContent_lvLineItems_ctrl2_lblHTMLContent">cccccccccccccc</span>
</div>
</div>
<div id="ctl00_phContent_lvLineItems_ctrl3_pnlLineItemEdit" class="DataItem LineItem_Panel_Edit InvoiceLineItem">
<div id="ctl00_phContent_lvLineItems_ctrl3_pnlHTMLEditor" class="HTMLEditorPanel">
<div style="width: 126px; height: 20px;" id="ctl00_phContent_lvLineItems_ctrl3_txtHTMLContent$HtmlEditorExtenderBehavior_ExtenderContainer"
class="unselectable ajax__html_editor_extender_container">
<input style="display: none; visibility: hidden;" id="ctl00_phContent_lvLineItems_ctrl3_txtHTMLContent"
name="ctl00$phContent$lvLineItems$ctrl3$txtHTMLContent" value="ddddddddddddd"
type="text" autocomplete="off">
<div style="height: 21px; overflow: auto; clear: both;" id="ctl00_phContent_lvLineItems_ctrl3_heeHTMLContent_ExtenderContentEditable"
class="ajax__html_editor_extender_texteditor" contenteditable="true">
<p>
ddddddddddddd</p>
<p>
</p>
</div>
</div>
</div>
</div>
<div class="DataItem">
<p>
Click <a id="ctl00_phContent_lvLineItems_lbAddLineItem" href='javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$phContent$lvLineItems$lbAddLineItem", "", true, "", "", false, true))'>
here</a> to add a new Data Item</p>
</div>
<div id="paste-here"></div>
<div class="DataItem InvoiceTotals">
<div class="InvoiceSubTotal">
Sub Total: <span id="ctl00_phContent_lvLineItems_lblInvoiceSubTotal">18,110.00</span></div>
<div class="InvoiceVATTotal">
VAT Total: <span id="ctl00_phContent_lvLineItems_lblInvoiceVATTotal">3,111.00</span></div>
<div class="InvoiceTotal">
Invoice Total: <span id="ctl00_phContent_lvLineItems_lblInvoiceTotal">21,221.00</span></div>
</div>
<div id="start-cut"></div>
</div>
</div>
<div class="FirstFooter PageFooter">
First Page Footer
</div>
<div class="ExtraFooter HiddenExtraPageSection">
Hidden ExtraPage Footer that is copied when a new page is created
</div>
</div>
<div id="ctl00_phContent_pnlInvoicePage" class="Page ExtraPage PortraitPage">
<div class="ExtraHeader PageHeader">
Extra Page Header
</div>
<div id="ctl00_phContent_pnlInvoicePageBody" class="PageSection Body PageBody">
<div id="ctl00_phContent_pnlInvoiceItemsForm" class="InvoiceItemsForm DataSection">
<div id="end-cut"></div>
</div>
</div>
<div class="ExtraFooter PageFooter">
Extra Page Footer
</div>
</div>
</body>
</html>
I don't see any reason you have to reparent anything to achieve the effect you want. Instead of trying to rely on the browser being smart enough to render things where you want them, which will prove to be inconsistent between browsers and possibly different versions of the same browser, I would suggest using CSS and javascript to explicitly position the items. When the text the user enters gets too long to fit in the space provided, you can use node.style.top=newY; node.style.left=newX; to reposition it, and node.style.height=newHeight; node.style.width=newWidth; to resize it however large it needs to be. These methods don't require the browser to remove and re-insert the element, so focus is not lost, nor is text selection or cursor position.

Categories