I have a grid layout where I'd like to limit the height of the text, by cutting the text than adding more... link. I used the length to get where i have to cut the text. But when a post contains short lines and divided with enter than they count as a short text but their height is still high.
like this:
---------- ----------
|12345678| |12 |
|9more...| |34 |
| | |56 |
---------- |78 |
|9more...|
----------
So are there any solution to limit the height?
Ps. Sorry for my English.
Make a function which reads every post and if have more than Xpx of height, you will add that 'more...' anchor and also limit the height.
Example:
$('post').each(function(){
if($(this).height > 50){
$(this).css('max-height', '50px');
$(this).append('<a class="more">more....</a>');
}
});
Then you make another function that listens the class more and if the click its done you quit the max-height property and the more anchor.
Here is a good solution that will remove a single character from the content until it's height is as specified:
var maxHeight = 70;
var limiter = document.getElementById("limiter");
var height = limiter.clientHeight;
var content = limiter.innerText;
alert("Original Content:\n" + content);
var count = 0;
while (height > maxHeight && count < 100) {
count++;
content = content.substring(0, content.length - 1);
limiter.innerText = content + " more...";
height = limiter.clientHeight;
}
alert("Adjusted Content:\n" + content);
var html = limiter.innerHTML;
alert("Final HTML:\n" + html);
The count is there just to prevent getting stuck in an infinite loop, just in case. It is not necessary.
Fiddle: http://jsfiddle.net/38p8hhve/
Related
I'll try my best to explain my current problem.
I've created a view, something like excel. It's dynamically created. (see below)
A B C
| 1| | 3| | 7| // The input format is `<input type='text' class='inputitem' id='colA_row1' />`
| 2| | 6| | 8| // The `id` of this `inputitem`is defined by the number of columns and rows automatically
| 9| | 7| | 4|
|12| |16| |19| // The format of total textbox is `<input type='text' class='totalitem' id='total_colA' />
//// The `id` of this `totalitem` is defined by the number of column automatically
User may input any number to any inputitem and the value of totalitem is adjusted to the SUM of value in each column. (in example, if user change the value of column A row 2 to 9, the totalcolumn of column A is changed into 19)
This is my current jquery code:
$('.inputitem').on('keyup', function(){
var _inputitem = $(this);
var _inputitem_arr = $(this).attr('id').split('_');
var _inputitem_col = _inputitem_arr[0];
var _inputitem_row = _inputitem_arr[1];
/*SUM SCRIPT*/
var sum_item = 0;
$('.inputitem').each(function(i){
var inputitem_val = parseFloat($(this).val().replace(',', ''));
$('.totalitem').each(function(i){
var _totalitem = $(this);
var _totalitem_arr = $(this).attr('id').split('_');
var _totalitem_col = _totalitem_arr[1];
if(_inputitem_col == _totalitem_col){
sum_item = sum_item + inputitem_val;
_totalitem.val(sum_item);
}
});
});
/*END SUM SCRIPT*/
});
My current script give wrong value of total item. It seems to adding the SUM of different column into the formula. Any help and suggestion is much appreciated
Think about the flow of this code.
Your outermost function executes when the user finishes a key press (keyup event) on any input element on your page that has class "input item". So far, so good.
You initialize the sum to 0 and then you call
$('.inputitem').each(function(i){
This call means that for every element on the page that has class "input item", you will run the entire script inside the inner function. So for the first inputitem (perhaps the one in the top left, perhaps not) we get the value 1.0 in inputitem_val.
Here's where the trouble really starts. Next you call the each function for all of your total cells. But this is a nested call. So you are doing that inner-most function anew for each of the 9 (or however many) cells of your outer each loop. Here's a fix un-nests the functions:
$('.inputitem').on('keyup', function(){
var _inputitem = $(this);
var _inputitem_arr = $(this).attr('id').split('_');
var _inputitem_col = _inputitem_arr[0];
//whichever column this cell is in is the column we need to re-sum
var active_col = _inputitem_col
/*SUM SCRIPT*/
var sum_item = 0;
//iterate through each input cell
$('.inputitem').each(function(i){
var _inputitem = $(this);
var _inputitem_arr = $(this).attr('id').split('_');
var _inputitem_col = _inputitem_arr[0];
//check whether the current input cell is in the active column
if(_inputitem_col == active_col){
//if so, add it to our partial sum
var inputitem_val = parseFloat($(this).val().replace(',', ''));
sum_item += inputitem_val;
}
});
//find and update only the relavent sum cell
$('.totalitem').each(function(i){
var _totalitem = $(this);
var _totalitem_arr = $(this).attr('id').split('_');
var _totalitem_col = _totalitem_arr[1];
if(_inputitem_col == _totalitem_col){
_totalitem.val(sum_item);
}
});
/*END SUM SCRIPT*/
});
$('.inputitem').on('keyup', function(){
var _inputitem_arr = $(this).attr('id').split('_');
var _inputitem_col = _inputitem_arr[0];
var $totlaSelector = '#total_' + _inputitem_col;
var $ColTotal = 0;
$('[id^="'+_inputitem_col+'"]').each(function(i){
var $thisVal = 0;
if($(this).val() != ''){
$thisVal = parseInt($(this).val());
}
$ColTotal = $ColTotal + $thisVal;
});
$($totlaSelector).val($ColTotal);
});
I have updated your jQuery on keyup event.
I am trying to draw connected lines using canvas from data in a MySql table. The table (gene_dna_segments) contains the length of each line segment and the segment name.
The desired output is a continuous straight horizontal line comprised of each of the segments. Each segment also needs to have the segment name showing above the corresponding segment as shown in the image below:
+----------------------+--------------------+------------------+--------------------+
| gene_dna_segments_pk | gene_expression_fk | dna_segment_name | dna_segment_length |
+----------------------+--------------------+------------------+--------------------+
| 1 | 11 | Exon 1 | 50 |
| 2 | 11 | Intron 1 | 75 |
| 3 | 11 | Exon 2 | 20 |
| 4 | 11 | Intron 2 | 90 |
+----------------------+--------------------+------------------+--------------------+
Query (old fashioned no PDO...):
$query_dna = "SELECT * FROM gene_dna_segments WHERE gene_expression_fk = '11'";
$result_dna = mysql_query($query_dna, $connection) or die(mysql_error());
Display:
<canvas id="canvas" width="800" height="500"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
<?php
while($row_dna = mysql_fetch_assoc($result_dna)) {
echo "context.beginPath();context.moveTo(100, 100);context.lineTo(" . $row_dna['dna_segment_length'] . ", 100);context.lineWidth = 12;context.strokeStyle = '#009543';context.stroke();context.font = 'bold 12pt Calibri';
context.fillStyle = '#009543';
context.fillText('" . $row_dna['dna_segment_name'] . "', 180, 90);";
}
?>
</script>
Now, the line segments and text as defined in the table are drawn OK, but on top of each other as the context.moveTo(100, 100) is the same for each row that is output in the while loop. How should this be handled so that the segments are drawn as a continuous line?
Possibly the easiest thing is to add a start point column to the table and calculate the start points for each segment based on the previous segment's length...I've opened a seperate question on that possibility Calculating new array values based on another numeric array
Note that 'normal' code to draw the lines is like the following code, note that the moveto parts start at the end of the previous line. I need to do the same in the loop...
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(100, 100);
context.lineTo(150, 100);
context.lineWidth = 12;
context.strokeStyle = '#009543';
context.stroke();
context.font = 'bold 11pt Calibri';
context.fillStyle = '#009543';
context.fillText('Exon 1', 105, 90);
context.beginPath();
context.moveTo(150, 100);
context.lineTo(225, 100);
context.lineWidth = 12;
context.strokeStyle = '#e97300';
context.stroke();
context.font = 'bold 11pt Calibri';
context.fillStyle = '#e97300';
context.fillText('Intron 1', 165, 90);
context.beginPath();
context.moveTo(225, 100);
context.lineTo(275, 100);
context.lineWidth = 12;
context.strokeStyle = '#009543';
context.stroke();
context.font = 'bold 11pt Calibri';
context.fillStyle = '#009543';
context.fillText('Exon 2', 230, 90);
context.beginPath();
context.moveTo(275, 100);
context.lineTo(375, 100);
context.lineWidth = 12;
context.strokeStyle = '#e97300';
context.stroke();
context.font = 'bold 11pt Calibri';
context.fillStyle = '#e97300';
context.fillText('Intron 2', 300, 90);
[ Updated based on new info from questioner ]
What you're describing is a horizontally stacked bar-chart
Demo: http://jsfiddle.net/m1erickson/RzMWS/
Your barchart is fairly straightforward.
Small problem:
We need to display the segment_name label above each bar. In a perfect world, we could use the segment_length for the bar width. But in reality, sometimes the resulting bar width will be too narrow to fit the text label above.
Therefore, we must preprocess the data and determine an appropriate scale factor for the bars. By scaling the bars proportionally, each bar will remain proportional to their segment_length and will also be wide enough to fit the segment_name label.
Here is heavily commented code.
Of course, you will read from your database fetch instead of reading the test data in the rows[] array.
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
// get references to the canvas
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.font = 'bold 11pt Calibri';
// define the color of the bar for each segment_name
var colorCodes={
Exon1:"green",
Intron1:"orange",
Exon2:"green",
Intron2:"orange"
};
// create some test data
var rows=[];
rows.push({dna_segment_name:"Exon 1",dna_segment_length:50});
rows.push({dna_segment_name:"Intron 1",dna_segment_length:75});
rows.push({dna_segment_name:"Exon 2",dna_segment_length:20});
rows.push({dna_segment_name:"Intron 2",dna_segment_length:90});
// some variables
// segments[]: pre-processed data will be saved into segments[]
// scaleFactor: scales every bar if any text label fails to fit
// padding: allow minimum padding between text labels
var segments=[];
var scaleFactor=1;
var padding=5;
// pre-process
// Of course, you will be reading from your database Fetch
// instead of this test data in rows[]
for(var i=0;i<rows.length;i++){
var $row_dna=rows[i];
// make variables for the segment_name & segment_length
// being read from the data fetch
var name=$row_dna['dna_segment_name'];
var length=$row_dna['dna_segment_length'];
// lookup the color for this segment_name
var color=colorCodes[name.replace(/\s+/g, '')];
// rescale the bars if any text won't fit
var textWidth=ctx.measureText(name).width+padding;
var textRatio=textWidth/length;
if (textRatio>scaleFactor){ scaleFactor=textRatio; }
// save the pre-processed info in a javascript object
// for later processing
segments.push({
name:name,
length:length*scaleFactor,
color:color
});
}
// draw the stacked bar-chart
// based on the preprocessed JS objects in segments[]
var accumLength=0;
var y=100; // the Y-coordinate of the barchart
for(var i=0;i<segments.length;i++){
// load the object for the current bar
var segment=segments[i];
// set the bar color
ctx.fillStyle=segment.color;
// draw the bar
ctx.fillRect(accumLength,y,segment.length,12);
// draw the text label
ctx.fillText(segment.name,accumLength,y-10);
// accumulate where the next bar will begin
accumLength+=segment.length;
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=400 height=300></canvas>
</body>
</html>
I use LIVE Highchart with 2 live graphs. The chart should display only 5 datapoints at on time. Therefore is the shift-argument
var series1 = chart.series[0];
shift1 = series1.data.length > 5;
series1.addPoint(point1, true, shift1);
So when point six arrives, point one is thrown away. But when i disable a series for a while ... and after enabling it again ... there was no shift.
http://www.abload.de/img/errorh5kko.jpeg
I reproduced it on jsfiddle for you
http://jsfiddle.net/yeDYr/1/
So both livegraphs no matter whether enabled or disabled should be shifted.
Looks like a bug in Highcharts to me. As a workaround, just .show() the series, then hide() it (if needed). Highcharts seems to be able to do this without any visible flickering.
// the button action
$('#button1').click(function() {
var point1 = Math.random() * 10;
var point2 = Math.random() * 10;
var series1 = chart.series[0];
shift1 = series1.data.length > 5;
isVisible = series1.visible;
if (!isVisible) series1.show();
series1.addPoint(point1, true, shift1);
if (!isVisible) series1.hide();
var series2 = chart.series[1];
shift2 = series2.data.length > 5;
isVisible = series2.visible;
if (!isVisible) series2.show();
series2.addPoint(point2, true, shift2);
if (!isVisible) series2.hide();
});
Updated fiddle.
i have this script i'm using to display random images with hyperlinks. can anyone tell me how i might adapt it to display 5 random images at once, preferably without repeating the same image twice?
Thanks
<script language="JavaScript">
<!--
/*
Random Image Link Script- By JavaScript Kit(http://www.javascriptkit.com)
Over 200+ free JavaScripts here!
Updated: 00/04/25
*/
function random_imglink(){
var myimages=new Array()
//specify random images below. You can have as many as you wish
myimages[1]="data/adverts/ad1.png"
myimages[2]="data/adverts/ad2.png"
myimages[3]="data/adverts/ad3.png"
myimages[4]="data/adverts/ad4.png"
myimages[5]="data/adverts/ad5.png"
//specify corresponding links below
var imagelinks=new Array()
imagelinks[1]="http://www.javascriptkit.com"
imagelinks[2]="http://www.netscape.com"
imagelinks[3]="http://www.microsoft.com"
imagelinks[4]="http://www.dynamicdrive.com"
imagelinks[5]="http://www.freewarejava.com"
var ry=Math.floor(Math.random()*myimages.length)
if (ry==0)
ry=1
document.write('<a href='+'"'+imagelinks[ry]+'"'+'><img src="'+myimages[ry]+'" border=0></a>')
}
random_imglink()
//-->
</script>
function random_imglink(){
var myimages=new Array();
...
var imagelinks=new Array();
...
var used = [];
var ry;
var howmany = 5;
for (var i = 1; i <= howmany; i++) {
ry=Math.ceil(Math.random()*myimages.length);
while(used.indexOf(ry)!=-1){
ry=Math.ceil(Math.random()*myimages.length);
}
used.push[ry];
document.write('<a href='+'"'+imagelinks[ry]+'"'+'><img src="'+myimages[ry]+'" border=0></a>')
}
}
this assumes you're going to put more images in your array than 5.
Instead random and checking with while if you have already chosen an image you can move the choosen image to the end of the array and reduce the variable for the random by one. Example:
function random_imglink(select){
if (select > 5 ) {
// make it fail ...
}
//specify random images below. You can have as many as you wish
var myimages = new Array();
myimages[0]="data/adverts/ad1.png"
myimages[1]="data/adverts/ad2.png"
myimages[2]="data/adverts/ad3.png"
myimages[3]="data/adverts/ad4.png"
myimages[4]="data/adverts/ad5.png"
//specify corresponding links below
var imagelinks=new Array()
imagelinks[0]="http://www.javascriptkit.com"
imagelinks[1]="http://www.netscape.com"
imagelinks[2]="http://www.microsoft.com"
imagelinks[3]="http://www.dynamicdrive.com"
imagelinks[4]="http://www.freewarejava.com"
var size = myimages.length
for (var i=0;i<select;i++) {
var index = Math.floor(Math.random() * size);
document.write('<a href='+'"'+imagelinks[index]+'"'+'><img src="'+myimages[index]+'" border=0></a>');
var tmp = myimages[index];
myimages[index] = myimages[size - 1];
myimages[size - 1] = tmp;
tmp = imagelinks[index];
imagelinks[index] = imagelinks[size - 1];
imagelinks[size - 1] = tmp;
--size;
}
}
random_imglink(3);
It could be something like that in one line of code and without creating functions:
<img src="https://www.example.com/images/image-<?php echo rand(1,7); ?>.jpg">
In order to get this to work, you’ll want to name your images: image-1.jpg, image-2.jpg, image-3.jpg....image-7.jpg,
When the page loads, the PHP rand() will echo a random number (in this case, a number between 1 and 7), completing the URL and thus displaying the corresponding image. Source: https://jonbellah.com/load-random-images-with-php/
I'm looking for ideas ...brainstorming a new project for a client ....I have an image ...300px x 300px ...I need to display the image one random pixel at a time until the entire image is revealed.
Basically, at certain intervals, a pixel is revealed and remains revealed while other pixels are still blank. At each interval, another pixel at random is revealed and remains revealed to join the other revealed pixels. Eventually, all the pixels will be revealed.
Any suggestions on how to make that happen?
I could make numerous copies of the image and manually reveal one random pixel, but surely it can be done programatically :)
Oh, and it cannot be any form of flash.
EDIT: I realize I mis-interpreted what you needed to do, but I thought this was cool anyway and could be applied to your problem...
See working demo of the following →
I threw this together in jQuery. I made each pixel actually a 3x3 box instead because otherwise it would take way too long to process. Seems to work pretty well for something on this in client side, though I haven't tested IE yet.
<div id="w">
<img id="i" src="yourImage.jpg" width="300" height="300" />
</div>
$('#w').css({
width: $('#i').width(),
height: $('#i').height()
});
var htmlFrag = '',
id, ids = [],
removePix = function () {
if (ids.length) {
var rand = Math.floor(Math.random()*ids.length);
$('#'+ids[rand]).fadeOut(function(){
$(this).remove();
});
ids = ids.slice(0, rand).concat(ids.slice(rand+1));
setTimeout(removePix, 1);
}
};
for (var i = 0, len = $('#i').height(); i < len; i += 3) {
for (var j = 0, len = $('#i').width(); j < len; j += 3) {
id = 'pix'+j+'-'+i;
ids.push(id);
htmlFrag += '<div id="'+id+'" class="pix" ' +
'style="width:3px;height:3px;position:absolute;' +
'left:'+j+'px;top:'+i+'px;"></div>';
}
}
$('#w').html($('#w').html() + htmlFrag);
removePix();
See working example →
Load the image file into an image resource (imagecreatefrompng, imagecreatefromgif, etc).
Decide what pixels to show, using rand() or however you want to choose them.
Loop over every pixel in the image, and if it's not one you chose to show, color it gray with imagesetpixel.