Widgets: textarea с сюрпризом

Скучное сообщение о количестве набранных символов около поля textarea можно украсить и преобразить. Как это сделать - смотрите ниже.

Вторая статья из серии widgets расскажет о таком давно известном и часто используемом элементе, как textarea с проверкой длины вводимого текста.

Задача, скажем смело, тривиальная, и сложностей никогда не вызывает. Однако, решают её всегда одним и тем же способом:

Моё предложение проще: пусть обработчик сам создаст элемент, в котором будут выводиться три числа: минимальное количество символов, набранное количество символов и максимальное количество.

Как всегда, начнём с примера:

Имя
Комментарии к сделке
Желаемый оклад
Описание деятельности

В общем, в данном подходе ещё раз напоминается утверждение «Краткость – сестра таланта». Три числа, с опознавательными знаками:

При желании, можно заменить эти обозначения на свои (или вообще их убрать, оставив только цветовые обозначения), и ввести четвёртое число – количество возможных оставшихся символов.

Теперь о том, как это работает. К сожалению, на данный момент все подобные обработчики форм вынуждают вставлять javascript-код либо после формы, либо в onLoad всего документа. Не избежала эта участь и наше решение.

Как всегда, не обошлось без требований. Всего их два: первое, textarea должна быть «обёрнута» в любой блочный элемент (т.е. просто ячейка таблицы нам не подходит). И второе: каждому элементу textarea должен быть присвоен id.

JavaScript-код подобного виджета прост. Но для его реализации, нам понадобятся четыре функции:


// prototype-analog
function $(obj) {
  	if (typeof obj == 'object')
  	return obj;
	if (document.getElementById)
		return (document.getElementById(obj));
	else  if (document.all) 
		return document.all(obj);

    return null;
}

// PHP str_replace-analog
String.prototype.str_replace = function(srch, rpl)
{
	var ar = this.split(srch);
	return ar.join(rpl);
}

// Узнаём родительский элемент
function getParent(el) {

	return ((el.parentElement) ? el.parentElement : ((el.parentNode) ? el.parentNode : null));

}

// Узнаём параметры элемента: ширину, высоту, а также координаты
function getElementPosition(el)
{
	
	w = el.offsetWidth;
	h = el.offsetHeight;
	
	l = t = 0;
	
	while (el)
	{
        	l += el.offsetLeft;
        	t += el.offsetTop;
        	el = el.offsetParent;
	}

	return {"left":l, "top":t, "width": w, "height":h};
}


Остальной код состоит из двух, среднего размера, функций:


function createTextAreaWidget(el, min, max)
{
	var el = $(el);
	var counter = $('counter' + el.id);
	if (!counter)
	{
		var parent = getParent(el);
		var counter = document.createElement('div');
		counter.setAttribute('id', 'counter' + el.id);
		counter.className = 'counter';
		parent.appendChild(counter);
		parent.style.position = 'relative';
		counter.style.position = 'absolute';

		counter.style.left = getElementPosition(el).width + 2 +  'px';
		counter.style.top = 0;
		counter.style.height = getElementPosition(el).height + 'px';
	}

	// перенос строки js принимает за два знака. Исправляем.
	len = el.value.str_replace(String.fromCharCode(13), '').length;
	if (len >= max) {
		el.value = el.value.substr(0, max);
		len = max;
	}

	el.onkeyup = function () {createTextAreaWidget(el, min, max);}
	el.onchange = function () {createTextAreaWidget(el, min, max);}
	createStat(counter, min, max, len);	

}

function createStat(el, min, max, current)
{
	el.innerHTML = '<span class=min>&lt; ' + min + '<\/span><br>';
	var className = (current <= min) ? 'gray' : ((current >= max) ? 'red' : 'normal');
	var cur = (current >= max) ? current + ' !!!' : current;
	el.innerHTML += '<span class=' + className + '>= ' + cur + '<\/span><br>';
	el.innerHTML += '<span class=max>&gt; ' + max + '<\/span>';
}

Функция createTextAreaWidget() создаёт элемент для подсчёта символов, и также для указанного элемента textarea создаёт два обработчика, которые вызываются по событиям OnKeyUp, и OnChange. Что особенно приятно, эту функцию можно явно включить в обработчик, то есть, написать в html-коде:


