Generate Excel file thumbnail preview in Javascript - javascript

I have a project handling a library of excel files. To make it easilier for the users to visually scan them, I would like to generate preview thumbnail images of their content. Google drive does this (screenshot below) but I have no idea how.
Any ideas/suggestions on how this could be done (without using the drive API) ?

I guess this is what you need
http://github.com/lonekorean/mini-preview
DEMO
/*
* MiniPreview v0.9
*
* #author Will Boyd
* #github http://github.com/lonekorean/mini-preview
*/
(function($) {
var PREFIX = 'mini-preview';
// implemented as a jQuery plugin
$.fn.miniPreview = function(options) {
return this.each(function() {
var $this = $(this);
var miniPreview = $this.data(PREFIX);
if (miniPreview) {
miniPreview.destroy();
}
miniPreview = new MiniPreview($this, options);
miniPreview.generate();
$this.data(PREFIX, miniPreview);
});
};
var MiniPreview = function($el, options) {
this.$el = $el;
this.$el.addClass(PREFIX + '-anchor');
this.options = $.extend({}, this.defaultOptions, options);
this.counter = MiniPreview.prototype.sharedCounter++;
};
MiniPreview.prototype = {
sharedCounter: 0,
defaultOptions: {
width: 256,
height: 144,
scale: .25,
prefetch: 'pageload'
},
generate: function() {
this.createElements();
this.setPrefetch();
},
createElements: function() {
var $wrapper = $('<div>', { class: PREFIX + '-wrapper' });
var $loading = $('<div>', { class: PREFIX + '-loading' });
var $frame = $('<iframe>', { class: PREFIX + '-frame' });
var $cover = $('<div>', { class: PREFIX + '-cover' });
$wrapper.appendTo(this.$el).append($loading, $frame, $cover);
// sizing
$wrapper.css({
width: this.options.width + 'px',
height: this.options.height + 'px'
});
// scaling
var inversePercent = 100 / this.options.scale;
$frame.css({
width: inversePercent + '%',
height: inversePercent + '%',
transform: 'scale(' + this.options.scale + ')'
});
// positioning
var fontSize = parseInt(this.$el.css('font-size').replace('px', ''), 10)
var top = (this.$el.height() + fontSize) / 2;
var left = (this.$el.width() - $wrapper.outerWidth()) / 2;
$wrapper.css({
top: top + 'px',
left: left + 'px'
});
},
setPrefetch: function() {
switch (this.options.prefetch) {
case 'pageload':
this.loadPreview();
break;
case 'parenthover':
this.$el.parent().one(this.getNamespacedEvent('mouseenter'),
this.loadPreview.bind(this));
break;
case 'none':
this.$el.one(this.getNamespacedEvent('mouseenter'),
this.loadPreview.bind(this));
break;
default:
throw 'Prefetch setting not recognized: ' + this.options.prefetch;
break;
}
},
loadPreview: function() {
this.$el.find('.' + PREFIX + '-frame')
.attr('src', this.$el.attr('href'))
.on('load', function() {
// some sites don't set their background color
$(this).css('background-color', '#fff');
});
},
getNamespacedEvent: function(event) {
return event + '.' + PREFIX + '_' + this.counter;
},
destroy: function() {
this.$el.removeClass(PREFIX + '-anchor');
this.$el.parent().off(this.getNamespacedEvent('mouseenter'));
this.$el.off(this.getNamespacedEvent('mouseenter'));
this.$el.find('.' + PREFIX + '-wrapper').remove();
}
};
})(jQuery);
.mini-preview-anchor {
display: inline-block;
position: relative;
white-space: nowrap;
}
.mini-preview-wrapper {
-moz-box-sizing: content-box;
box-sizing: content-box;
position: absolute;
overflow: hidden;
z-index: -1;
opacity: 0;
margin-top: -4px;
border: solid 1px #000;
box-shadow: 4px 4px 6px rgba(0, 0, 0, .3);
transition: z-index steps(1) .3s, opacity .3s, margin-top .3s;
}
.mini-preview-anchor:hover .mini-preview-wrapper {
z-index: 2;
opacity: 1;
margin-top: 6px;
transition: opacity .3s, margin-top .3s;
}
.mini-preview-loading, .mini-preview-cover {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
.mini-preview-loading {
display: table;
height: 100%;
width: 100%;
font-size: 1.25rem;
text-align: center;
color: #f5ead4;
background-color: #59513f;
}
.mini-preview-loading::before {
content: 'Loading...';
display: table-cell;
text-align: center;
vertical-align: middle;
}
.mini-preview-cover {
background-color: rgba(0, 0, 0, 0); /* IE fix */
}
.mini-preview-frame {
border: none;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MiniPreview Demo</title>
<link href="http://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<style>
body {
height: 100%;
margin: 0;
padding: 0 10% 40px;
font-size: 2rem;
line-height: 1.5;
font-family: 'Roboto Slab', sans-serif;
text-align: justify;
color: #59513f;
background-color: #f5ead4;
}
a {
color: #537f7c;
}
.break {
text-align: center;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<!-- MiniPreview stuff here -->
<link href="./jquery.minipreview.css" rel="stylesheet">
<script src="./jquery.minipreview.js"></script>
<script>
$(function() {
$('#p1 a').miniPreview({ prefetch: 'pageload' });
$('#p2 a').miniPreview({ prefetch: 'parenthover' });
$('#p3 a').miniPreview({ prefetch: 'none' });
});
</script>
</head>
<body>
<p id="p1">
This demo shows how to add live mini-previews to links on hover. Check out these links to SitePoint and A List Apart. Hover over them to see a small preview of what they point to.
</p>
<p class="break">• • •</p>
<p id="p2">
Those previews were fetched as soon as this page loaded. This is great for having the previews ready ahead of time, but can eat up extra bandwidth. As an alternative, check out these links to Abduzeedo and Smashing Magazine. These previews aren't fetched until you hover over this paragraph.
</p>
<p class="break">• • •</p>
<p id="p3">
Finally, check out these links to Daniel's blog, Joni's blog, and my blog. These previews are only fetched when needed. This saves the most bandwidth, but there will be a delay before the previews can be shown.
</p>
</body>
</html>
ORIGINAL SOURCE:
http://codepen.io/kanakiyajay/pen/NqgZjo

I just use a library to generate a PNG preview of the excel file and show it.
I use Free Spire.XLS for .NET because I'm in the .net world, but you can look at Wijmo Workbook Viewer for your Node.js needs.

Related

Div with sprite-animation doesn't change properly during window.resize event

I am trying to imitate 3d-model rotation with a sprite sheet. I found a perfect example on Codepen, but it was not responsive.
What I tried to do is to write divs, containers and spritesize (in script) in vw, and then it is being checked in the window.resize event. It does work, but unfortunately not DURING window resize.
I put my snippet and three pictures in the post —
I opened website and everything is perfect - image
I started to change the size of my browser window and as you can see something is wrong - image
Now I tried to "rotate" the "model" with resized window and all is fine again - image
var spriteslider = document.createElement('div');
var clientWidth = document.getElementById('spritetarget').clientWidth;
document.body.appendChild(spriteslider);
spriteslider.slider = document.getElementById('spriteslider');
spriteslider.sprite = document.getElementById('spritetarget');
spriteslider.spritesize = clientWidth;
spriteslider.spritecount = 20;
spriteslider.pixelsperincrement = 5;
spriteslider.multiplier = spriteslider.lastmultiplier = 0;
Draggable.create(spriteslider, {
type: 'x',
trigger: spriteslider.slider,
bounds: {
minX: 0,
maxX: 0,
minY: 0,
maxY: 0
},
edgeResistance: 0,
cursor: 'e-resize',
onDrag: function() {
if (this.isDragging) {
var t = this.target;
t.multiplier = Math.floor(this.x / t.pixelsperincrement) + t.lastmultiplier;
// TweenLite.set(t.sprite, { backgroundPosition: (-t.multiplier * t.spritesize) + "px 0"});
TweenLite.set(t.sprite, {
backgroundPosition: (-t.multiplier * t.spritesize) + "px 0"
});
}
},
onDragEnd: function() {
var t = this.target;
t.lastmultiplier = t.multiplier % t.spritecount;
}
});
window.addEventListener('resize', function(event) {
var clientWidth = document.getElementById('spritetarget').clientWidth;
spriteslider.spritesize = clientWidth;
TweenLite.set(t.sprite, {
backgroundPosition: (-t.multiplier * t.spritesize) + "px 0"
});
}, true);
body {
text-align: center;
font: normal 12px sans-serif;
background: #000000;
color: #91E600;
}
.spriteslider {
margin: 20px auto;
padding: 60px;
width: 20vw;
height: 20vw;
background: #FCFEFC;
border-radius: 5px;
}
#spritetarget {
width: 20vw;
height: 20vw;
background-size: cover;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/29123/heart.png);
/* horizontal spritesheet - image from http://preloaders.net */
background-repeat: repeat-x;
}
<div class='spriteslider' id='spriteslider'>
<div id='spritetarget'></div>
</div>
<p>Drag the box left/right to control the sprite's position.</p>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/utils/Draggable.min.js'></script>
The issue is because you're referencing t in the window.resize event handler, yet that variable has been defined in a different scope, and is not accessible from that location.
To fix this issue you can replace t in that function with the spriteslider variable, as that's what t is expected to contain. Try this:
var spriteslider = document.createElement('div');
var clientWidth = document.getElementById('spritetarget').clientWidth;
document.body.appendChild(spriteslider);
spriteslider.slider = document.getElementById('spriteslider');
spriteslider.sprite = document.getElementById('spritetarget');
spriteslider.spritesize = clientWidth;
spriteslider.spritecount = 20;
spriteslider.pixelsperincrement = 5;
spriteslider.multiplier = spriteslider.lastmultiplier = 0;
Draggable.create(spriteslider, {
type: 'x',
trigger: spriteslider.slider,
bounds: {
minX: 0,
maxX: 0,
minY: 0,
maxY: 0
},
edgeResistance: 0,
cursor: 'e-resize',
onDrag: function() {
if (this.isDragging) {
var t = this.target;
t.multiplier = Math.floor(this.x / t.pixelsperincrement) + t.lastmultiplier;
TweenLite.set(t.sprite, {
backgroundPosition: (-t.multiplier * t.spritesize) + "px 0"
});
}
},
onDragEnd: function() {
var t = this.target;
t.lastmultiplier = t.multiplier % t.spritecount;
}
});
window.addEventListener('resize', function(event) {
var clientWidth = document.getElementById('spritetarget').clientWidth;
spriteslider.spritesize = clientWidth;
TweenLite.set(spriteslider.sprite, {
backgroundPosition: (-spriteslider.multiplier * spriteslider.spritesize) + "px 0"
});
}, true);
body {
text-align: center;
font: normal 12px sans-serif;
background: #000000;
color: #91E600;
}
.spriteslider {
margin: 20px auto;
padding: 60px;
width: 20vw;
height: 20vw;
background: #FCFEFC;
border-radius: 5px;
}
#spritetarget {
width: 20vw;
height: 20vw;
background-size: cover;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/29123/heart.png);
/* horizontal spritesheet - image from http://preloaders.net */
background-repeat: repeat-x;
}
<div class='spriteslider' id='spriteslider'>
<div id='spritetarget'></div>
</div>
<p>Drag the box left/right to control the sprite's position.</p>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/utils/Draggable.min.js'></script>

