php - wordwrap with html - php

The problem is simple:
Using tinyMCE, I am storing html data into the database. Then at the home page, I am showing 5 latest posts I've inserted into the database. I want to crop each of these posts to the specified length if they exceed it and put a continue reading link (can be a soft crop here, doesn't have to be rigid).
It would be easy to crop the string with php's wordwrap function but since the string is composed of html I don't wanna ruin the html code by cropping it from a wrong place.
So the question is: Is there an easy way to crop this, (can be a css, javascript solution as well) or do I have a write a long function with lots of checks to implement such a basic feature? I was thinking to use the DOM class but before creating function I just wanted to ask you guys.
EDIT
Styling is essential to me. So there is no possibility to strip the tags.
Thanks in advance.

One possible solution could be to strip tags, if the styling of this HTML is not vital, so you can cut wherever you want:
http://php.net/manual/es/function.strip-tags.php
Another solution for CSS3 browsers, would be to use text-overflow, read more about this:
http://davidwalsh.name/css-ellipsis

assuming you use jQuery
the javascript
$(function () {
$('p').filter(function () {
return $(this).height() > 50;
}).addClass('collapsed').css('position', 'relative').append('read more');
$('.expand').on('click', function(){
if($(this).parents('.collapsed').length)
$(this).parents('.collapsed:first').removeClass('collapsed')
else
$(this).parents(':first').addClass('collapsed')
})
})
the css
.collapsed{overflow: hidden; height: 20px; margin-bottom: 10px; position: relative}
.expand{position: absolute; right: 0; bottom: 0; background: #fff; padding: 0 0 0 15px;}
Just a proof of concept. Needs JS optimization

Related

How to style a dynamic html created by PHP

My php page will generate a dynamic html.
The following is the output;
<label class="required">suject *</label>
Unfortunately i can't edit the html
Now I need to show '*' in red color.
How I can write the css for that?
There are several ways to do this:
If you have access to the PHP source code, then you can modify the output accordingly, perhaps wrap the * with <span> tags and style the accordingly.
Alternative, you can use JS to do the same:
$(document).ready(function() {
// Loop through all labels with required class
$('label.required').each(function() {
$(this).html($(this).html().replace(/\*/g, '<span class="asterisk">*</span>'));
});
});
And in your CSS, you can style it in any way you want:
.required .asterisk {
color: red;
}
See fiddle here - http://jsfiddle.net/teddyrised/JTesR/
Even better: Using CSS
This is written in light of trying to be as semantically correct as possible - you can remove the * character with JS (or changing the PHP code), but use a pseudo-class to add it back to the label element:
label.required:after {
content: '*';
color: red;
}
CSS allows you to select elements (and a limited number of pseudo-elements such as :first-line).
There is no way to select "last character", "characters matching *" or anything else that would make what you want achievable.
You have to modify the DOM. The easiest way to do that would be to modify the HTML it is generated from. The hacky approach would be to modify it with JavaScript after it has loaded.
This is based on Terry's answer: You can simply use :after to simulate effect, and place that content over generated HTML.
label.required:after {
content: '*';
color: red;
background:white;
position: relative;
left: -8px;
}
http://jsfiddle.net/x2KN7/
Its not possible through CSS, but you can do something with the javascript. If this content is generated on page load then you can hook page load event, get reference to this element and make changes.
<script type='text/javascript'>
document.onload = function (e) {
var col = document.getElementsByClassName("required");
for (var i=0;i<col.length;i++) {
if (col[i].innerHTML == "subject *") {
col[i].innerHTML = "subject <span style='color:red'>*</span>";
}
}
}
</script>
Try the above, hopefully it will solve your problem. I have used simple javascript, but if you know a javascript library (YUI, dojo, jquery) then you can do this in 1 or 2 line.

Continuing overflowed text in a different div?

What I am trying to do is create a site that displays my rants in faux letter form.
I want the "paper size" (div size) to be fixed, and the text to continue on the second piece of paper (a second div) displayed just below the first paper like this..
I apologize, being a new user, I am not allowed to post the
screenshots I have created to help explain my situation, so am forced
to link until I have enough reputation points:
http://img16.imageshack.us/img16/5538/pagesuc.jpg
ONLY FOR THE SAKE OF SIMPLICITY: I've created a simple html/css page to demonstrate in the simplest form what I am trying to accomplish with the code:
<style type="text/css">
* {
margin: 0;
padding: 0;
border: 0;
}
.container {
background: #FFFFFF;
width: 600px;
height: 400px;
margin: 0 auto;
}
#lbox {
background: #F00;
width: 300px;
height: 400px;
float: left;
}
#rbox {
background: #00F;
width: 300px;
height: 400px;
float: right;
}
.flowcontent {
padding: 10px 50px;
}
</style>
<div class="container">
<div id="lbox">
<div class="flowcontent">
<p>Lorem Ipsum...</p>
</div>
</div>
<div id="rbox">
<div class="flowcontent"> </div>
</div>
</div>
Screenshot:
I apologize, being a new user, I am not allowed to post the
screenshots I have created to help explain my situation, so am forced
to link until I have enough reputation points:
http://img689.imageshack.us/img689/7853/overflowc.jpg
In this case I would like the overflow from the red div to continue in the blue div on the right.
I realise this may not be possible with HTML/CSS alone, but was hoping maybe CSS3 might have some new tricks for this, as it has more advanced column handling.. If that's a no go, does anyone have a suggestion for a logical way to go about breaking this up using PHP or even JavaScript or JQuery?
I know PHP, but am still a JS/JQ newb so I have provided some (hopefully) very simple example code for anyone to plug in their own JS/PHP examples.
Anyway, thanks for your time.
I came up with a small JS Script that might help you out. It's far from perfect, but might give you a decent starting point. Essentially, it loops through your large text and looks for a scrollbar to appear. You may need to alter the calculations just a bit.
JSFiddle http://jsfiddle.net/Tt9sw/2/
JS
var currentCol = $('.col:first');
var text = currentCol.text();
currentCol.text('');
var wordArray=text.split(' ');
$.fn.hasOverflow = function() {
var div= document.getElementById($(this).attr('id'));
return div.scrollHeight>div.clientHeight;
};
for(var x=0; x<wordArray.length; x++){
var word= wordArray[x];
currentCol.append(word+' ');
if (currentCol.hasOverflow()){
currentCol = currentCol.next('.col');
}
}
HTML
<div class="col" id="col1">Lorem Ipsum ....... LONG TEXT .......</div>
<div class="col" id="col2"></div>
<div class="col" id="col3"></div>
<div class="col" id="col4"></div>
<div class="col" id="col5"></div>
CSS
.col{
width:200px;
float:left;
height:200px;
border:1px solid #999;
overflow:auto;
font-family:tahoma;
font-size:9pt;
}
UPDATE
For this example, you must include the jQuery Libray in your scripts.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script>
PS - if you get to know jQuery, you will start to use it for everything. It greatly increases cross-browser compatibility and simplifies many common tasks.
What you want is CSS Regions module proposed by Adobe and currently supported by zero browsers. Adobe did release a very rough webkit-based browser for playing with the spec if you're really interested. But as others have said, right now you're SOL and will need to find another solution.
http://www.adobe.com/devnet/html5/articles/css3-regions.html
http://labs.adobe.com/technologies/cssregions/
http://dev.w3.org/csswg/css3-regions/
CSS3 has Multi-column Layout Module. However, I doubt it is widely supported to the moment.
Test it on your target browsers: http://www.quirksmode.org/css/multicolumn.html
You cannot do this with HTML and CSS only. CSS is targeted primarily at web browsers, and the layout model is that of a document on a vertically expanding surface. You can make boxes auto-height (which is the default), or fixed-height, but you cannot change the way content belongs to a parent box (which is what you would need for this to work).
A few options you could consider, if this is really important to you:
Use the paged-media features that are built into CSS to provide nice paging when rendered onto paged media (such as printouts); I'm talking about properties like page-break-after, page-break-before, etc. You won't get pages in a web browser, but at least you can control how it prints on physical paper
Write some incredible clever javascript that partitions your content into pages. There's a bit of a vicious circle here, because you won't know if your content fits until you try, so you may have to reflow several times in trial-and-error fashion. If your content has a special structure you can take advantage of, e.g. a poem form, where all line breaks are explicit, or if you use a fixed-width font, then a one-pass algorithm is possible, and you may even be able to do it server-side, using PHP, ASP.NET, or any other server-side scripting technology.
Use a different document format that gives you control over pages and absolute placement of elements within a page structure, e.g. PDF. (I wouldn't recommend using PDF for general web documents though; from a user's perspective, PDFs aren't convenient at all).
Use something like Flash or Silverlight to produce the desired layout. This, too, is something you should avoid unless there are other reasons why you'd be using it anyway; also, the formatting algorithm suffers from the same problems as a javascript implementation would, except that you have more control over the rendering part (fonts, kerning, etc.).
For most things on the web, however, I'd just let go of the idea and go with a more realizable design.
If you know how many characters one of your pages hold you can separate your string dynamically using javascript or php and then print the first part of the array in the first "paper sheet" and the second on the second.
You won't be able to do that with just HTML/CSS
Shapes by Adobe does exactly that, however, it has a very limited browser support.
IE: 11+
Chrome: 37+
FireFox: 32+

Best way to make an easy to edit "thermometer for donations"

I am trying to think of the best way to make a really small thermometer image, that can be easily edited by typing in a number (dollar value) and having the image change based on the value.
The simplest way to achieve this is the best. It will be going online onto a site that is using a CMS called spip.
Does anything small like this exist? and if i have to create it myself what's the best way to go about it?
The basic concept here is very simple; check out this fiddle. It's a basic nested div:
<div id='thermometer'>
<div id='level'>
</div>
</div>
which takes input from some form element:
<input type='text' id='fill'>
and some simple styling:
#thermometer { height: 15px; width: 100px; margin:5px; padding:0; border: #cccccc solid 1px; }
#level { height: 15px; width: 40px; margin: 0; padding:0; border-right: 1px solid #666666; background: #ffcccc; }
and a tiny bit of javascript:
$('#fill').keyup(function() {
$('#level').css('width',this.value);
});
Granted, this has no error checking, and could use a lot more work to make it robust, but it does what you ask it to do.
Layer two divs, each having part of the thermometer image, and hide parts of the red indicator bit div.
html 5 canvas + jquery or, a vary simple method will be to use divs, one on top of the other to simulate the thermometer levels. and simply change the background to red when the value increase or decrease
Something like this should work:
<?php
$goal = 100; // need to raise $100
$done = 78; // got $78 so far, e.g. 78% done
$full_size = '200'; // 200px
?>
<style type="text/css">
#thermometer {
width: <?php echo floor($full_size * ($done / $goal)) ?>px;
height: 1em;
color: red;
}
</style>
<div id="thermometer"></div>
Create a small text input form element that the user can enter a dollar amount into. Use jQuery and hook that element's onblur event, and within that hook, redraw the image as you want, scaling and all.
Don't have an example, but some simple steps for a PHP + CSS solution.
Use PHP to calculate the percentage of your goal met.
Use this percentage to calculate a CSS background-position property to show more or less of the thermometer background image by setting the style attribute inline with PHP.
UPDATE
For everyone that is gawking at doing this with PHP - how do you think JavaScript is getting the value to begin with? If PHP generates the page output and calculates the value, having PHP output the style directly is perfectly acceptable and keeps this at the source.

