- #42446: Resizable textareas.
parent
afd8ccaf7e
commit
5e49dd2a68
|
@ -760,9 +760,15 @@ function theme_form($element) {
|
|||
* A themed HTML string representing the textarea.
|
||||
*/
|
||||
function theme_textarea($element) {
|
||||
$class = 'textarea';
|
||||
if ($element['#resizable'] !== false) {
|
||||
drupal_add_js('misc/textarea.js');
|
||||
$class .= ' resizable';
|
||||
}
|
||||
|
||||
$cols = $element['#cols'] ? ' cols="'. $element['#cols'] .'"' : '';
|
||||
|
||||
return theme('form_element', $element['#title'], '<textarea'. $cols .' rows="'. $element['#rows'] .'" name="'. $element['#name'] .'" id="' . $element['#id'] .'" class="'. _form_get_class('textarea', $element['#required'], form_get_error($element)) .'"'. drupal_attributes($element['#attributes']) .'>'. check_plain($element['#value']) .'</textarea>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
|
||||
return theme('form_element', $element['#title'], '<textarea'. $cols .' rows="'. $element['#rows'] .'" name="'. $element['#name'] .'" id="' . $element['#id'] .'" class="'. _form_get_class($class, $element['#required'], form_get_error($element)) .'"'. drupal_attributes($element['#attributes']) .'>'. check_plain($element['#value']) .'</textarea>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -618,3 +618,17 @@ html.js fieldset.collapsed legend a {
|
|||
* html.js fieldset.collapsible legend a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
** Resizable text areas
|
||||
*/
|
||||
.resizable-textarea {
|
||||
width: 95%;
|
||||
}
|
||||
.resizable-textarea .grippie {
|
||||
height: 14px;
|
||||
background: #eee url('grippie.png') no-repeat 100% 100%;
|
||||
border: 1px solid #ddd;
|
||||
border-top-width: 0px;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
|
|
|
@ -211,6 +211,10 @@ function absolutePosition(el) {
|
|||
return r;
|
||||
};
|
||||
|
||||
function dimensions(el) {
|
||||
return { width: el.offsetWidth, height: el.offsetHeight };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an element has a specified class name
|
||||
*/
|
||||
|
@ -279,6 +283,20 @@ function removeNode(node) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents an event from propagating.
|
||||
*/
|
||||
function stopEvent(event) {
|
||||
if (event.preventDefault) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
else {
|
||||
event.returnValue = false;
|
||||
event.cancelBubble = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around document.getElementById().
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
if (isJsEnabled()) {
|
||||
addLoadEvent(function() {
|
||||
// Attach to all textareas
|
||||
textareas = document.getElementsByTagName('textarea');
|
||||
var textarea;
|
||||
for (var i = 0; textarea = textareas[i]; ++i) {
|
||||
if (hasClass(textarea, 'resizable')) {
|
||||
new textArea(textarea);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function textArea(element) {
|
||||
var ta = this;
|
||||
this.element = element;
|
||||
this.parent = this.element.parentNode;
|
||||
this.dimensions = dimensions(element);
|
||||
|
||||
// Prepare wrapper
|
||||
this.wrapper = document.createElement('div');
|
||||
this.wrapper.className = 'resizable-textarea';
|
||||
this.parent.insertBefore(this.wrapper, this.element);
|
||||
|
||||
// Add grippie and measure it
|
||||
this.grippie = document.createElement('div');
|
||||
this.grippie.className = 'grippie';
|
||||
this.wrapper.appendChild(this.grippie);
|
||||
this.grippie.dimensions = dimensions(this.grippie);
|
||||
this.grippie.onmousedown = function (e) { ta.beginDrag(e); };
|
||||
this.element.onmouseup = function (e) { ta.endDrag(e); };
|
||||
|
||||
// Set wrapper and textarea dimensions
|
||||
this.wrapper.style.height = this.dimensions.height + this.grippie.dimensions.height + 1 +'px';
|
||||
this.element.style.marginBottom = '0px';
|
||||
this.element.style.width = '100%';
|
||||
this.element.style.height = this.dimensions.height +'px';
|
||||
|
||||
// Wrap textarea
|
||||
removeNode(this.element);
|
||||
this.wrapper.insertBefore(this.element, this.grippie);
|
||||
|
||||
// Measure difference between desired and actual textarea dimensions to account for padding/borders
|
||||
this.widthOffset = dimensions(this.wrapper).width - this.dimensions.width;
|
||||
|
||||
// Make the grippie line up in various browsers
|
||||
if (window.opera) {
|
||||
// Opera
|
||||
this.grippie.style.marginRight = this.widthOffset +'px';
|
||||
}
|
||||
if (document.all && !window.opera) {
|
||||
// IE
|
||||
this.grippie.style.width = '100%';
|
||||
this.grippie.style.paddingLeft = '2px';
|
||||
}
|
||||
// Mozilla
|
||||
this.element.style.MozBoxSizing = 'border-box';
|
||||
|
||||
this.heightOffset = absolutePosition(this.grippie).y - absolutePosition(this.element).y - this.dimensions.height;
|
||||
}
|
||||
|
||||
textArea.prototype.beginDrag = function (event) {
|
||||
event = event || window.event;
|
||||
// Capture mouse
|
||||
var cp = this;
|
||||
this.oldMoveHandler = document.onmousemove;
|
||||
document.onmousemove = function(e) { cp.handleDrag(e); };
|
||||
this.oldUpHandler = document.onmouseup;
|
||||
document.onmouseup = function(e) { cp.endDrag(e); };
|
||||
|
||||
// Store drag offset from grippie top
|
||||
var pos = absolutePosition(this.grippie);
|
||||
this.dragOffset = event.clientY - pos.y;
|
||||
|
||||
// Make transparent
|
||||
this.element.style.opacity = 0.5;
|
||||
|
||||
// Process
|
||||
this.handleDrag(event);
|
||||
}
|
||||
|
||||
textArea.prototype.handleDrag = function (event) {
|
||||
event = event || window.event;
|
||||
// Get coordinates relative to text area
|
||||
var pos = absolutePosition(this.element);
|
||||
var y = event.clientY - pos.y;
|
||||
|
||||
// Set new height
|
||||
var height = Math.max(32, y - this.dragOffset - this.heightOffset);
|
||||
this.wrapper.style.height = height + this.grippie.dimensions.height + 1 + 'px';
|
||||
this.element.style.height = height + 'px';
|
||||
|
||||
// Avoid text selection
|
||||
stopEvent(event);
|
||||
}
|
||||
|
||||
textArea.prototype.endDrag = function (event) {
|
||||
// Uncapture mouse
|
||||
document.onmousemove = this.oldMoveHandler;
|
||||
document.onmouseup = this.oldUpHandler;
|
||||
|
||||
// Restore opacity
|
||||
this.element.style.opacity = 1.0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue