I'm using a word count textarea jquery script and I'm trying to work out how to update the word count onload to e.g. 2 from the preset text area "this example" to start with.
(it currently shows 0)
I can set the focus on it and move the cursor but I don't know how to update it initially, any ideas?
HTML
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="js/jQuery.textareaCounter.c.js"></script>
<textarea id="txtarea" name="text" rows="7" cols="120">this example</textarea>
<script type="text/javascript">
$("textarea").textareaCounter();
document.getElementById('txtarea').focus();
var val = document.getElementById('txtarea').value; //store the value of the element
document.getElementById('txtarea').value = ''; //clear the value of the element
document.getElementById('txtarea').value = val; //set that value back. so cursor is at end.
</script>
jquery.min.js contains:-
(function(a){a.fn.textareaCounter=function(b){var c={limit:10};var b=a.extend(c,b);return this.each(function(){var c,d,e,f;c=a(this);c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">Max. '+b.limit+" words</span>");c.keyup(function(){d=c.val();if(d===""){e=0}else{e=a.trim(d).split(" ").length}if(e>b.limit){a("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');f=a.trim(d).split(" ",b.limit);f=f.join(" ");a(this).val(f)}else{a("#counter-text").html(b.limit-e+" words left")}})})}})(jQuery)
jQuery.textareaCounter.c.js contains:-
(function(a) {
a.fn.textareaCounter = function(b) {
var c = {
limit: 10
};
var b = a.extend(c, b);
return this.each(function() {
var c, d, e, f;
c = a(this);
c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">' + "0 words</span>");
c.keyup(function() {
d = c.val();
if (d === "") {
e = 0
} else {
e = d.replace(/^[\s,.;]+/, "").replace(/[\s,.;]+$/, "").split(/[\s,.;]+/).length;
}
if (e > b.limit) {
// a("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');
// f=a.trim(d).split(" ",b.limit);
// f=f.join(" ");
// a(this).val(f)
a("#counter-text").html(e + " words ")
document.myform.numwords.value = e;
} else {
a("#counter-text").html(e + " words ")
document.myform.numwords.value = e;
}
});
});
}
})
(jQuery)
This is what I changed in jQuery.textareaCounter.c.js:
var initCount = c.text().split(" ").length;
if(initCount < 2){initCount=0;}
c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">' + initCount +" words</span>");
Here is the JSFiddle demo
You can fire a keyup event during initialization to trigger the update:
<script type="text/javascript">
$("textarea").textareaCounter();
document.getElementById('txtarea').focus();
var val = document.getElementById('txtarea').value; //store the value of the element
document.getElementById('txtarea').value = ''; //clear the value of the element
document.getElementById('txtarea').value = val; //set that value back. so cursor is at end.
// init word count
$("textarea")[0].dispatchEvent(new Event('keyup'));
</script>
//Function to show maxlength of Textarea
document.getElementById("textArea").addEventListener("keyup",function(){
var textAreaValue = document.getElementById("textArea").value;
var show = (250 - (textAreaValue.length));
document.getElementById('count').innerHTML = show + " characters remaining";
});
Related
I am a guitar addict and I try to make a UI for guitar tablature.
In my js code, you can see
var notes = ['s6f1', 's5f5', 's4f7', 's3f6', 's2f5', 's1f3', 's6f8',
's5f1', 's4f6', 's3f1', 's2f3', 's1f3', 's6f9', 's5f17', 's4f19'];
's6f1' means string 6 & fret 1 and I want to show it on tablature. The way I show this is to put a "1" on string 6. Please the picture below. In my code, I basically traverse the notes array and attach each note on tablature . I define each 6 six lines as a group. After a group is filled with 4 notes, a new group is shown. Since In my real application, I do not know how many notes that notes array has(In this examples, I just simplify there are 15 notes), I have to dynamically create each group and assign each line a unique id. My question is that I do not know how to attach the number on the string. For instance, after dynamically create a "six-line", how do I attach the number on the correct line. I think the challenge in my question is that I cannot predefine the location of six-liner in html. The code below is the html, css, js code that I wrote. Hope someone could help me out. Thank you in advance.
html:
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="code.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="code_js.js"></script>
</head>
<body>
</div>
<div id = "output">
</body>
</html>
css:
.deco {
border-bottom: 1px solid black;
width: 120px;
margin-left:0px;
margin-bottom:10px;
z-index: 2;
position: relative;
display: block;
margin-right: 20px;
}
#output {
width: 300px;
height: 200px;
position:absolute;
float:left;
background-color: yellow;
}
.six_line {
width: 125px;
height: 80px;
float:left;
margin-right: 20px;
}
js:
"use strict"
var count = 0;
var group = -1;
$(document).ready(function() {
var notes = ['s6f1', 's5f5', 's4f7', 's3f6', 's2f5', 's1f3', 's6f8', 's5f1', 's4f6', 's3f1', 's2f3', 's1f3', 's6f9', 's5f17', 's4f19'];
hideNote(notes, 0);
});
function hideNote(notes, i) {
var x = -2;
if(count == 4) {count = 0;}
if(count++ == 0) {
group++;
makeItHappen();
}
var ns4 = notes[i];
// retrive the info of string
var ns2 = ns4.substring(0,2);
x = parseInt(ns4.substring(1,2)) + (group*6);
**/*How to attach fret(#) on the string*
// finds the line with corresponding id
$('#hr' + x).attr('class', '?');
*/**
hide(function(){
if(++i < notes.length) {
hideNote(notes, i);
}
},notes[i]);
}
function hide(callback, note) {
setTimeout(function(){
callback();
}, 1000);
}
function makeItHappen() {
var six = document.createElement('div');
six.className = "six_line";
for (var i = 1; i < 7; i++) {
var hr = document.createElement('hr');
hr.className = "deco";
hr.id = "hr" + (group * 6 + i);
six.append(hr);
}
$('#output').append(six);
}
I suggest some modifications in your code.
Starting with the function that creates your strings:
function makeItHappen(nbGroup) {
for(var g = 1; g <= nbGroup; g++){
var six = document.createElement('div');
six.className = "six_line";
for (var i = 6; i >= 1; i--) {
var string = document.createElement('div');
string.className = "deco";
string.id = "string" + ('G' + g + 'S' + i);
six.append(string);
}
$('#output').append(six);
}
}
That will create all your groups of strings at the same time. It becomes easily to attribute an explicit ID for each of them : strGiSj where i is the group and j the string in the group.
Next, how about the hideNode function:
function hideNote(notes) {
makeItHappen(Math.ceil(notes.length / 4));
notes.forEach(function(n, i){
var values = n.match(/s(\d)f(\d)/); // values[1] = string, values[2] = fret
var parentEl = $("#stringG" + (Math.ceil((i + 0.5) / 4)) + "S" + values[1]);
var child = $("<div></div>")
.addClass("fret")
.css("left", (10+ (i%4) * 25) + "px")
.text(values[2]);
parentEl.append(child)
});
}
We create the amount of groups needed (amount of notes / 4 rounded to next int). For each note in your array, we retrieve the string and the fret with a regular expression /s(\d)f(\d+)/:
\d matches a digit
\d+ matches one or more digits
Parenthesis allow to retrieve values easily
Next, we just have to retrieve the appropriate group, and retrieve the associated div with good id, then create the fret element and place it.
The full code looks like this:
"use strict"
$(document).ready(function() {
var notes = ['s6f1', 's5f5', 's4f7', 's3f6', 's2f5', 's1f3', 's6f8', 's5f1', 's4f6', 's3f1', 's2f3', 's1f3', 's6f9', 's5f17', 's4f19'];
hideNote(notes);
});
function hideNote(notes) {
makeItHappen(Math.ceil(notes.length / 4))
notes.forEach(function(n, i){
var values = n.match(/s(\d)f(\d+)/);
var parentEl = $("#stringG" + (Math.ceil((i + 0.5) / 4)) + "S" + values[1]);
var child = $("<div></div>")
.addClass("fret")
.css("left", (10+ (i%4) * 25) + "px")
.text(values[2]);
parentEl.append(child)
})
}
function makeItHappen(nbGroup) {
for(var g = 1; g <= nbGroup; g++){
var six = document.createElement('div');
six.className = "six_line";
for (var i = 6; i >= 1; i--) {
var string = document.createElement('div');
string.className = "deco";
string.id = "string" + ('G' + g + 'S' + i);
six.append(string);
}
$('#output').append(six);
}
}
Here is a codepen with a working sample.
I need help with optimizing this small system that takes in a string and looks for any words that match the words stored in an array. The system should reprint the same string with the new words every time there was a match. However, it only changes after the first match currently.
Sample text:
his de is good
but his en is worse then nl
The result for the above is currently:
his Dutch is good
but his English is worse then nl
But the result I want to get is:
his Dutch is good
but his English is worse then Danish
So how can I fix the system to print the second result?
Here is my system in JSFIDDLE.
function check(string, wrapper) {
var terms = ['de', 'en', 'nl'];
var match = false;
for(var i=0;i<terms.length && !match;i++) {
if(string.indexOf(terms[i]) > -1) {
match = true;
var newString='';
wrapper.css("background", "#a1e4ff");
var matchString = string.substring(string.indexOf(terms[i]), (string.indexOf(terms[i])+terms[i].length));
var rx = RegExp("\\b" + matchString + "\\b", "g");
switch(matchString) {
case 'de':
newString = string.replace(rx, "Dutch");
break;
case 'en':
newString = string.replace(rx, "English");
break;
case 'nl':
newString = string.replace(rx, "Danish");
break;
default:
alert('no matches');
}
$(".corrections").append("<li>" + newString + "</li>");
}
}
}
$(document).ready(function() {
$('textarea').focusout(function() {
var x = $(this).val();
$('.orig-list').html(x.replace(/\n(?!>)/g, '<li>'));
});
$('#down').click(function() {
$('.orig-list li').each(function() {
var phrase = $(this).text();
var matchHighlight = $(this);
check(phrase, matchHighlight);
});
});
});
The main point is that you did not add <li> tag before the first item, and that is why you $('.orig-list li').each did not select it and that is why the string consisting of one line did not work. Change the $('.orig-list').html() code to
$('.orig-list').html("<li>" + x.replace(/\n(?!>)/g, '<li>'));
Besides, it will be much easier if you put the terms with replacements into a dictionary, and use it like
if (/en|de|nl/.test(string)) {
wrapper.css("background", "#a1e4ff");
newString = string.replace(/en|de|nl/g, function(x) {
return terms[x] || "";
});
$(".corrections").append("<li>" + newString + "</li>");
}
See the updated snippet below.
function check(string, wrapper) {
var terms = {'de':'German', 'en':'English', 'nl':'Dutch'};
if (/en|de|nl/.test(string)) {
wrapper.css("background", "#a1e4ff");
newString = string.replace(/en|de|nl/g, function(x) {
return terms[x] || "";
});
$(".corrections").append("<li>" + newString + "</li>");
}
}
$(document).ready(function() {
$('textarea').focusout(function() {
var x = $(this).val();
$('.orig-list').html("<li>" + x.replace(/\n(?!>)/g, '<li>'));
});
$('#down').click(function() {
$('.orig-list li').each(function() {
var phrase = $(this).text();
var matchHighlight = $(this);
check(phrase, matchHighlight);
});
});
});
span#down {
background: #4f5152;
width: 100px;
color: #fff;
display: block;
margin-top: 20px;
padding: 9px;
border-radius: 4px;
line-height: 1;
font-weight: 600;
cursor:pointer;
margin-bottom: 50px;
}
.receiver div {
border: 1px solid red;
width: 40%;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content-wrapper">
<div class="receiver">
<textarea></textarea>
<span id="down">Generate List</span>
<div>
<h4>Generated List with unicode errors</h4>
<ol class="orig-list"></ol>
</div>
<div class="corrections-wrapper">
<h4>Corrected Names</h4>
<ol class="corrections"></ol>
</div>
</div>
</div>
The following fiddle allows text to be imported into a <textarea> and dynamically generated into equal paragraphs. Is it possible to break the text in to paragraphs without breaking the text in the middle of a sentence? I want the length of each paragraph to be at or near the ChunkSize or user-adjusted limit, with each paragraph's element on the page being the same height.
If an updated fiddle could please be provided, would be extremely helpful, as I am still new to coding.
Thank You!
Fiddle
$(function() {
$('select').on('change', function() {
//Lets target the parent element, instead of P. P will inherit it's font size (css)
var targets = $('#content'),
property = this.dataset.property;
targets.css(property, this.value);
sameheight('#content p');
}).prop('selectedIndex', 0);
});
var btn = document.getElementById('go'),
textarea = document.getElementById('textarea1'),
content = document.getElementById('content');
chunkSize = 100;
btn.addEventListener('click', initialDistribute);
content.addEventListener('keyup', handleKey);
content.addEventListener('paste', handlePaste);
function initialDistribute() {
custom = parseInt(document.getElementById("custom").value);
chunkSize = (custom > 0) ? custom : chunkSize;
var text = textarea.value;
while (content.hasChildNodes()) {
content.removeChild(content.lastChild);
}
rearrange(text);
}
function rearrange(text) {
var chunks = splitText(text, false);
chunks.forEach(function(str, idx) {
para = document.createElement('P');
para.classList.add("Paragraph_CSS");
para.setAttribute('contenteditable', true);
para.textContent = str;
content.appendChild(para);
});
sameheight('#content p');
}
function handleKey(e) {
var para = e.target,
position,
key, fragment, overflow, remainingText;
key = e.which || e.keyCode || 0;
if (para.tagName != 'P') {
return;
}
if (key != 13 && key != 8) {
redistributeAuto(para);
return;
}
position = window.getSelection().getRangeAt(0).startOffset;
if (key == 13) {
fragment = para.lastChild;
overflow = fragment.textContent;
fragment.parentNode.removeChild(fragment);
remainingText = overflow + removeSiblings(para, false);
rearrange(remainingText);
}
if (key == 8 && para.previousElementSibling && position == 0) {
fragment = para.previousElementSibling;
remainingText = removeSiblings(fragment, true);
rearrange(remainingText);
}
}
function handlePaste(e) {
if (e.target.tagName != 'P') {
return;
}
overflow = e.target.textContent + removeSiblings(fragment, true);
rearrange(remainingText);
}
function redistributeAuto(para) {
var text = para.textContent,
fullText;
if (text.length > chunkSize) {
fullText = removeSiblings(para, true);
}
rearrange(fullText);
}
function removeSiblings(elem, includeCurrent) {
var text = '',
next;
if (includeCurrent && !elem.previousElementSibling) {
parent = elem.parentNode;
text = parent.textContent;
while (parent.hasChildNodes()) {
parent.removeChild(parent.lastChild);
}
} else {
elem = includeCurrent ? elem.previousElementSibling : elem;
while (next = elem.nextSibling) {
text += next.textContent;
elem.parentNode.removeChild(next);
}
}
return text;
}
function splitText(text, useRegex) {
var chunks = [],
i, textSize, boundary = 0;
if (useRegex) {
var regex = new RegExp('.{1,' + chunkSize + '}\\b', 'g');
chunks = text.match(regex) || [];
} else {
for (i = 0, textSize = text.length; i < textSize; i = boundary) {
boundary = i + chunkSize;
if (boundary <= textSize && text.charAt(boundary) == ' ') {
chunks.push(text.substring(i, boundary));
} else {
while (boundary <= textSize && text.charAt(boundary) != ' ') {
boundary++;
}
chunks.push(text.substring(i, boundary));
}
}
}
return chunks;
}
#text_land {
border: 1px solid #ccc;
padding: 25px;
margin-bottom: 30px;
}
textarea {
width: 95%;
}
label {
display: block;
width: 50%;
clear: both;
margin: 0 0 .5em;
}
label select {
width: 50%;
float: right;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
font-family: monospace;
font-size: 1em;
}
h3 {
margin: 1.2em 0;
}
div {
margin: 1.2em;
}
textarea {
width: 100%;
}
button {
padding: .5em;
}
p {
/*Here the sliles for OTHER paragraphs*/
}
#content p {
font-size: inherit;
/*So it gets the font size set on the #content div*/
padding: 1.2em .5em;
margin: 1.4em 0;
border: 1px dashed #aaa;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h3>Import Text below, then press the button</h3>
<textarea id="textarea1" placeholder="Type text here, then press the button below." rows="5">
</textarea>
<input style="width:200px;" id="custom" placeholder="Custom Characters per box">
<br>
<button style="width:200px;" id="go">Divide Text into Paragraphs</button>
</div>
<div>
<h3 align="right">Divided Text Will Appear Below:</h3>
<hr>
<div id="content"></div>
</div>
You can take the approach of splitting the text in to sentences, and then adding sentences to the paragraphs until you reach the desired length (chunkSize in your code).
function splitText (text) {
var paragraph = "",
paragraphs = [],
sentenceRegex = /[^\.!\?]+([\.!\?]+|\s*$)/g,
sentences = text.match(sentenceRegex);
sentences.forEach(function createParagraphs (sentence, index) {
paragraph += sentence;
if (paragraph.length >= chunkSize || index === sentences.length - 1) {
paragraphs.push(paragraph);
paragraph = "";
}
});
return paragraphs.length === 0 ? [text] : paragraphs;
}
https://jsfiddle.net/DirectCtrl/95kuyw4g/4/ (Tried to keep the rest of the code as similar to what it was as possible).
This doesn't deal with margins (meaning you could potentially get much longer paragraphs if you have sentences which end near the boundaries or go well beyond the boundary limit), though those kinds of problems are very likely to appear regardless on edge cases (e.g. with a chunkSize of 100 characters, what do you do when the first sentence is 40 characters and the second is 160 characters?). Tweaking this to use a margin should be pretty trivial, though, if that is a requirement. As the number of characters per paragraph increases, this would become less of an issue.
How does citicards.com implement the login ID text box with special mask?
When you type "johndoe" and focus out the textbox becomes "jo***oe"
Is there a HTML5 mask with pattern?
Here is a sample implementation of the desired behaviour using pure javascript. This is just for a sample. You may need to do length check etc before actually using substr
document.querySelector("input#accountName").addEventListener("blur", function() {
var value = this.value;
document.querySelector("#maskedAccountName").textContent=this.value.substr(0,2)+this.value.substr(2,value.length-2).replace(/./g,"*")+this.value.substr(this.value.length-2, this.value.length);
this.style.display = "none";
document.querySelector("#maskedAccountName").style.display = "block";
}, false);
document.querySelector("#maskedAccountName").addEventListener("click", function() {
this.style.display = "none";
document.querySelector("input#accountName").style.display = "block";
document.querySelector("input#accountName").focus();
}, false);
div#maskedAccountName {
border: 1px solid rgba(231, 231, 231, 0.67);
padding: 2px;
display: none;
border-top-style: inset;
-webkit-appearance: textfield;
background-color: white;
width: 120px;
}
<input type="text" id="accountName">
<div id="maskedAccountName">
</div>
The reason why I'm not changing the existing input value is I may not be able to read the original value when accessed inside the form submit. So i've created a hidden div which is shown in place of the original input element. You can style the div to be same as the input element using CSS.
You have to use JS/jQuery. First count how mush letters from start and end you wish to take off, then replace everything else with * and append to fake input field.
You can see that in action here (replace opacity to 0 to completely hide input field, display: none will not work here, because you have to click on input itself):
$(document).ready(function() {
$("#hField").focusin(
function() {
$('#hFieldSp').text($(this).val());
});
$("#hField").focusout(function() {
var start = '';
var end = '';
var value = $(this).val();
var stars = '';
if (value.length < 3) {
return;
}
if (value.length > 6) {
start = value.substring(0, 2);
end = value.substring(value.length - 2);
stars = '*'.repeat(Math.max(1, value.length - 4));
} else {
start = value.substring(0, 1);
end = value.substring(value.length - 1);
stars = '*'.repeat(Math.max(1, value.length - 2));
}
$('#hFieldSp').text(start + stars + end);
});
$(document).on('input paste change', '#hField', function() {
$('#hFieldSp').text($(this).val());
});
});
String.prototype.repeat = function(num) {
return new Array(num + 1).join(this);
}
.wrapper {
float: left;
position: relative;
}
#hField,
#hFieldSp {
width: 100px;
height: 30px;
line-height: 30px;
border: 1px solid #ddd;
}
#hField {
opacity: .2;
position: absolute;
left: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div id="hFieldSp"></div>
<input type="text" id="hField" />
</div>
I would use a dummy input for the display. Then on blur, transfer the value to a hidden input and alter the text in the dummy. You might also want the reverse in place in case the user wants to alter the value: on focus, copy the value from the hidden input to the dummy. Here's a sample, no jQuery required, and if there are less than 5 characters in the input, it will make all *s instead.
var start = 0;
var end = 4;
var dummy_user = document.getElementById("user");
var actual_user = document.getElementById("hidden_user");
dummy_user.addEventListener("blur", function() {
actual_user.value = dummy_user.value;
if (dummy_user.value.length > 4) {
start = 2;
end = dummy_user.value.length - 2;
}
var val = "";
for (var i = 0; i < start; i++) {
val += dummy_user.value[i];
}
for (i = start; i < end; i++) {
val += "*";
}
for (i = end; i < dummy_user.value.length; i++) {
val += dummy_user.value[i];
}
dummy_user.value = val;
});
dummy_user.addEventListener("focus", function() {
this.value = actual_user.value;
});
<form action="">
<input type="text" name="user" id="user">
<input type="hidden" name="hidden_user" id="hidden_user" value="">
<input type="password" name="password">
<input type="submit" value="Sign in">
</form>
I need to truncate the text(with ... at the end) and on mouseover the entire text should get expanded.
I have tried to truncate by the below code. Problem with this code is, it expands the content on click of the ... but I need it to get opened when user mouse over anywhere on p tag
var len = 100;
var p = document.getElementById('truncateMe');
if (p) {
var trunc = p.innerHTML;
if (trunc.length > len) {
trunc = trunc.substring(0, len);
trunc = trunc.replace(/\w+$/, '');
trunc += '<a href="#" ' +
'onmouseover="this.parentNode.innerHTML=' +
'unescape(\''+escape(p.innerHTML)+'\');return false;">' +
'...<\/a>';
p.innerHTML = trunc;
}
}
DEMO
I am looking for an easy way to do it.
Thanks in advance.
PS: No CSS solution please, as it is not compatible with all browsers (IE7).
You can use Jquery Like this :
HTML :
<p>Some Text</p>
JS :
var lengthText = 30;
var text = $('p').text();
var shortText = $.trim(text).substring(0, lengthText).split(" ").slice(0, -1).join(" ") + "...";
$('p').text(shortText);
$('p').hover(function(){
$(this).text(text);
}, function(){
$(this).text(shortText);
});
DEMO : http://jsfiddle.net/1yzzbv4b/2/
Or you can also achieve this with css3 property text-overflow:ellipsis;
CSS :
p{
text-overflow:ellipsis;
width: 250px;
white-space: nowrap;
overflow: hidden;
}
p:hover{
text-overflow:clip;
width:auto;
white-space: normal;
}
DEMO : http://jsfiddle.net/1yzzbv4b/
Assuming that you set the class of your p-elements to be of escape-text, the following jQuery-code should work.
$(document).ready(function() {
$ps = $('.escape-text');
$ps.each(function(i, el) {
$(el).data('full-text', el.innerHTML);
strip(el);
});
$ps.on('mouseover', function() {
$(this).text($(this).data('full-text'));
}).on('mouseout', function() {
$(this).text(strip(this));
})
});
var length = 100;
var strip = function(el) {
el.innerHTML = el.innerHTML.substr(0, length) + '...';
}