Read more on Database result - javascript

Hi there my code is quite simple but Id like for the design purposes to keep everything neat , at the moment Im pulling all the description which is like Some could be huge others can be quite small , anyway to make it fair I decided to make a read more button and once I click it just expand on the text like , SO somehow to make it show the first 160 characters after that ... then ReadMore link button that when you click it expands and shows the whole text
Heres my script that I use for now :
<p><?PHP echo $thismovie['description']; ?></p> <div style="text-align:right">
So I would like to know how this is done and if possible only using javascript, thanks !

While you could of course use PHP, another way is to use the text-overflow property of css correctly.
This method will put less strain on the server, especially when there are a bunch of descriptions on the page. Using PHP to concatenate every single one is not efficient and is not the correct way to do this.
Removing a class is much simpler. And you can add it back when you want to show less.
<style>
.ellipsis {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
height: 14px;
}
.description {
width: 300px;
background: #ccc;
padding: 3px;
margin-top: 30px;
margin-bottom: 0;
}
</style>
<!-- It is likely you would use a PHP loop for this but for illustration
purposes I've listed them out -->
<p class="description ellipsis"><?=$movie[0]['description']?></p>
Read More
<p class="description ellipsis"><?=$movie[1]['description']?></p>
Read More
<p class="description ellipsis"><?=$movie[2]['description']?></p>
Read More
<!-- use as many as you want with no additional strain on server. -->
WITH JQUERY... http://jsfiddle.net/kx2nbv3z/
<!-- Include jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document)
.on('click','.read-more',function() {
$(this).removeClass('read-more').addClass('show-less').html('Show Less').prev('.description').removeClass('ellipsis');
})
.on('click','.show-less',function() {
$(this).removeClass('show-less').addClass('read-more').html('Read More').prev('.description').addClass('ellipsis');
})
;
</script>
WITH PURE JAVASCRIPT... http://jsfiddle.net/8wsbw0u8/
<script>
if (document.body.addEventListener) {
document.body.addEventListener('click',yourHandler,false);
}
else {
document.body.attachEvent('onclick',yourHandler);//for IE
}
function yourHandler(e) {
e = e || window.event;
var target = e.target || e.srcElement;
prev = target.previousSibling.previousSibling;
if (target.className.match(/read-more/)) {
target.className="show-less";
target.innerHTML = "Show Less";
prev.setAttribute("class","description");
console.log(prev);
}
else if (target.className.match(/show-less/)) {
target.className="read-more";
target.innerHTML = "Read More";
prev.setAttribute("class","description ellipsis");
}
}
</script>

for PHP way:
$firstdesc=substr($thismovie['description'], 0, 160);
and when read-more pressed.
$totaldesc=substr($thismovie['description'], 160);
Ofcourse you can do it with Javascript too.