<textarea OnKeyUp='createStat(this, 10, 100);' id="some_id" name="some_text"></textarea>

Три параметра, которые передаются в createTextAreaWidget(el, min, max) не нуждаются в особом пояснении. Всё просто: el - это id текстового поля textarea (или само поле, переданное как this или form.elemens[textarea_index] или form.textarea_name); min - минимальное, а max - максимальное количество вводимых в поле символов.

Функция действует просто: присваивает родительскому элементу свойство CSS display: relative, создаёт DIV-элемент с классом counter, который позиционируется абсолютно. Таким образом, counter можно точно расположить справа от текстового поля textarea, зная длину и ширину текстового поля. Именно это и реализуется в коде.

Далее, необходимо корректно подсчитать количество символов в текстовом поле, обрезать его, если их количество превышает максимально допустимое, и назначить обработчики, не забыв также вызвать функцию createStat().

Функция createStat() заполняет созданный около textarea элемент. Три переданных числа располагаются друг под другом, и содержатся в трёх элементах SPAN с различными стилевыми классами.

Соответствующие CSS-стили могут быть такими, как приведено ниже:

.counter {width: 82px; margin: 0; padding: 0 0 0 4px}

.counter SPAN {padding: 1px 0; font: bold 10px 'MS Sans Serif', serif}

.counter .min {color: #4aa24c}

.counter .max {color: #c2311a}

.counter .gray {color: #ccc}

.counter .red {color: #f00}

.counter .normal {color: #000}

Функция createStat() как раз решает, какой класс и какое значение должно быть у элемента с текущим количеством символов. В нашем примере, если количество меньше минимального, число выводится серым цветом (CSS-класс gray); если количество в пределах допустимого, оно выводится чёрным цветом (класс normal), и, наконец, если текущее число больше или равно максимальному, его цвет красный (класс red) и к числу прибавляются восклицательные знаки.

Вот, практически, и всё. Единственное, что осталось сделать, это вывести под необходимой формой код, который и создаст необходимые элементы и обработчики:


<script type='text/javascript'>
<!--
	createTextAreaWidget('text1', 100, 2500);
	createTextAreaWidget('text2', 0, 200);
-->
</script>

<!-- или сразу в HTML-коде -->

<div><textarea OnKeyUp='createStat(this, 100, 2500);' name="text1" id="some_id1"></textarea></div>
<div><textarea OnKeyUp='createStat(this, 10, 100);' 
	OnChange='createStat(this, 10, 100);' name="text2" id="some_id2"></textarea></div>

Разумеется, приведённое выше решение можно варьировать и изменять как угодно, а если у Вас есть собственное оригинальное решение – смело делитесь им в комментариях.

Скачать исходный код

10 - 12 февраля 2008 года


Оценка материала:

 
На данный момент нет голосовавших

Число просмотров: 0
Андрей, 22.04.2009, 11:07

А как єто всё встроить в php скрипт??

Инкогнито, 07.05.2009, 10:23

Руками

-0poiyg, 18.06.2009, 21:29

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Алексей, mchuk[::::]mail.ru, 20.11.2009, 00:40

Хороший код! Спасибо! А можно добавить туда еще функцию чтобы второй и далее ПОДРЯД пробелы не засчитывались бы счетчиком. А то повадились длину текста пробелами увеличивать...

Алексей, 20.11.2009, 01:43

И деактивировать кнопку Submit пока условие по тексту не будет соблюдено. Ну больше или меньше заданных значений. Вообще бы цены не было б скрипту!

Сергей, biosera[::::]ukr.net, 29.01.2010, 19:40

Здравствуйте! Спасибо очень нужная вещь! Но нельзя ли более подробно объяснить что как и куда вставлять? :) Например мне нужна лиш вторая часть Вашего скрипта - та которая считает просто от 0 до 130 символов..

Сам код - его нужно заключать в теги яваскрипта? и Куда его прописать вначале документа под формой или как? Пожалуйста объясните более подробно чайнику)! Как правильно встроить Ваш скрипт в свою форму (2 часть нужно только подсчет количества символов от 0 до 130) Спасибо заранее большое!

фывфыв, 24.05.2010, 16:09

вфывфыв

Имя *

Цифровой ящик

Комментарии *