Prototype: new Element Shortcut
February 12th, 2009
I thought I might share a little piece of code I use to create new HTML elements using Prototype. When building complex HTML fragments dynamically, always having to type "new Element" and then append the element seems like a lot of work to me. Particularly, when I just want a reference to the parent element. So I wrote this bit of code to cut out a lot of the leg work:
function $e(tag, options, children){
if( typeof tag == 'object' ) children = options, options = tag, tag = 'div';
var el = new Element(tag, options || {});
if( Object.isArray(children) ) children.collect(function(e){
if( Object.isArray(e) ){
el.appendChild($e(e[0], e[1], e[2]));
} else if( Object.isElement(e) ){
el.appendChild(e);
} else {
el.appendChild($e(e));
}
});
return el;
}
This bit of code will allow you to create complex HTML fragments like this:
$e('div', { className: 'foo' }, [ [ 'span', { className: 'bar' } ] ]);
... or ...
$e('div', { className: 'foo' }, [ $e('span', { className: 'bar' }) ]);
... or ...
$e('div', { className: 'foo' }, [ 'span' ]);
Let me know if you find this useful or have suggestion for improvement.
Prototype: Element#replaceClassName
February 27th, 2008
This one is kind of a no brainer. I am kind of surprised it wasn't already in Prototype.
Element.addMethods({
replaceClassName: function(element, className, replacement){
if (!(element = $(element))) return;
return element.removeClassName(className).addClassName(replacement);
}
});
Prototype Element#disableSelection and Element#enableSelection
February 25th, 2008
I thought these methods may help someone out there.
Element.addMethods({
disableSelection: function(element){
if (!(element = $(element))) return;
element.unselectable = 'on';
if( typeof element.onselectstart != 'undefined' ){
element.onselectstart = function(){ return false };
} else if( typeof element.style.MozUserSelect != 'undefined' ){
element.style.MozUserSelect = 'none';
} else {
element.onmousedown = function(){ return false };
}
if( !element.style.cursor ) element.style.cursor = 'default';
return element
},
enableSelection: function(element){
if (!(element = $(element))) return;
element.unselectable = 'on';
if( typeof element.onselectstart != 'undefined' ){
element.onselectstart = null;
} else if( typeof element.style.MozUserSelect != 'undefined' ){
element.style.MozUserSelect = 'none';
} else {
element.onmousedown = null;
}
if( !element.style.cursor ) element.style.cursor = 'default';
return element;
}
});
Script.aculo.us / Prototype: Effect#DropShadow
February 23rd, 2008
This is probably not purely in the spirit of script.aculo.us, because it uses images to accomplish the effect. It was adapted for script.aculo.us/prototype from this blog post. Tested in Firefox 2, Safari 3 and IE7.
Usage:
// adds a drop shadow to a given element
Effect.DropShadow = function(element){
element = $(element);
var i1 = new Element('div', { 'class': 'i1' });
var i2 = new Element('div', { 'class': 'i2' });
var i3 = new Element('div', { 'class': 'i3 cf' });
i2.appendChild(i3);
i1.appendChild(i2);
$A(element.childNodes).each(function(e){ i3.appendChild(e); });
var bfunc = function(className){
var e = new Element('div', { 'class': className });
e.appendChild(new Element('div'));
return e;
};
element.addClassName('cp');
element.appendChild(bfunc('bt'));
element.appendChild(i1);
element.appendChild(bfunc('bb'));
};
Here is the CSS:
/* Drop Shadow Box
--------------------------------------------------- */
.bt { /* Top corners and border */
height: 4px;
margin: 0 0 0 5px;
background: url(drop_shadow_box.png) no-repeat 100% 0;
}
.bt div {
position: relative;
left: -5px;
width: 5px;
height: 4px;
background: url(drop_shadow_box.png) no-repeat 0 0;
font-size: 0;
line-height: 0;
}
.bb { /* Bottom corners and border */
height: 4px;
margin:0 0 0 4px;
background: url(drop_shadow_box.png) no-repeat 100% 100%;
}
.bb div {
position:relative;
left: -4px;
width: 4px;
height: 4px;
background: url(drop_shadow_box.png) no-repeat 0 100%;
font-size: 0;
line-height: 0;
}
.i1 { /* Left border */
padding:0 0 0 4px;
background: url(drop_shadow_borders.png) repeat-y 0 0;
}
.i2 { /* Right border */
padding:0 4px 0 0;
background: url(drop_shadow_borders.png) repeat-y 100% 0;
}
/* Wrapper for the content. Use it to set the background color and insert some
padding between the borders and the content. */
.i3 {
display:block;
margin: 0;
}
and the images here
and here
Usage:
Effect.DropShadow('some_dom_id');
Prototype: IE Leak-Safe Element#remove
February 21st, 2008
Thought this might help someone out. This adapts Prototype's Element#remove method to conditionally use a "leak-safe" method of removal outlined in this post on the MSDN forums.
/*
Adapted for Prototype based on:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2847218&SiteID=1
*/
Element.removeWithoutLeakProtection = Element.Methods.remove;
Element.addMethods({
discard: function(element){
element = $(element);
var garbageBin = $('IELeakGarbageBin') || document.body.appendChild(
new Element('div', { id:'IELeakGarbageBin', style:'display:none;' })
);
garbageBin.appendChild(element);
garbageBin.innerHTML = '';
return element;
},
remove: function(element){
if( Prototype.Browser.IE ){
return Element.discard(element);
} else {
return Element.removeWithoutLeakProtection(element);
}
}
});
Prototype: String#constantize
February 19th, 2008
String.prototype.constantize || (String.prototype.constantize = function(){
return this.charAt(0).toUpperCase() + this.substring(1).dasherize().camelize();
});
Prototype: Array#sum
February 19th, 2008
Array.prototype.sum || (Array.prototype.sum = function(iterator){
var result = 0;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
try { result += parseInt(value || 0); } catch(e){}
});
return result;
});