use the css style `text-overflow: ellipsis; and jquery for the full feature.
$('#read-more').click(function() {
$('#description').css('width','100%');
});
#description {
white-space: nowrap;
width: 12em;
overflow: hidden;
text-overflow: ellipsis;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="description">This is some long text that will not fit in the box</div> <a id="read-more" href="#">Read More</a>

Related

How do I detect hover to elements inside of each() in jQuery?

Thanks for taking a look at my question.
I'm trying to be able to hover over portfolio items but I need to loop through them using each() because I need some way of identifying each item.
I'm trying to hover over .recent-work-item to show .recent-work-item__overlay the .show-none class does display:none;
Neither the hover nor the on.("mouseenter", function(){}) is working.
Here is the HMTL:
<section class="recent-work-item" data-portfolio-id="rwi-<?php echo $i;?>">
<div class="recent-work-item__overlay show-none">
<h3 class="color-white bolder-font"><?php the_title(); ?></h3>
VIEW CASE
</div>
<div class="recent-work-img">
<img src="<?php echo get_template_directory_uri();?>/assets/img/work1.jpg" class="portrait">
</div>
Here is the jQuery:
$.each($('.recent-work-item'), function(){
var thisid = $(this).attr("data-portfolio-id");
console.log(thisid);
$("[data-portfolio-id="+"'"+thisid+"']").on('mouseenter', function(){
$(thisid).find('.recent-work-item__overlay').removeClass('show-none');
});
$("[data-portfolio-id="+"'"+thisid+"']").on('mouseleave',function(){
$(thisid).find('.recent-work-item__overlay').addClass('show-none');
});
});
This is not working, I can't get the hover to work and all I want to do is add or remove a class, can I not do this in each().
I've researched thoroughly in StackOverflow but can't find an answer. I would REALLY appreciate any help I can get on this.
I have test your code in my codepen, and the problem you should use $(this) than use $(thisid)
$.each($('.recent-work-item'), function(){
var thisid = $(this).attr("data-portfolio-id");
$("[data-portfolio-id="+"'"+thisid+"']").on('mouseenter', function(){
$(this).find('.recent-work-item__overlay').removeClass('show-none');
});
$("[data-portfolio-id="+"'"+thisid+"']").on('mouseleave',function(){
$(this).find('.recent-work-item__overlay').addClass('show-none');
});
});
Here look at my codepen
Here I have added an example that shows how you could use CSS to show/hide elements. It might not give you exact answer to your problem, but it will help you change your stylesheets as per your requirement.
Essentially, as per the discussion in comments, I don't think you need javascript to design the page the way you need it.
.container {
padding: 10px;
border: 1px solid gray;
}
.container > .hideOnHover {
display: block;
}
.container > .showOnHover {
display: none;
}
.container:hover > .hideOnHover {
display: none;
}
.container:hover > .showOnHover {
display: block;
}
<div class="container">
<div class="hideOnHover">
This text will be hidden on hover.
</div>
<div class="showOnHover">
This text will be shown on hover.
</div>
</div>

hide and show some div based on overflow

I have a dynamic table where i have hide after displaying first few words from a big text, if the user want to read the complete data he use to click view more button to read the complete data it works fine but the problem is how to show view more only for the rows which has overflowed text in it.
Php solution
simply in php we can use strlen() and can give condition like
if(strlen($data) > 100 ){
make visible
}
but cant assume how many chars exactly fit in the div because users may use enter so that the text count may vary so it wont works.
JavaScript solution
function checkOverflow(el)
{
var curOverflow = el.style.overflow;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflow = "hidden";
var isOverflowing = el.clientWidth < el.scrollWidth
|| el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
}
here i can find which div is overflowing, but since table was dynamic i don't know the exact ids i tried something like
<tr>
<td>
<div id="hidden_field_{$row['his_id']}">{$row['his_data']}</div>
</td>
<td>
<br/>
<?php
$check_overflow=echo "<script>checkOverflow(document.getElementById('hidden_field_".{$row['his_id']}."'));</script>";
if($check_overflow=="true"){
?>
<a id="get_view_more_{$row['his_id']}" onclick="view_more({$row['his_id'];});">View More</a>
<?php } ?>
</td>
</tr>
this function works fine outside php on the bottom of the page
<script>
alert(checkOverflow(document.getElementById('hidden_field_1')));</script>
you can use ellipsis.
#div2 {
white-space: nowrap;
width: 12em;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid #000000;
}
#div2:hover {
width: auto;
overflow: visible;
border: 1px solid #000000;
}
<p>This div uses "text-overflow:ellipsis": when you hover this it's visible</p>
<div id="div2">This is some long text that will not fit in the box</div>
just like this way.

HTML Elements inside Contenteditable?

I have a contenteditable tag, and I want my users to be able to type code into it. However, when I type into the contenteditable tag, my code shows up as text rather than an actual element. Is there a way for a user to create a full, working HTML element in a contenteditable box? I know it is possible for the client to insert code using javascript, but what about users who do not have access to javascript? How could users get code such as buttons inside a contenteditable box?
<p contenteditable="true">Try typing code in here as user, code will only be text...</p>
Is there a javascript way to accomplish this without JQUERY?
EDIT
I spent a long time searching for answers on Google, but nothing came up. The best solution I've gotten at this point has been #Dekel's comment on CKEditor. If there is another solution, I want to hear it. If there isn't, I'm sticking to CKEditor. I don't have much time, so I need a solution fast.
MORE EDIT =D
I recently developed my own answer to my question by looking at #Brandon's .replace answer (which only worked for client-coding, not user-coding) and modifying it to work with user-coding.
This isn't pretty, but you could make it work if you are looking to add HTML only. Otherwise an inline editor might work best.
var el = document.querySelector('p')
el.addEventListener('blur', function() {
var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
var html = this.innerHTML.replace(/&([^;]+);/g, (m, c) => map[c]);
this.innerHTML = html;
});
<p contenteditable="true">Try typing <b>code</b> in here as user, code will only be text...</p>
This answer is similar to #Brandon's idea, but is much more simple.
https://jsfiddle.net/azopqLe4/
<iframe width="100%" height="300" src="//jsfiddle.net/azopqLe4/embedded/js,html,result/dark/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
function convertit() {
var convet = document.getElementById("convet");
var text = convet.innerHTML;
var newtext;
newtext = text.replace(/</g, "<").replace(/>/g, ">");
convet.innerHTML = newtext;
}
//this version runs onrightclick =D
<p contenteditable="true" oncontextmenu="convertit();" id="convet">
Type some code here, then right-click... =D
</p>
In the second snippet, I typed <b>Test</b>, right-clicked it, and it became Test! My answer works through simple array replacement methods, although it is frustrating and time-wasting to keep right-clicking all the time. To prevent the actual contextmenu from popping up, just add .preventDefault().
You can't insert code, but you can insert DOMElements with JS. No need for jQuery.
var element=document.createElement("button");
element.innerHTML="Hello";
document.getElementById("yourContentEditable").append(element);
The idea with this would be to have a button to prompt for the code and insert it. Something like this:
(It is very ugly and buggy but it's just an example I just wrote)
var editorSelection=null;
function openCodePopup() {
//Store cursor position before editor loses focus
editorSelection=getEditorSelection();
//Open the popup
document.querySelector("#codePopup").style.display="block";
var ta=document.querySelector("#userCode");
ta.value="";
ta.focus();
}
function closeCodePopup() {
document.querySelector("#codePopup").style.display="none";
}
function insertCode() {
var code=document.querySelector("#userCode").value;
closeCodePopup();
if(code=="") return;
insertIntoEditor(html2dom(code));
}
function getEditorSelection() {
//TODO make crossbrowser
//TODO (VERY IMPORTANT) validate if selection is whitin the editor
var sel=window.getSelection();
if(sel.rangeCount) return sel.getRangeAt(0);
return null;
}
function insertIntoEditor(dom) {
if(editorSelection) {
editorSelection.deleteContents();
editorSelection.insertNode(dom);
} else {
//Insert at the end
document.querySelector("#editor").append(dom);
}
}
function html2dom(code) {
//A lazy way to convert html to DOMElements, you can use jQuery or any other
var foo=document.createElement('div'); //or you could use an inline element
foo.contentEditable=false;
foo.innerHTML=code;
return foo;
}
#editor {
height: 180px;
overflow: auto;
border: 1px solid #ccc;
}
#toolbar {
position: relative;
}
#codePopup {
position: absolute;
left: 10px;
top: 15px;
background-color: #fff;
border: 1px solid #ccc;
padding: 5px;
display: none;
}
#userCode {
display: block;
width: 200px;
height: 100px;
}
<div id="toolbar">
<button onclick="openCodePopup()"></></button>
<div id="codePopup">
<textarea id="userCode" placeholder="Type code here"></textarea>
<button onclick="insertCode()">Ok</button>
<button onclick="closeCodePopup()">Cancel</button>
</div>
</div>
<div contenteditable="true" id="editor"></div>
With the same idea you could create other options to convert element (example, text->link, etc.).

Show div if another div has content

So I don't get why this isn't working. I want to show a Div when another div has a value. I got this code from stackoverflow and it's pretty simple. But it doesn't work for me. No console errors..
$(document).ready(function(){
if ($(".txt").html().length > 0) {
$('.btn-01').show();
}
});
If the html value of .txt is larger then 0 then show btn-01.
But it doesn't. In my web inspector it just says:
<div style="display: block;" class="btn-01"><p>Things</p></div>
If I remove the script it says:
<div class="btn-01"><p>Things</p></div>
So it does do something. I tried changing the show to hide. But no go.
<div style="display: none;" class="btn-01"><p>Things</p></div>
I tried:
$(document).ready(function(){
if ($(".txt").html().length > 0) {
$('.btn-01').addClass('showme);
}
});
btn-01 css:
.btn-01 {
background: #f60;
color: #fff;
border-radius: 2px;
padding: 5px;
text-align: center;
margin: 40px auto 0px auto;
width: 90%;
}
But that didn't work either. Does anyone know whats going on here?
Maybe I should work with an else statement? Help would be much appreciated.
JsFiddle
You need to either set the button to display none prior to the window loading or add an "else" statement to hide the element:
.btn-01{
display:none;
}
OR
$(document).ready(function(){
if ($(".txt").html().length > 0) {
$('.btn-01').show();
}
else
{
$('.btn-01').hide();
}
});
See the fiddle: https://jsfiddle.net/r89gg7tp/
IMPORTANT TO CONSIDER
If you have entered a line break between the starting and closing tags of the element, this will add to the length. You need to set the txt div to be in the following format:
<div class='txt'></div>
It may be better to change your function to this:
$(document).ready(function(){
if ($(".txt").html().trim(' ').length > 0) {
$('.btn-01').show();
} else {
$('.btn-01').hide();
}
});
This way you trim the whitespace before checking.
See the second fiddle: https://jsfiddle.net/r89gg7tp/3/
You need to hide the btn-01 with a "display:none" in the stylesheet and then execute your script.
I think you are having a "display:none !important" which is overriding the jquery show() function inline style.
This might help you.
$(document).ready(function(){
if (!$.trim($(".txt").html())){
$('.btn-01').addClass('showme');
}
});
Please let me know if you've any queries.
You can use .contents() with .toggle():
$(document).ready(function() {
$('.btn-01').toggle($(".txt").contents().length > 0);
});
.btn-01{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="txt">
<h3>Things Title</h3>
</div>
<div class="btn-01">
<p>Things</p>
</div>
You guys where all right. I needed to place the code in some Session file (Ajax). Now its working with the original code and even some that you provide.
Thanks!

Truncate <a> tag text

In below code I'm attempting to truncate the <a> tag text :
<a href='test'>
<script>
truncate("truncate this text");
</script>
</a>
function truncate(string){
if (string.length > 5)
return string.substring(0,5)+'...';
else
return string;
};
https://jsfiddle.net/fcq6o4Lz/6/
But returns error Uncaught ReferenceError: truncate is not defined
How can this function be invoked from within <a> tag ?
Why
The reason you get the error is because your computer hasn't run the code that defined truncate yet. That function is running before the page finishes loading, that includes the JavaScript. Put the code in a window.onload with a setTimeout to be safe.
window.onload = function(){setTimeout(function () {
truncate("truncate this text");
},1);};
How
Also, unlike languages such as PHP. return won't place any text. Do something like:
<a id="result-location" href='test'>
<script>
window.onload = function(){setTimeout(function () {
document.getElementById('result-location').innerHTML = truncate("truncate this text");
},1);};
</script>
</a>
Fiddle
JSFiddle Fix
Remember to keep the function outside of a window.onload. You can change this in JSFiddle by setting it no no-wrap
CSS
You can use CSS to truncate text
.truncate {
width: 50px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
This will cause the text to truncate, after 50px;
.truncate {
width: 50px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
<a class="truncate">This text is truncated</a>
You don't invoke javascript code like this. Although you could use document.write to print result of javascript function into HTML element, it is stongly advised to avoid this, as it makes code really confusing.
Instead try something like this: select HTML element in question with CSS selector, select corresponding HTML element, and finally modify its inner content.
function truncate(selector) {
var obj = document.querySelector(selector),
string = obj.innerHTML;
if (string.length > 5) string = string.substring(0, 5) + '...';
obj.innerHTML = string;
};
truncate('#link');
truncate this text
You have to address the element with an ID, like this:
truncate this text
<script>
function truncate(id){
var string = document.getElementById(id).innerHTML;
if (string.length > 5) {
document.getElementById(id).innerHTML = string.substring(0,5)+'...';
}
};
truncate("test-id");
</script>
JSFiddle-Demo: http://jsfiddle.net/c8s3dc6q/1/
All javascript, including the function definition, should happen within a <script> ... </script> block. And that script block should stay in the end of the page, where the function "selects" the a tag with an id or class.
However I think that you might want to achieve the same results using pure CSS.
<a class="trim-text">This text should be trimmed!</a>
// add this to your css file / block
.trim-text {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
h1 {
max-width: 100px;
}
If you're open to a css only method there's a way to do that. It's based on width and not character count so more precise for styling.
fiddle
http://jsfiddle.net/Hastig/ufe1t66v/3/
html
<a class="truncated-anchors">This be way too long</a>
<a class="truncated-anchors">This too is too long</a>
<a class="truncated-anchors">This as well, far too long</a>
<a class="truncated-anchors">This one is even longer if I add some more words</a>
css
.truncated-anchors {
display: inline-block;
width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
A more thorough explanation
http://makandracards.com/makandra/5883-use-css-text-overflow-to-truncate-long-texts
And there are options to not use ellipsis and just end it immediately.
Simply define the function before its call in the code, then use document.write to receive the output of the function
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script>
function truncate(string){
if (string.length > 5)
return string.substring(0,5)+'...';
else
return string;
};
</script>
</head>
<body>
hhhhhhh<br />
<a href='test'>
<script>
document.write(truncate("truncate this text"));
</script>
</a>
</body>
</html>
Checkout this DEMO

Categories