Minipreview jQuery link preview contents of parent <p> or <div> only

I'd like to use https://github.com/lonekorean/mini-preview to create mouseover previews for parts of a website only.
I have no problems using anchors from the target website to have the script render a full website preview, scrolled to where an individual anchor is.
That's not what I'm after however.
I'd like the script to show only the content of the anchors' parent <p> or <div>.
On the site, the link target anchors are coded like this:
<div class="paragraph">
<p>
<a id="anchor_1"></a>
Foo bar baz.
</p>
</div>
So, I'd like the little preview box to show Foo bar baz. only.
I suspect the answer lies in this part of the script:
loadPreview: function() {
this.$el.find('.' + PREFIX + '-frame')
.attr('src', this.$el.attr('href'))
.on('load', function() {
// some sites don't set their background color
$(this).css('background-color', '#fff');
});
specifically, the .attr('src', this.$el.attr('href')) part.
I'm not sure though.
Does anyone know how I can do this?
Or can you recommend some other script that I can use to do this and makes things look as nice as this one?
I'm not a web dev, so please go easy on me.
Thanks
UPDATE (based on Swati's answer and corresponding comments):
For example, if my website includes this:
<body>
<p>
See internal
</p>
<p>
See external
</p>
<div class="paragraph">
<p>
<a id="anchor_on_my_site"></a>
Foo bar baz.
</p>
</div>
</body>
and the external website includes this:
<body>
<div class="paragraph">
<p>
<a id="external_anchor"></a>
Qux quux quuz.
</p>
</div>
</body>
I'd like See internal to display Foo bar baz. and See external to display Qux quux quuz.
Inside loadPreview function you can use closest('p').clone().children().remove().end().text() to get text from p tag where a has been hover then using this put that text to show inside your frame div i.e : .find('.' + PREFIX + '-frame').text(data_to_show) .
Demo Code :
(function($) {
var PREFIX = 'mini-preview';
$.fn.miniPreview = function(options) {
return this.each(function() {
var $this = $(this);
var miniPreview = $this.data(PREFIX);
if (miniPreview) {
miniPreview.destroy();
}
miniPreview = new MiniPreview($this, options);
miniPreview.generate();
$this.data(PREFIX, miniPreview);
});
};
var MiniPreview = function($el, options) {
this.$el = $el;
this.$el.addClass(PREFIX + '-anchor');
this.options = $.extend({}, this.defaultOptions, options);
this.counter = MiniPreview.prototype.sharedCounter++;
};
MiniPreview.prototype = {
sharedCounter: 0,
defaultOptions: {
width: 256,
height: 144,
scale: .25,
prefetch: 'parenthover'
},
generate: function() {
this.createElements();
this.setPrefetch();
},
createElements: function() {
var $wrapper = $('<div>', {
class: PREFIX + '-wrapper'
});
//no need to use iframe...use simple div
var $frame = $('<div>', {
class: PREFIX + '-frame'
});
var $cover = $('<div>', {
class: PREFIX + '-cover'
});
$wrapper.appendTo(this.$el).append($frame, $cover);
// sizing
$wrapper.css({
width: this.options.width + 'px',
height: this.options.height + 'px'
});
// scaling
var inversePercent = 100 / this.options.scale;
$frame.css({
width: inversePercent + '%',
height: inversePercent + '%',
transform: 'scale(' + this.options.scale + ')'
});
var fontSize = parseInt(this.$el.css('font-size').replace('px', ''), 10)
var top = (this.$el.height() + fontSize) / 2;
var left = (this.$el.width() - $wrapper.outerWidth()) / 2;
//add more style here ...if needed to outer div
$wrapper.css({
top: top + 'px',
left: left + 'px',
'font-size': '55px',
'color': 'blue'
});
},
setPrefetch: function() {
switch (this.options.prefetch) {
case 'pageload':
this.loadPreview();
break;
case 'parenthover':
this.$el.parent().one(this.getNamespacedEvent('mouseenter'),
this.loadPreview.bind(this));
break;
case 'none':
this.$el.one(this.getNamespacedEvent('mouseenter'),
this.loadPreview.bind(this));
break;
default:
throw 'Prefetch setting not recognized: ' + this.options.prefetch;
break;
}
},
loadPreview: function() {
//to get text from p tag
var data_to_show = this.$el.closest('p').clone().children().remove().end().text().trim()
//set new text inside div frame
this.$el.find('.' + PREFIX + '-frame').text(data_to_show)
//set bg color..
this.$el.find('.' + PREFIX + '-frame').css('background-color', '#fff');
},
getNamespacedEvent: function(event) {
return event + '.' + PREFIX + '_' + this.counter;
},
destroy: function() {
this.$el.removeClass(PREFIX + '-anchor');
this.$el.parent().off(this.getNamespacedEvent('mouseenter'));
this.$el.off(this.getNamespacedEvent('mouseenter'));
this.$el.find('.' + PREFIX + '-wrapper').remove();
}
};
})(jQuery);
$('a').miniPreview();
body {
height: 100%;
margin: 0;
padding: 0 10% 40px;
font-size: 2rem;
line-height: 1.5;
font-family: 'Roboto Slab', sans-serif;
text-align: justify;
color: #59513f;
background-color: #f5ead4;
}
a {
color: #537f7c;
}
.mini-preview-anchor {
display: inline-block;
position: relative;
white-space: nowrap;
}
.mini-preview-wrapper {
-moz-box-sizing: content-box;
box-sizing: content-box;
position: absolute;
overflow: hidden;
z-index: -1;
opacity: 0;
margin-top: -4px;
border: solid 1px #000;
box-shadow: 4px 4px 6px rgba(0, 0, 0, .3);
transition: z-index steps(1) .3s, opacity .3s, margin-top .3s;
}
.mini-preview-anchor:hover .mini-preview-wrapper {
z-index: 2;
opacity: 1;
margin-top: 6px;
transition: opacity .3s, margin-top .3s;
}
.mini-preview-cover {
background-color: rgba(0, 0, 0, 0);
/* IE fix */
}
.mini-preview-frame {
border: none;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<div class="paragraph">
<p>
<a id="anchor_1">See</a> This is text we are showing for first
</p>
<p>
<a id="anchor_2">See</a> This is text we are showing for second
</p>
</div>
</body>
</html>
Update 1 :
You can differentiate between external & internal link using some class i.e : simply check if the a tag which is hover has a particular class or not depending on this change your code to preview divs.
Updated Code :
if (this.$el.hasClass("internal")) {
//to get text from p tag
var data_to_show = this.$el.closest('p').siblings(".paragraph").clone().text().trim()
//set new text inside div frame
this.$el.find('.' + PREFIX + '-frame').text(data_to_show)
//set bg color..
this.$el.find('.' + PREFIX + '-frame').css('background-color', '#fff');
} else {
console.log("for external code ..")
}

Random name picker with bounce animation

I'm looking to create a random name picker with HTML, JS and CSS which has gone quite well as you can see here... http://clients.random.agency/namepicker/
However, the client has asked for it to have a similar animation to this with ...
https://www.dropbox.com/s/3likecb0ld30som/Jv0Gp4XkhQ.mp4?dl=0
I've search google but I can't seem to find any examples of what I'm looking for and would really appreciate if anyone could point me in the right direction.
This is a simple example, hope be helpful.
var names =['John', 'David', 'Joe', 'Sara'];
var nameCount= names.length;
var p = document.getElementById("container");
var randTimer = setInterval(function(){ p.innerHTML = names[Math.floor(Math.random() * nameCount)]; }, 200);
function stop(){
clearInterval(randTimer);
}
#container{
color: red;
font-size:2rem;
text-align:center;
cursor: pointer;
}
<p id="container" onClick="stop()"></p>
<p>click on random names to pick one!</P>
Here's a pretty similar example I was able to find. Using Javascript seems to be the most straightforward way to go about doing this. https://codepen.io/maerianne/pen/pRQbQr
var myScrollTop = function(elem, delay){
elem.animate({ scrollTop: 0 }, delay, function(){
myScrollBottom(elem, delay);
});
};
var myScrollBottom = function(elem, delay){
elem.animate({ scrollTop: elem.height() }, delay, function(){
myScrollTop(elem, delay);
});
};
var scrollUpDown = function(elem, delay) {
myScrollTop(elem, delay);
};
$(document).ready(function(){
scrollUpDown($(".scroll-up-down"), 5000);
});
As you can see, scrollUpDown()is the initial function which starts a loop switching between myScrollTop() and myScrollBottom(). You could pretty easily make the delay increase with each iteration to mimic the slowing down and eventual stop in the example animation you gave.
You could also refactor this to be a singular recursive function.
Best of luck!
It picks a random item from the array of labels. Then it goes into a loop, changing the label to the next item in the array until it gets to the chosen one, and using animation for the transitions
$('#search_btns button:nth-child(2)').hover(function() {
btnTimeID = setTimeout(function() {
// We are using the math object to randomly pick a number between 1 - 11, and then applying the formula (5n-3)5 to this number, which leaves us with a randomly selected number that is applied to the <ul> (i.e. -185) and corresponds to the position of a word (or <li> element, i.e. "I'm Feeling Curious").
var pos = -((Math.floor((Math.random() * 11) + 1)) * 5 - 3) * 5
if (pos === -135) {
console.log("position didn't change, let's force change")
pos = -35;
}
$('#search_btns button:nth-child(2) ul').animate({'bottom':pos + 'px'}, 300);
// Change the width of the button to fit the currently selected word.
if (pos === -35 || pos === -110 || pos === -185 || pos === -10 || pos === -60 || pos === -160) {
console.log(pos + ' = -35, -110, -185, -10, -60, -160');
$('#search_btns button:nth-child(2)').css('width', '149px');
} else if (pos === -85) {
console.log(pos + ' = -85');
$('#search_btns button:nth-child(2)').css('width', '160px');
} else if (pos === -210) {
console.log(pos + ' = -210');
$('#search_btns button:nth-child(2)').css('width', '165px');
} else {
console.log(pos + ' = -260, -235');
$('#search_btns button:nth-child(2)').css('width', '144px');
}
},200);
}, function() {
clearTimeout(btnTimeID);
setTimeout(function() {
console.log('setTimeout function');
$('#search_btns button:nth-child(2) ul').css('bottom', '-135px'); // this is the original position
$('#search_btns button:nth-child(2)').css('width', '144px'); // reset the original width of the button
},200);
});
body, html {
margin: 0;
box-sizing: border-box;
font-family: arial;
}
*, *:before, *:after {
box-sizing: inherit;
}
#search_btns {
width: 400px;
margin: 30px auto;
padding-left: 60px;
}
#search_btns button:nth-child(2) {
width: 144px;
}
#search_btns button:nth-child(1) {
bottom: 12px;
}
#search_btns button {
position: relative;
height: 34px;
margin: 3px;
font-weight: bold;
color: gray;
background: #f1f1f1;
border: 1px solid #f1f1f1;
border-radius: 2px;
padding: 0 15px;
overflow: hidden;
}
#search_btns button:hover {
color: black;
border: 1px solid #bdbdbd;
box-shadow: 0px 0.5px 0px 0px #d3d3d3;
}
#search_btns button:active {
border: 1px solid #7f7fff;
}
#search_btns button:focus {
outline: 0;
}
#search_btns button ul li {
list-style-type: none;
padding: 5px 0;
text-align: left;
}
#search_btns button ul {
padding-left: 0;
position: absolute;
bottom: -135px;
width: 144px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="search_btns">
<button>This might be the effect you looking for</button>
<button>
<ul>
<li>item0/li>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
<li>item9</li>
</ul>
</button>
</div>
</body>
</html>