How to make a block (or a region) float in Drupal?

I saw that there's a module called Floating block that should do what I'm searching for: but it duplicates the floating block, making it totally unusable.
Can you please tell me some other ways to accomplish that?
By "float" do you mean have the CSS attribute "float" applied to it?
You can do this easily by looking at the HTML source code to get the Block div's id (usually "block-block-3" or something) then adding a new style is the CSS to float it.
Look for this in the HTML source to identify the correct block ID:
<div id="block-block-4" class="yadda yadda">
My block content
</div>
Then in your active theme's CSS file add an entry like this:
#block-block-4 { float: left; }
If you mean you want it to float in the same position as the user scrolls, you can use a jQuery plugin pretty easily to do that. I have used StickyFloat before with good success. Use the trick above to identify the correct block id to bind it to. Include jQuery and the plugin scripts, then bind it like so:
$('#block-block-4').stickyfloat({ duration: 400 });
Even better, if you use CSS correctly you can accomplish this without any additional modules or plugins.
The "Floating Block" module really only selets the block and set's it's position to fixed.
With the example above:
#block-block-4 {
position: fixed;
top: 100px;
left: 100px;
}
position: [fixed, absolute, relative]
these values override float:
if you need to force it, use
position: inherit !important;
then you should be able to use
float: [left, right];

