With the help of you fantastic JavaScript wizards I've got a native JavaScript function that beefs up the size of an HTML5 video when clicking a button and then re-runs whenever the window is resized.
I'd like to remove the button from the equation instead launching it on page load, remove the class name dependencies (if they're still in after button removal), while maintaining the window resize trigger.
Thanks for your help! Couldn't do it without you. A demo can be seen at http://kzmnt.com/test/
JavaScript:
var clicked = document.getElementById("buttonImportant")
var videoContainer = document.getElementById('video_container');
var video = videoContainer.getElementsByTagName('video')[0];
video.style.height="auto";
video.style.width="1280px";
clicked.addEventListener('click',function(){
if( videoContainer.className.lastIndexOf("fullScreen")>=0 ){
videoContainer.className="video-js-box";
video.style.height = "";
video.style.width="";
}
else
{
videoContainer.className="video-js-box fullScreen";
video.style.height = "";
video.style.width="";
}
myResizerObject.prevWidth = video.offsetWidth;
myResizerObject.prevHeight = video.offsetHeight;
myResizerObject.Init();
},false);
var RESIZER = function(){
this.prevWidth = video.offsetWidth;
this.prevHeight = video.offsetHeight;
this.videoContainer = document.getElementById('video_container');
this.video = videoContainer.getElementsByTagName('video')[0];
this.videoStyle = this.video.style;
var ratio = this.video.offsetHeight/this.video.offsetWidth;
var that = this;
this.Init = function(){
if( that.videoContainer.className.lastIndexOf("fullScreen")>=0 )
{
var videoContOffsetWidth = that.videoContainer.offsetWidth;
var videoOffsetWidth = that.video.offsetWidth;
var videoContOffsetHeight = that.videoContainer.offsetHeight;
var videoOffsetHeight = that.video.offsetHeight;
if(that.prevWidth!= videoContOffsetWidth)
{
that.prevWidth = videoContOffsetWidth;
var desired = videoContainer.offsetHeight/videoContainer.offsetWidth;
if(desired>ratio){
that.videoStyle.width=videoContOffsetWidth*desired+videoContOffsetWidth*desired+"px";
that.videoStyle.left = -1*(videoOffsetWidth-videoContOffsetWidth)/2+'px';
}
else{
that.videoStyle.cssText="height:auto;width:100%;left:0px;top:0px;";
}
}
if(that.prevHeight!=videoContOffsetHeight)
{
that.prevHeight = videoContOffsetHeight;
var desired = videoContOffsetHeight/videoContOffsetWidth;
if(desired>ratio){ console.log(ratio);
that.videoStyle.top = '0px';
that.videoStyle.left = -1*(videoOffsetWidth-videoContOffsetWidth)/2+'px';
that.videoStyle.width = videoContOffsetHeight*desired+videoContOffsetHeight/desired+'px';
}
else
{
that.videoStyle.top = -1*(videoOffsetHeight-videoContOffsetHeight)/2+'px';
}
}
}
};
};
var myResizerObject = new RESIZER();
window.onresize = myResizerObject.Init;
Are you looking for something like...
window.onload = mySuperCoolFunction;
And why do you need jQuery? Maybe you could explicitly state your goals/questions at the bottom in bold so that we can help you :)
If you're only looking to init another function, why not just add the call to your superCoolFunction while you're calling your other pre-written jQuery function. For example:
$(document).ready(function() {
center();
mySuperCoolFunction(); // not necessary to init in another file...
});
$(window).load(function(){
center();
mySuperCoolFunction();
});
$(window).resize(function(){
center();
mySuperCoolFunction();
});
Rewritten in jQuery:
$(function() {
$('video').eq(0).css({
height: "auto",
width: "1280px"
});
if ($('#video_container').hasClass('fullScreen')) {
$('#video_container').attr('class', 'video-js-box');
$('video').eq(0).css({
height: "auto",
width: "1280px"
});
}
else {
$('#video_container').attr('class', 'video-js-box fullscreen');
$('video').eq(0).css({
height: "auto",
width: "1280px"
});
}
myResizerObject.prevWidth = video.offsetWidth;
myResizerObject.prevHeight = video.offsetHeight;
myResizerObject.Init();
});
Related
When the window loads, the console is returning indexIn.But when I run the bottom function, it returns NaN.
const recentItem = document.querySelector('.recent-item');
var indexIn;
window.onload = function() {
var indexIn = JSON.parse(localStorage.getItem("indexInStore"));
var indexOut = JSON.parse(localStorage.getItem("indexOutStore"));
var indexIn = Number(indexIn);
console.log(indexIn);
}
var indexIn = indexIn;
recentItem.addEventListener('click', function() {
console.log(indexIn);
});
Can you try:
const recentItem = document.querySelector('.recent-item');
var indexIn;
window.onload = function() {
indexIn = Number(JSON.parse(localStorage.getItem("indexInStore")));
var indexOut = JSON.parse(localStorage.getItem("indexOutStore"));
console.log(indexIn);
}
recentItem.addEventListener('click', function() {
console.log(indexIn);
});
You have indexIndefined globally then your are "redefining" it and setting in inside an "onload" function. Not good coding.
I use prettyPhoto version: 3.1.6 to display simple lightbox with thumbnail.
Normally title attribute appear inside the lightbox for the active/selected image.
My client ask for this change
http://i.stack.imgur.com/7932x.jpg
How I can accomplish this?
Here is a part of my code
<a rel="prettyPhoto[pp_gal]"href="1.jpg" title="Staring at the sun"><img src="2.jpg"></a>
try this jquery function. You may have to style it a little.
(function($)
{
$.fn.avia_activate_lightbox = function(variables)
{
var defaults =
{
autolinkElements: 'a[rel^="prettyPhoto"], a[rel^="lightbox"], a[href$=jpg], a[href$=png], a[href$=gif], a[href$=jpeg], a[href$=".mov"] , a[href$=".swf"], a[href$=".flv"] , a[href*="vimeo.com"] , a[href*="youtube.com"]'
};
var options = $.extend(defaults, variables);
var imagedefaults =
{
autolinkImages: 'img[title!=""]'
};
return this.each(function()
{
var elements = $(options.autolinkElements, this),
lastParent = "",
counter = 0;
var images = $(imagedefaults.autolinkImages, this),
imgcounter = 0;
var alltitlesalt = new Array();
var alltitles = new Array();
images.each(function()
{
if($(this).attr('alt') != undefined && $(this).attr('alt') !="")
{
alltitlesalt.push($(this).attr('alt'));
}
else
{
alltitlesalt.push("");
};
alltitles.push($(this).attr('title'));
});
elements.each(function()
{
var el = $(this),
parentPost = el.parents('.post-entry:eq(0)'),
group = 'auto_group';
if(parentPost.get(0) != lastParent)
{
lastParent = parentPost.get(0);
counter ++;
}
if((el.attr('rel') == undefined || el.attr('rel') == '') && !el.hasClass('noLightbox'))
{
el.attr('rel','lightbox');
el.attr('title',alltitles[imgcounter]);
el.attr('alt',alltitlesalt[imgcounter]);
imgcounter ++;
}
});
if($.fn.prettyPhoto)
elements.prettyPhoto({ "theme": 'premium_photo', 'slideshow': 5000 }); /* facebook /light_rounded / dark_rounded / light_square / dark_square */
});
};
})(jQuery);
Reference
I am trying to modify the following titanium Widget.
https://github.com/pablorr18/TiFlexiGrid
It is a photo gallery, where you can fetch remote images and store it in a gallery. See this question for a background to what the problem is:
Modifying widgets in an alloy project
The trouble I am having is that, like the poster in that thread said, I am unable to get the variable passed (in this case image URL) to my controller using callback functions. In Widget.JS, at the bottom of the file, I added the following code:
Widget.xml
<Alloy>
<View id="fgMain">
<Button title="Click me!" onTouchend="buttonClicked"/>
<View id="fgWrapper">
<ScrollView id="fgScrollView"/>
</View>
</View>
</Alloy>
Widget.js
// This will hold our callback
var onClickCallback;
// The button has been clicked, call callback
function buttonClicked(e) {
if(typeof(onClickCallback) === 'function') {
onClickCallback({ type:'clicked!' }); }
}
// Assign our callback
function onClick(callback) {
onClickCallback = callback;
};
// Make the onClick function public
exports.onClick = onClick;
I was then hoping to go into my main app and get the values from the callback function like this:
photoGallery.xml
<Alloy>
<Window>
<Widget id="myWidget" src="myWidget" />
</Window>
</Alloy>
photoGallery.js
// Now we can intercept the click within the widget
// and use the values passed
$.myWidget.onClick(function(e) {
alert(e.type);
});
The trouble is, as the onTouchend event did not fire, I was unable to pass the variable to the controller which inherits the widget as the callback functions are not set.
The original widget.js code is as follows:
exports.createGrid = function(args){
var params = args || {};
//Ti.API.info('Params es ---> '+ JSON.stringify(params));
var columns = params.columns || 4;
var space = params.space || 5;
var data = params.data || {};
var options = params.params || {};
var layout = params.layout || 'gallery';
var screenWidth = params.width || Ti.Platform.displayCaps.getPlatformWidth();
if (OS_ANDROID) {
screenWidth /= Ti.Platform.displayCaps.logicalDensityFactor;
}
var newWidth = screenWidth - space;
var columnWidth = (newWidth / columns) - space;
var frameBGcolor = options.backgroundColor || '#fff';
//ADJUST THE SCROLLVIEW
$.fgScrollView.left = space;
$.fgScrollView.top = space;
$.fgScrollView.right = -1;
$.fgMain.backgroundColor = frameBGcolor;
for (var x=0;x < data.length; x++){
var frame = Ti.UI.createView({
width:columnWidth,
height:columnWidth,
backgroundColor:options.gridColor || '#eee',
top:0,
left:0,
right:space,
bottom:space
});
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height:Ti.UI.FILL,
backgroundColor:'transparent',
zIndex:1,
strImage:data[x].image
});
var gridElement;
//TYPE OF LAYOUT
switch(layout){
case('gallery'):
gridElement = Widget.createController('gallery',{
image:data[x].image,
title:data[x].title,
width:columnWidth,
padding:options.padding || 10,
showTitle:options.showTitle || false
}).getView();
overlay.addEventListener('click',function(e){
exports.openModal(e.source.strImage);
});
break;
case('customView'):
gridElement = data[x];
break;
}
frame.add(gridElement);
// This condition makes the overlay not be added if it's not gallery layout.
// It's used to make the custom view, caputre the click method. If not,
// The overlay is on top of it and captures the click.
if(layout == 'gallery')
frame.add(overlay);
$.fgScrollView.add(frame);
};
};
exports.openModal = function(url){
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
backgroundColor:'#000',
opacity:0,
zIndex:100
});
var topView = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
zIndex:1200,
visible:false
});
//this gets image , adds it to top view
var imgView = Ti.UI.createImageView({
image: url,
width:Ti.UI.SIZE,
height: Ti.UI.SIZE
});
//add it
topView.add(imgView);
$.fgMain.add(overlay);
if (OS_IOS){
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200});
//ANIMATION FOR POP EFFECT
var t = Titanium.UI.create2DMatrix();
t = t.scale(0);
var a = Titanium.UI.createAnimation();
a.transform = t;
a.duration = 200;
$.fgMain.add(topView);
topView.animate(a);
a.addEventListener('complete', function(){
topView.visible = true;
var t2 = Titanium.UI.create2DMatrix();
t2 = t2.scale(1.2);
topView.animate({transform:t2, duration:200},function(e){
var t4 = Titanium.UI.create2DMatrix();
t4 = t4.scale(1.0);
topView.animate({transform:t4, duration:200});
//alert('animation complete');
//hide cancel button
});
});
}
else{
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200},function(e){
topView.visible = true;
$.fgMain.add(topView);
});
}
topView.addEventListener('click',function(e){
if (OS_IOS){
var t3 = Titanium.UI.create2DMatrix();
t3 = t3.scale(1.2);
var a2 = Titanium.UI.createAnimation();
a2.transform = t3;
a2.duration = 200;
topView.animate(a2);
a2.addEventListener('complete', function(){
var t5 = Titanium.UI.create2DMatrix();
t5 = t5.scale(0);
topView.animate({transform:t5, duration:200},function(e){
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
});
});
}
else{
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
}
});
};
exports.clearGrid = function(){
$.fgScrollView.removeAllChildren();
};
From looking at it, the only way it seems to get an event handler to register is to put it one of the functions (createGrid) and call it like this:
exports.createGrid in widget.xml
var button = Titanium.UI.createButton({
title : 'Use Picture',
top : 10,
width : 100,
height : 50
});
button.addEventListener('click',function(e)
{
Titanium.API.info(url);
//do not want to store in global variable
Alloy.Globals.urlFromGal = url;
});
//add it
topView.add(imgView);
topView.add(button);
$.fgMain.add(overlay);
However I am not sure how to adapt that code to this:
// This will hold our callback
var onClickCallback;
// The button has been clicked, call callback
function buttonClicked(e) {
if(typeof(onClickCallback) === 'function') {
onClickCallback({ type:'clicked!' }); }
}
// Assign our callback
function onClick(callback) {
onClickCallback = callback;
};
// Make the onClick function public
exports.onClick = onClick;
So that I am able to access the url variable outside of the widget.js scope. I could use GLOBAL Variables - by that store the variable in one instead for this task, however I want to avoid doing things this way.
UPDATE:
Unable to get it working, but I have added the callback into an event handler. Got the event handler to fire, but not sure how to pass the callback data to onClick function:
var onClickCallback;
exports.createGrid = function(args){
var params = args || {};
//Ti.API.info('Params es ---> '+ JSON.stringify(params));
var columns = params.columns || 4;
var space = params.space || 5;
var data = params.data || {};
var options = params.params || {};
var layout = params.layout || 'gallery';
var screenWidth = params.width || Ti.Platform.displayCaps.getPlatformWidth();
if (OS_ANDROID) {
screenWidth /= Ti.Platform.displayCaps.logicalDensityFactor;
}
var newWidth = screenWidth - space;
var columnWidth = (newWidth / columns) - space;
var frameBGcolor = options.backgroundColor || '#fff';
//ADJUST THE SCROLLVIEW
$.fgScrollView.left = space;
$.fgScrollView.top = space;
$.fgScrollView.right = -1;
$.fgMain.backgroundColor = frameBGcolor;
for (var x=0;x < data.length; x++){
var frame = Ti.UI.createView({
width:columnWidth,
height:columnWidth,
backgroundColor:options.gridColor || '#eee',
top:0,
left:0,
right:space,
bottom:space
});
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height:Ti.UI.FILL,
backgroundColor:'transparent',
zIndex:1,
strImage:data[x].image
});
var gridElement;
//TYPE OF LAYOUT
switch(layout){
case('gallery'):
gridElement = Widget.createController('gallery',{
image:data[x].image,
title:data[x].title,
width:columnWidth,
padding:options.padding || 10,
showTitle:options.showTitle || false
}).getView();
overlay.addEventListener('click',function(e){
exports.openModal(e.source.strImage);
});
break;
case('customView'):
gridElement = data[x];
break;
}
frame.add(gridElement);
// This condition makes the overlay not be added if it's not gallery layout.
// It's used to make the custom view, caputre the click method. If not,
// The overlay is on top of it and captures the click.
if(layout == 'gallery')
frame.add(overlay);
$.fgScrollView.add(frame);
};
};
exports.openModal = function(url){
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
backgroundColor:'#000',
opacity:0,
zIndex:100
});
var topView = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
zIndex:1200,
visible:false
});
//this gets image , adds it to top view
var imgView = Ti.UI.createImageView({
image: url,
width:Ti.UI.SIZE,
height: Ti.UI.SIZE
});
var button = Titanium.UI.createButton({
title : 'Use Picture',
top : 10,
width : 100,
height : 50
});
button.addEventListener('touchend',function(e)
{
//Titanium.API.info(url);
if(typeof(onClickCallback) === 'function') {
onClickCallback({ type:'clicked!' }); }
});
//pass callback, not working
onClick();
//add it
topView.add(imgView);
topView.add(button);
$.fgMain.add(overlay);
if (OS_IOS){
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200});
//ANIMATION FOR POP EFFECT
var t = Titanium.UI.create2DMatrix();
t = t.scale(0);
var a = Titanium.UI.createAnimation();
a.transform = t;
a.duration = 200;
$.fgMain.add(topView);
topView.animate(a);
a.addEventListener('complete', function(){
topView.visible = true;
var t2 = Titanium.UI.create2DMatrix();
t2 = t2.scale(1.2);
topView.animate({transform:t2, duration:200},function(e){
var t4 = Titanium.UI.create2DMatrix();
t4 = t4.scale(1.0);
topView.animate({transform:t4, duration:200});
//alert('animation complete');
//hide cancel button
});
});
}
else{
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200},function(e){
topView.visible = true;
$.fgMain.add(topView);
});
}
topView.addEventListener('click',function(e){
if (OS_IOS){
var t3 = Titanium.UI.create2DMatrix();
t3 = t3.scale(1.2);
var a2 = Titanium.UI.createAnimation();
a2.transform = t3;
a2.duration = 200;
topView.animate(a2);
a2.addEventListener('complete', function(){
var t5 = Titanium.UI.create2DMatrix();
t5 = t5.scale(0);
topView.animate({transform:t5, duration:200},function(e){
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
});
});
}
else{
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
}
});
};
exports.clearGrid = function(){
$.fgScrollView.removeAllChildren();
};
// Assign our callback
function onClick(callback) {
onClickCallback = callback;
alert(onClickCallback);
};
// Make the onClick function public
exports.onClick = onClick;
I have created a "prev/next" slideshow using javascript, now I want to add a counter(1/10, 2/10, 3/10...) beside my "prev/next" buttons but nothing seemed to work.
This is my first time attempting to make a website, I know nothing about jQuery, so please stick with html+javascript if possible. Here is my script
var image = new Array(
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg")
var imgNumber=1
var numberOfImg=2
function previousImage(){
if(imgNumber>1){
imgNumber--
}
else{
imgNumber = numberOfImg
}
document.slideImage.src = image[imgNumber-1]
}
function nextImage(){
if(imgNumber < numberOfImg){
imgNumber++
}
else{
imgNumber = 1
}
document.slideImage.src = image[imgNumber-1]
}
if(document.images){
var image1 = new Image()
image1.src = "http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg"
var image2 = new Image()
image2.src = "http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg"
}
Script+html: http://jsfiddle.net/nLHY9/5/
(Prev/Next buttons seem not to be working on this----they work fine when I launched them from laptop to browser.)
you could have used some existing javascript image sliders, for example, sliderman slider, for your current code, you can do like, add an element like span, to hold the count, and you could add a function like:
function changeCounter(cur, total) {
document.getElementById("counter").innerHTML = cur + "/" + total;
}
and call it in your previousImage() and nextImage() functions, as in this demo jsfiddle
There are many pure css slideshows that are beautiful and can do impressive things. However, as you try to support older browsers, the pure css slideshows get less and less impressive or even impossible. JavaScript is the most flexible and powerful way to go. That being, I wanted to help you clean up your code. I only had a few minutes, so this is a quickly thrown together plugin, but it should get you on the right track.
First, a few notes on your code:
//you're missing semicolons everywhere. ";"
/* "var image" is very unclear.
* it's an array, so it should be plural "images"
* there aren't images in this array - it's image urls or sources
* instead of "new Array" you could just use "[]"
*/
var image = new Array(
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg")
var imgNumber=1 //the name doesn't mean anything. I have to assume that you mean "currentImgNumber" or something to that effect
var numberOfImg=2 //this could be determined by checking the length of your array - myArray.length
And here's my exampe plugin:
Live demo here (click).
/***** This section is how you use the plugin. I start writing with the usage and then I make it mean something *****/
window.onload = function() { //when the page is loaded
var fooElem = document.getElementById('foo'); //get an element where we will attach the plugin
var foo = Object.create(slideshow); //create a new slideshow object
foo.create({ //create a slideshow with the given options
element: fooElem, //the element where the slideshow will be
sources: [ //image urls
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg"
]
});
//we can make more of these and with different options
var barElem = document.getElementById('bar');
var bar = Object.create(slideshow);
bar.create({
element: barElem,
sources: [
"http://eggboss.com/wp-content/uploads/2013/09/The-Gentleman-233x300.png",
"http://fc07.deviantart.net/fs71/f/2013/040/8/a/profile_picture_by_classy_like_a_sir-d5uf426.jpg"
]
});
};
/**** now let's create the plugin and make it work as it is used above *****/
var slideshow = {
currentIndex: 0,
imgs: [],
create: function(options) {
options.element.className+= ' slideshow'; //add a class to the main element for styling
this.imgs = this.getImgs(options.sources); //make img html
var controls = this.getControls(); //make controls
//add the html to the element from the options
var frag = document.createDocumentFragment();
this.imgs.forEach(function(img) {
frag.appendChild(img);
});
frag.appendChild(controls);
options.element.appendChild(frag);
},
getImgs: function(sources) {
var imgs = [];
sources.forEach(function(src, i) {
var img = document.createElement('img');
img.src = src;
imgs.push(img);
if (i > 0) {
img.style.display = 'none'; //hide all but first image
}
});
return imgs;
},
getControls: function() {
var that = this; //so that we can access "this" within the click functions
var controls = document.createElement('div');
controls.className = 'controls';
var counter = document.createElement('span');
counter.className = 'counter';
this.setCounter(counter);
var prev = document.createElement('a');
prev.textContent = 'Prev';
prev.className = 'prev';
prev.addEventListener('click', function() {
newIndex = (that.currentIndex) ? that.currentIndex-1 : that.imgs.length-1;
that.changeImg(newIndex, counter);
});
var next = document.createElement('a');
next.textContent = 'Next';
next.className = 'next';
next.addEventListener('click', function() {
newIndex = (that.currentIndex !== that.imgs.length-1) ? that.currentIndex+1 : 0;
that.changeImg(newIndex, counter);
});
controls.appendChild(prev);
controls.appendChild(next);
controls.appendChild(counter);
return controls;
},
changeImg: function(newIndex, counter) {
this.imgs[this.currentIndex].style.display = 'none';
this.imgs[newIndex].style.display = 'inline';
this.currentIndex = newIndex;
this.setCounter(counter);
},
setCounter: function(counter) {
counter.textContent = (this.currentIndex+1)+' / '+this.imgs.length;
}
};
This is my first attempt at a plugin but I think I'm missing the whole "How to" on this.
Ok here goes:
Trying to write an error popup box for form validation.
I like the look and functionality on this JavaScript code on this page, See demo here and source here.
It's basically what I want to do if the user enters invalid data.
Now I have tried to create a jQuery plugin with this code but it's not working, any help would be great :-)
(function($){
/* Might use the fadein fadeout functions */
var MSGTIMER = 20;
var MSGSPEED = 5;
var MSGOFFSET = 3;
var MSGHIDE = 3;
var errorBox = function(target, string, autohide, options)
{
var ebox = $(ebox);
var eboxcontent = $(eboxcontent);
var target = $(target);
var string = $(string);
var autohide = $(autohide);
var obj = this;
if (!document.getElementById('ebox')) {
ebox = document.createElement('div');
ebox.id = 'ebox';
eboxcontent = document.createElement('div');
eboxcontent.id = 'eboxcontent';
document.body.appendChild(ebox);
ebox.appendChild(eboxcontent);
ebox.style.filter = 'alpha(opacity=0)';
ebox.style.opacity = 0;
ebox.alpha = 0;
}
else {
ebox = document.getElementById('ebox');
eboxcontent = document.getElementById('eboxcontent');
}
eboxcontent.innerHTML = string;
ebox.style.display = 'block';
var msgheight = ebox.offsetHeight;
var targetdiv = document.getElementById(target);
targetdiv.focus();
var targetheight = targetdiv.offsetHeight;
var targetwidth = targetdiv.offsetWidth;
var topposition = topPosition(targetdiv) - ((msgheight - targetheight) / 2);
var leftposition = leftPosition(targetdiv) + targetwidth + MSGOFFSET;
ebox.style.top = topposition + 'px';
ebox.style.left = leftposition + 'px';
clearInterval(ebox.timer);
ebox.timer = setInterval("fadeMsg(1)", MSGTIMER);
if (!autohide) {
autohide = MSGHIDE;
}
window.setTimeout("hideMsg()", (autohide * 1000));
// hide the form alert //
this.hideMsg(msg) = function (){
var msg = document.getElementById('msg');
if (!msg.timer) {
msg.timer = setInterval("fadeMsg(0)", MSGTIMER);
}
};
// face the message box //
this.fadeMsg(flag) = function() {
if (flag == null) {
flag = 1;
}
var msg = document.getElementById('msg');
var value;
if (flag == 1) {
value = msg.alpha + MSGSPEED;
}
else {
value = msg.alpha - MSGSPEED;
}
msg.alpha = value;
msg.style.opacity = (value / 100);
msg.style.filter = 'alpha(opacity=' + value + ')';
if (value >= 99) {
clearInterval(msg.timer);
msg.timer = null;
}
else
if (value <= 1) {
msg.style.display = "none";
clearInterval(msg.timer);
}
};
// calculate the position of the element in relation to the left of the browser //
this.leftPosition(target) = function() {
var left = 0;
if (target.offsetParent) {
while (1) {
left += target.offsetLeft;
if (!target.offsetParent) {
break;
}
target = target.offsetParent;
}
}
else
if (target.x) {
left += target.x;
}
return left;
};
// calculate the position of the element in relation to the top of the browser window //
this.topPosition(target) = function() {
var top = 0;
if (target.offsetParent) {
while (1) {
top += target.offsetTop;
if (!target.offsetParent) {
break;
}
target = target.offsetParent;
}
}
else
if (target.y) {
top += target.y;
}
return top;
};
// preload the arrow //
if (document.images) {
arrow = new Image(7, 80);
arrow.src = "images/msg_arrow.gif";
}
};
$.fn.errorbox = function(options)
{
this.each(function()
{
var element = $(this);
// Return early if this element already has a plugin instance
if (element.data('errorbox')) return;
// pass options to plugin constructor
var errorbox = new errorBox(this, options);
// Store plugin object in this element's data
element.data('errorbox', errorbox);
});
};
})(jQuery);
How Im calling it
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>jQuery Plugin - Error ToolTip</title>
<script type="text/javascript" src="js/jquery.js">
</script>
<script type="text/javascript" src="js/jquery.errorbox.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
var name = document.getElementById('name');
if(name == "") {
$('#name','You must enter your name.',2).errorbox();
alert("Blank");
}
});
</script>
<link rel="stylesheet" type="text/css" href="css/errorbox.css" />
</head>
<body>
<div>
Name: <input type="text" id="name" width="30"></input>
</div>
</body>
Any help on my first plugin would be great, thanks in advance.
--Phill
The var errorBox = function(... needs to change to:
$.errorBox = function(...
then you can call it on the jquery object.
Secondly, for clarity you may want to use $('#eboxcontent') instead of document.getElementById('eboxcontent') . It wont be any faster, but it is "clearer" to other jquery developers.
Lastly, jQuery has many built in functions for fading things over a specified time period, and it appears that you have built your own. I know that jQuery's fading is cross-browser compatible. just use:
$('#someDivId').fadeOut(timeInMilliseconds);
var name = document.getElementById('name');
if(name == "") {
//...
}
should be
var name = document.getElementById('name');
if(name.value == "") {
//...
}
or
var name = $('#name').val();
if(name == "") {
//...
}