JS function is passed a different value depending on whether I'm executing or debugging

PROBLEM: Element with id "containerLnkMenu" does not center correctly in it's parent div when passed into the js function "centerElementYParent" unless I put a break point in the function using google chrome's debugger.
The "getComputedStyle(f, null)" call returns a "0px" for height if executed normally so I end up with a '-57px' for the margin-top.
COMMENT: So I found a few people that had similar problems on the internet, but I couldn't find a way to map their solution to my needs.
Any help on this would be appreciated.
Let me know if you need me to explain anything further.
I would prefer a detailed response or links to further reading, that is related to my issue (so I can learn from this error), but any related/helpful comment is welcome.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="main.css">
<script src="main.js"></script>
</head>
<body>
<div id="btnMenu" class="borderRadius" style="top: 10px; left: 10px;" onClick="btnMenuClicked(this)">
<div id="bar1" class="bar"></div>
<div id="bar2" class="bar"></div>
<div id="bar3" class="bar"></div>
</div>
<div id="menu" class="borderRadius" style="width: 0px; height: 0px;">
<div id="containerLnkMenu">
<a id="lnkNews" class="centerTxt lnkMenu" href="">NEWS</a>
<a id="lnkFiles" class="centerTxt lnkMenu" href="">FILES</a>
<a id="lnkTree" class="centerTxt lnkMenu" href="">TREE</a>
</div>
</div>
</body>
<script>
function btnMenuClicked(e) {
animateBtnMenu(e);
var menu = document.getElementById('menu');
var menuStyle = window.getComputedStyle(menu, null);
if (menuStyle.width == '0px' && menuStyle.height == '0px') {
openMenu(menu, menuStyle, e);
centerElementYParent(document.getElementById('containerLnkMenu'), document.getElementById('menu'));
} else {
closeMenu(menu, menuStyle, e);
}
}
</script>
</html>
body {
margin: 0;
font-family: Arial;
font-size: 16px;
}
a {
display: block;
text-decoration: none;
cursor: pointer;
}
/* Class Tools */
.centerTxt { text-align: center; }
.borderRadius { border-radius: 5px; }
.bar {
height: 5px;
transition: 0.4s;
background-color: #2E0A91;
}
.lnkMenu {
padding: 5px;
color: #FFD500;
font-size: 1.5em;
}
/*--- navigation ---*/
#btnMenu {
position: fixed;
width: 25px;
padding: 5px;
transition: 0.8s;
cursor: pointer;
}
#btnMenu:hover { background-color: #2E0A91; }
#btnMenu:hover .bar { background-color: #D4B100; }
#bar2 { margin: 5px 0 5px 0; }
.change #bar1 {
transform: rotate(-45deg) translate(-10px, 4px);
width: 141%;
}
.change #bar2 { opacity: 0; }
.change #bar3 {
transform: rotate(45deg) translate(-10px, -4px);
width: 141%;
}
#menu {
position: fixed;
z-index: 100;
top: 0;
left: 0;
overflow: hidden;
transition: 0.8s;
background-color: #2E0A91;
}
//NAME: centerElementYParent
//DESCRITPTION: e = element to center, f = parent element
// Adds margin top to e in order to vertically center element within parent (f)
function centerElementYParent(e, f) {
var eStyle = window.getComputedStyle(e, null);
var fStyle = window.getComputedStyle(f, null);
console.log(fStyle.height);
var eHeight = parseInt(eStyle.height.slice(0, eStyle.height.length - 2));
var fHeight = parseInt(fStyle.height.slice(0, fStyle.height.length - 2));
var marginTop = ((fHeight - eHeight)/2) + 'px';
e.style.marginTop = marginTop;
}
//NAME: animateBtnMenu
//DESCRIPTION: Attaches the 'change' class to the btnMenu element.
function animateBtnMenu(e) {
e.classList.toggle('change');
}
//NAME: openMenu
//DESCRIPTION: Applies a width and height to the menu whilst moving the menu button respectivley
function openMenu(e, eStyle, f) {
e.style.height = '250px';
e.style.width = '300px';
var eStyle = window.getComputedStyle(e, null);
f.style.left = '310px';
f.style.top = '260px';
}
//NAME: closeMenu
//DESCRIPTION: Sets width and height of the menu to 0 and moves the menu button respectivley
function closeMenu(e, eStyle, f) {
e.style.width = '0px';
e.style.height = '0px';
f.style.top = '10px';
f.style.left = '10px';
}
It may be because the element you want to center didn't rendered on the right position yet. Try adding setTimeout to call the function.
openMenu(menu, menuStyle, e);
setTimeout(function() {
centerElementYParent(document.getElementById('containerLnkMenu'), document.getElementById('menu'));
}, 800);