How to center a div generated dynamically?

I generate a div for my javascript automated validation script. It is generated with below code:
var alertbox = document.createElement("div");
Now how do i center that div programatically both horizontally and vertically?
Note: Currently I am showing an alert box but once i know how to center a div, i will
replace the alertbox with this dynamically generated div which will also provide some
lightbox-like effect.
Thanks
Note: For reference, you can download latest version of this script here.
Please note that i dont want to use external css for this because this is validation script and it should be able to do it programatically. For example:
using something like this can be helpful:
alertbox.style.position: whatever
....
It's a matter of applying the same CSS rules as you would have with static content. Horizontal centering can be achieved as described in this article - basically you give the div a fixed with and set left and right margins to auto. Vertical centering is a bit trickier - a few approaches are discussed here and detailed in this this blog post.
The tidiest way is probably to define a CSS class that takes care of the centering and then apply that class to the dynamically generated element like this:
alertbox.className = "myCssClass";
Update:
Since you are already using JavaScript for creating the div, you could of course use it for the centering as well (in combination with CSS absolute positioning) - that would actually probably be a cleaner solution (due to the hackishness of the CSS vertical centering). Exactly how you do this depends a bit on what tools you are using - it's probably much easier to achieve with a JS framework such as Prototype or jQuery than with "raw" JavaScript since browsers handle window/browser heights a bit differently.
If you are using jQuery, why not use the validation plugin?
You should be able to combine it with a modal window (like SimpleModal).
But if you don't want to change what you have already done, try something like this:
I would just apply some CSS rules to the div to position it (I've included an overlay which covers up the page and puts the alertbox on top):
Note: The reason the div is positioned to the far left is because you need to get the dimensions of the div with the contents inside. A hidden div will have a height and width of zero. Once the size is determined, it calculates the center of the page and positions the div.
CSS
#overlay {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
background: #000;
opacity: 0.8;
filter: alpha(opacity=80);
z-index: 100;
}
#alertbox {
background: #444;
padding: 10px;
position: absolute;
left: -99999px;
top: 0;
z-index: 101;
}
Script
function alertBox(alertMsg){
// Add overlay
$('<div id="overlay"></div>')
.hide()
.appendTo('body')
.fadeIn('slow');
// Add alert
$('<div id="alertbox"></div>')
.html(alertMsg)
.appendTo('body');
// calculate & position alertbox in center of viewport
var abx = $('#alertbox');
var abxTop = ($(window).height() - abx.height())/2;
var abxLft = ($(window).width() - abx.width())/2;
abx
.hide()
.css({ top: abxTop, left: abxLft })
.fadeIn('slow');
// add click to hide alertbox & overlay
$('#overlay, #alertbox').click(function(){
$('#overlay, #alertbox').fadeOut('slow',function(){
$('#alertbox').remove();
$('#overlay').remove();
});
})
}
For whatever reason, I have not been able to center a DIV using margin-right and margin-left. What I have found works better is to encapsulate them within a table (it's a bit globby code, but it works for me). And you can use the DOM style object to modify the margin as follows:
<table style="margin-left:auto;margin-right:auto;"><tr><td><div id="yourdiv"></div></td></tr></table>

Categories