How to implement a jQuery plugin in my server?

I'm new to jQuery and web development. I have succesfully implemented other jQuery plugins like data tables or a simple sliders.
I'm having some problems when trying to make this run:
http://jsfiddle.net/KurtWM/pQnPg/
I know that is a must to initialize my code so I did the following:
<script type="text/javascript" language="javascript" class="init">
$(document).ready(function() {
$('#survey1').numericScale();
} );
</script>
I copied the js part exactly as it is from the provided link and uploaded to my server with the name:
jquery.numericScale.js
I have included jQuery and this plugin in the following way:
<script type="text/javascript" language="javascript" src="media/js/jquery.dataTables.js"></script>
<script type="text/javascript" language="javascript" src="media/js/jquery.numericScale.js"></script>
Regarding the HTML part I just copied it into my HTML body.
I really don't have a clue of what could I be doing wrong.
Try removing this from the end of your jquery.numericScale.js file:
var disciplines = $('#survey1').numericScale({
'responseRange' : 5,
'lowOpinionAnswer' : 'Least like me',
'highOpinionAnswer' : 'Most like me'
});
console.dir(disciplines);
Add this to your html page after your loaded plugins:
<script>
$('#survey1').numericScale({
'responseRange' : 5,
'lowOpinionAnswer' : 'Least like me',
'highOpinionAnswer' : 'Most like me'
});
</script>
This should work for you
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.survey-wrapper
{
position: relative;
display: table;
width: 100%; /*height: 500px;*/
max-width: 640px;
border-collapse: separate !important;
border-spacing: 1px !important;
}
ol.survey
{
list-style: decimal; /*margin-top: 160px;*/
list-style-position: inside;
}
ol.survey > li:last-child
{
border-bottom: 1px solid #CDCDCD;
}
ol.survey li
{
padding-left: -20px;
border-top: 1px solid #CDCDCD;
border-right: 1px solid #CDCDCD;
border-left: 1px solid #CDCDCD;
}
ol.survey li.alt, ol.survey li:nth-child(even)
{
background-color: #E8E8E4;
}
.scores > div
{
background: #E8E8E4;
}
.scores div.alt, .scores > div:nth-child(even)
{
background-color: #E8E8E4;
}
ol.survey li .opinion-question
{
margin-bottom: 0.5em;
font-weight: bold;
}
ol.survey li
{
padding-top: 6px;
padding-bottom: 1px;
padding-left: 12px;
}
ol.survey li .opinion-responses
{
display: table;
width: 100%;
margin-bottom: 1.0em;
}
ol.survey li .opinion-responses .bipolar-adjective
{
display: table-cell;
width: 25%;
text-align: center;
vertical-align: middle;
font-style: italic;
}
ol.survey li .opinion-responses .response-choice
{
display: table-cell;
width: 10px;
text-align: center;
vertical-align: middle;
}
ol.survey li .opinion-responses .response-choice input[type=radio], ol.survey li .opinion-responses .response-choice input.radio
{
}
.scores
{
width: 100%;
height: 400px;
position: relative;
}
.scores .discipline
{
display: block;
position: absolute;
bottom: 0;
text-align: center;
background: #E8E8E4 url(../images/gifts_orange.png) no-repeat 0 0;
border: 1px solid #FFFFFF;
}
.scores .discipline .discipline-name
{
text-align: center;
position: relative;
bottom: 24px;
z-index: 200;
font-family: "Futura Lt BT" , helvetica, sans-serif;
}
.scores .discipline .discipline-total
{
text-align: center;
display: block;
font-weight: bold;
font-size: 150%;
font-family: "Futura Md BT" , helvetica, sans-serif;
margin-top: 0px;
}
.scores .selected
{
background: #1047a9 url(../images/gifts_blue.png) no-repeat 0 0 !important;
}
.scores .selected .discipline-total
{
color: #FFFFFF !important;
}
.box
{
position: relative;
width: 60%;
background: #ddd;
-moz-border-radius: 4px;
border-radius: 4px;
padding: 2em 1.5em;
color: rgba(0,0,0, .8);
text-shadow: 0 1px 0 #fff;
line-height: 1.5;
margin: 60px auto;
}
.box:before, .box:after
{
z-index: -1;
position: absolute;
content: "";
bottom: 15px;
left: 10px;
width: 50%;
top: 80%;
max-width:300px;
background: rgba(0, 0, 0, 0.7);
-webkit-box-shadow: 0 15px 10px rgba(0,0,0, 0.7);
-moz-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
-webkit-transform: rotate(-3deg);
-moz-transform: rotate(-3deg);
-o-transform: rotate(-3deg);
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
}
.box:after
{
-webkit-transform: rotate(3deg);
-moz-transform: rotate(3deg);
-o-transform: rotate(3deg);
-ms-transform: rotate(3deg);
transform: rotate(3deg);
right: 10px;
left: auto;
}
.rotate
{
/* Safari */
-webkit-transform: rotate(-90deg); /* Firefox */
-moz-transform: rotate(-90deg); /* IE -ms-transform: rotate(-90deg); */ /* Opera */
-o-transform: rotate(-90deg);
}
</style>
</head>
<body>
<form>
<ol id="survey1" class="survey">
<li class="question" title="Prophecy">When a situation needs to be corrected I feel a burden to speak up about it in order to correct it.</li>
<li class="question" title="Shepherd">I feel a special concern for less mature Christians and feel compelled to care for them spiritually.</li>
<li class="question" title="Teaching">I find it easy and enjoyable to spend time in intensive Bible study.</li>
<li class="question" title="Encouraging">I am able to help others identify problems and offer solutions.</li>
<li class="question" title="Giving">I don't understand why others don't give as much and as freely as I do.</li>
<li class="question" title="Mercy">I am comfortable visiting people who are sick and disabled.</li>
<li class="question" title="Evangelism">I have greater desire than most to witness to non-Christians.</li>
<li class="question" title="Administration">If there is no leadership in a group I will step up and take charge.</li>
<li class="question" title="Serving">I enjoy being called upon to do special jobs around the church.</li>
<li class="question" title="Prophecy">When issues are being dealt with in a group, I speak up rather than just listening.</li>
<li class="question" title="Shepherd">I find myself especially concerned that newer Christians will be influenced by false teachers and be harmed in their spiritual growth as a result. </li>
<li class="question" title="Teaching">Others sometimes accuse me of being too technical or detail-oriented. </li>
<li class="question" title="Encouraging">I would rather talk personally with someone rather than refer them elsewhere. </li>
<li class="question" title="Giving">I find myself looking for opportunities to give my money without being asked to give. </li>
<li class="question" title="Mercy">I have a tendency to think about things for a while before making a decision. </li>
<li class="question" title="Evangelism">Witnessing to non-Christians comes easily to me. </li>
<li class="question" title="Administration">I enjoy handling the details of organizing ideas, people, resources, and time in order to have more effective ministry. </li>
<li class="question" title="Serving">I feel that I am not specifically skilled, but I enjoy doing what needs to be done around the church. </li>
</ol>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
(function( $ ) {
$.fn.extend({
numericScale: function(options) {
var defaults = {
responseRange: 5,
topNumber: 3,
lowOpinionAnswer: 'Lowest',
highOpinionAnswer: 'Highest'
};
var scores = []; // Array to hold scores
var key; // HTML5 localStorage key
var disciplines = []; // Array to hold disciplines
var aHighVals = []; // Array to hold n highest scores
var options = $.extend(defaults, options);
// Act on every target list of the plugin.
return this.each(function() {
var $list = $(this);
key = $list.attr('id') + "_key";
// Replace list items with survey controls.
$($list).children().each(function(index) {
createQuestion($list, $(this), index);
}).filter(':odd').addClass('alt');
// Create HTML for survey & scores containers and button
$list.wrap('<div id="wrap-' + $list.attr('id') +
'" class="survey-wrapper"></div>');
$list.after('<div id="scores-' + $list.attr('id') +
'" class="scores"></div>');
$list.after('<input type="button" id="submitBtn"' +
' class="button btnStyle" value="Show My Gifts"' +
' disabled="disabled" />');
// Hide scores initially
$('#scores-' + $list.attr('id')).hide();
loadScores();
setSubmitBtnState();
console.dir(scores);
// ====================
// Handler:
// ====================
$('input[type="radio"]').change(function(e) {
// Get the discipline of the question
var discipline = $(e.target).closest('li[class~="question"]').attr('data-discipline');
var qNum = $(e.target).attr('name').substr(1) - 1;
// Replace the question's object property 'value' in the Scores array with the new selection
scores[qNum].value = $(e.target).val();
storeScores();
setSubmitBtnState();
});
// ====================
// Function:
// ====================
function storeScores() {
var jsonScores = JSON.stringify(scores);
localStorage.setItem(key, jsonScores);
}
// ====================
// Function:
// ====================
function setSubmitBtnState() {
if (getFormFinished()) {
$('#submitBtn').removeAttr('disabled');
}
else {
$('#submitBtn').attr('disabled', 'disabled');
}
}
// ====================
// Function:
// ====================
function getFormFinished() {
//var boolFinished = true;
for (var i = 0; i < scores.length; i++) {
if (scores[i].value == 0) {
//boolFinished = false;
return false;
break;
}
}
//return boolFinished;
return true;
}
// ====================
// Function:
// ====================
function createQuestion(oList, oItem, index) {
// Add the 'title' of the list item
var title = oItem.attr('title');
var qName = "q" + (index + 1);
// Create score items in scores Array.
createScore(oItem, title, qName);
var question = "<div class='opinion-question'>" +
oItem.text() + "</div>" +
"<div class='opinion-responses'>" +
"<span class='bipolar-adjective'>" +
defaults.lowOpinionAnswer + "</span>";
// Create a radio button group for each question.
for (var i = 1; i <= defaults.responseRange; ++i) {
question += "<span class='response-choice'>" +
"<input type='radio' name='" + qName +
"' value='" + i + "' class='radio'";
// Create a LocalStorage item for each question.
//check if discipline's localstorage is set.
if (localStorage.getItem(oList.attr('id') + "_" + qName)) {
if (localStorage.getItem(oList.attr('id') + "_" + qName) == i) {
question += " checked='checked'";
}
}
// Add required attribute to first radio button in group to allow validation with the jquery.validate.js plugin.
if (i == 1) {
question += " validate='required:true'";
}
question += " />" + i + "</span>";
}
question += "<span class='bipolar-adjective'>" + defaults.highOpinionAnswer + "</span>" + "</div>";
oItem.empty().prepend(question).attr('data-discipline', oItem.attr('title')).removeAttr('title');
}
// ====================
// Function:
// ====================
function createScore(oItem, d, qName) {
var score = {};
score.question = qName;
score.value = oItem.val();
score.discipline = d;
scores.push(score);
}
// ====================
// Function:
// ====================
function addScoreToPage(score) {
if (replace(scores, score.question, score.value)) {
var scoreUl = document.getElementById('scores-' + $list.attr('id') + '-ul');
var li = document.createElement('li');
li.innerHTML = score.question + '; ' + score.value + '; ' + score.discipline;
if (scoreUl.childElementCount > 0) {
scoreUl.insertBefore(li, scoreUl.firstChild);
} else {
scoreUl.appendChild(li);
}
}
}
// ====================
// Function:
// ====================
function replace(arrayName, replaceTo, replaceWith) {
for (var i = 0; i < arrayName.length; i++) {
if (arrayName[i].question == replaceTo) {
arrayName.splice(i, 1, replaceWith);
return true;
} else {
return false;
}
}
}
// ====================
// Function:
// ====================
function getHighestScores(oItems, num) {
for (var key in oItems) {
var obj = oItems[key];
for (var prop in obj) {
}
}
}
// ====================
// Function:
// ====================
function surveySetup() {
var submitButton = document.getElementById("submitBtn");
submitButton.onclick = submitSurvey;
if (!window.localStorage) {
alert("The Web Storage API is not supported in your browser. You may still submit the form, but your answers will not be saved to your browser.")
} else {
loadScores();
}
}
// ====================
// Handler:
// ====================
$("#submitBtn").click(function() {
if (!window.localStorage) {
alert("The Web Storage API is not supported in your browser. You may still submit the form, but your answers will not be saved to your browser.")
} else {
submitSurvey();
$('html, body').animate({
scrollTop: $("html, body").offset().top
}, 1000);
}
});
// ====================
// Function:
// ====================
function submitSurvey() {
// Create visual elements for scores.
var surveyId = 'div#scores-' + $list.attr('id');
var dNumber = 0;
var dWidth;
var maxHeight = 350;
var tallBarHeight = 0;
$(surveyId).empty();
for (var i = 0; i < scores.length; i++) {
if ($('div#' + scores[i].discipline).length == 0) {
var dScore = tallyDiscipline(scores[i].discipline);
dNumber++;
var discipline = {};
discipline.name = scores[i].discipline;
discipline.value = dScore;
disciplines.push(discipline);
$(surveyId).append("<div id='" + scores[i].discipline + "' class='discipline'><div class='discipline-name'>" + scores[i].discipline + "</div><div class='discipline-total'>" + dScore + "</div>" + "</div>");
if (dScore > tallBarHeight) {
tallBarHeight = dScore;
}
};
$(surveyId).show('fast');
};
//console.dir(disciplines);
//return(disciplines);
dWidth = 100 / dNumber
for (var ii = 0; ii < dNumber; ii++) {
$('.scores .discipline').eq(ii).css({
'left': Math.floor(dWidth) * ii + '%'
});
$('.scores .discipline').eq(ii).css({
'width': (Math.floor(dWidth) - 1) + '%'
});
barHeight = Math.floor((disciplines[ii].value / tallBarHeight) * maxHeight)
$('.scores .discipline').eq(ii).animate({
height: barHeight
}, 2000);
$('.scores .discipline'); //.addClass('box');
};
getHighestValues();
$list.hide();
$('#submitBtn').hide();
$('[id*="btnSaveGifts"]').show();
};
// ====================
// Function:
// ====================
function getHighestValues() {
for (var i = 0; i < disciplines.length; i++) {
aHighVals[i] = [disciplines[i].value, disciplines[i].name];
}
aHighVals.sort(mySorting);
aHighVals.splice(defaults.topNumber, aHighVals.length - defaults.topNumber);
for (var ii = 0; ii < aHighVals.length; ii++) {
$('#' + aHighVals[ii][1]).addClass('selected');
$('input[id*="hdnSelectedVals"]').val($('input[id*="hdnSelectedVals"]').val() + aHighVals[ii][1]);
if (aHighVals.length - 1 > ii) {
$('input[id*="hdnSelectedVals"]').val($('input[id*="hdnSelectedVals"]').val() + ", ");
}
}
}
// ====================
// Function:
// ====================
function mySorting(a, b) {
a = a[0];
b = b[0];
return b == a ? 0 : (b < a ? -1 : 1)
}
// ====================
// Function:
// ====================
function tallyDiscipline(discipline) {
var total = 0;
for (var i = 0; i < scores.length; i++) {
if (scores[i].discipline == discipline) {
total += parseInt(scores[i].value);
}
}
return total;
}
// ====================
// Function:
// ====================
function loadScores() {
var jsonScores = localStorage.getItem(key);
if (jsonScores != null) {
scores = JSON.parse(jsonScores);
for (var i = 0; i < scores.length; i++) {
addScoresToPage(scores[i]);
}
}
}
// ====================
// Function:
// ====================
function addScoresToPage(score) {
$('input:radio[name=' + score.question + '][value=' + score.value + ']').attr('checked', 'checked');
}
});
}
});
})( jQuery );
var disciplines = $('#survey1').numericScale({
'responseRange' : 5,
'lowOpinionAnswer' : 'Least like me',
'highOpinionAnswer' : 'Most like me'
});
console.dir(disciplines);
</script>
</body>
</html>
I've put everything is one file

Categories