Ограничение количества символов в textarea

Предположим, нам захотелось ограничить длину текста, вводимого пользователем в текстовое поле нашей формы (да-да, примерно как в Твиттере). «Из коробки» Друпал такой возможности нам не предоставляет, свойства элемента формы, задающего максимальную длину текста в textarea — нет. Однако сделать ограничение руками оказывается довольно просто.

Для определенности озвучим задачу: мы хотим, чтобы для текстового поля note длина текста была ограничена заданным числом. При этом пользователю при вводе выводилось бы оставшееся число символов, а текст, введенный сверх этого числа — беспощадно удалялся (для чего задействуем jQuery).

Начнем с описания формы:

$form['note'] = array(
  '#type' => 'textarea',
  '#title'    => t("Note"),
  '#description' => '<div class="note-length-limit-msg">' .t('Note length is limited to <span class="note-char-length">@length</span> characters.', array('@length' => $length,)) .'</div>',
  '#attributes' => array('class' => 'length-limited'),
);

Здесь в переменной $length содержится значение максимального количества символов. Выводить его мы будем в описании текстового поля, показывать оставшееся число символов будем там же.

Теперь добавим на страницу с формой небольшой яваскрипт:

Drupal.behaviors.noteBehaviour = function (context) {
  var lengthMsg = $("div.note-length-limit-msg");
  //будем ограничивать длину только если найдены формы с классом div.note-length-limit-msg
  if (lengthMsg.length > 0) {
    //определим максимальную длину прямо из текста
    var lengthVal = lengthMsg.find("span.note-char-length").text();
    lengthVal = (lengthVal - 0); //toInt
    //обновим сообщение (а кто выключил JS - будет видеть старое сообщение)
    lengthMsg.html(Drupal.t('There are <span class="note-char-length">@count</span> characters left', {'@count': lengthVal}));
    $("textarea.length-limited").keyup( function() {
      var newValue = $(this).val();
      if (newValue.length <= lengthVal) {
        //еще есть символы, обновим сообщение
        lengthMsg.html(Drupal.t('There are <span class="note-char-length">@count</span> characters left', {'@count': (lengthVal-newValue.length)}));
        lengthMsg.find("span.note-char-length").css("font-weight","normal");
      } else {
        //лимит превышен, обрезаем текст
        $(this).val($(this).val().substr(0,lengthVal));
        //выделим нуль, чтобы пользователь заметил
        lengthMsg.find("span.note-char-length").css("font-weight","bold");
      }
    });
}

Вот и все, теперь каждый пользователь с включенным JavaScript-ом сможет уложить свою мысль в выделенные ему $length символов, а если у него не будет получаться — скрипт поможет (автоматически удалит лишний текст при наборе). Замечу только, что если на одной странице планируется разместить сразу несколько текстовых полей с ограниченной длиной, скрипт придется слегка причесать.

Напоследок не забудем добавить аналогичное ограничение и в валидацию формы, ведь выключившие JS граждане смогут ввести в форму столько символов, сколько им хочется:

if (strlen($form_state['values']['note']) > $length) {
  form_set_error('note', t('Maximum note length exceeded.'));
}

Таким образом, получается, что для решения задачи нам необходимо вставить код в трех местах — в описании формы, в валидаторе и в скрипте обработки текстового поля. Ах да, еще и вставить скрипт с помощью drupal_add_js(). И это придется делать всякий раз, когда мы захотим создать очередное текстовое поле с описанными свойствами. Ситуация неидеальная, имеет смысл ее улучшить. Например, сделать так, чтобы для каждого элемента textarea можно было просто указать свойство, называющееся, скажем, '#max_length', а все остальное делалось автоматически. И три недели назад на горизонте появилось решение в виде модуля Form Extended. Данный модуль как раз задуман для облегчения создания новых свойств элементов форм и их интеграции с существующими формами Друпала (как через API, так и через UI). Правда, в настоящий момент единственный релиз модуля — 'dev', а описание API отсутствует. Можно посмотреть демку, в которой показано текстовое поле с автоподстройкой размера (симпатишное), но про API там тоже ничего нет.

А поскольку изучение API по одному только коду dev-релиза я считаю излишним героизмом, придется применение Form Extended отложить до выхода стабильной версии или хотя бы документации. Как выйдет — постараюсь исследовать API модуля в отдельной заметке. И заодно сравнить его с уже существующим в Друпале хуком hook_elements(), поскольку с его помощью тоже можно создавать собственные свойства для элементов форм.

На этом пока все.

Гость (гость)
Аватар пользователя Гость
neochief (гость)
Аватар пользователя neochief

Роман, установите пожалуйста http://drupal.org/project/comment_notify. Это позволит вести дискуссию, я не отвечать один раз.

graker
Аватар пользователя graker

Цитата:
http://drupal.org/project/maxlength
Посмотрел описание, не нашел ничего про API и свойства элемента. Судя по странице модуля, он дает включать ограничения только для тела и заголовка ноды. А мне очень надо, чтобы к произвольной textarea в модуле можно было прилепить.

Цитата:
Роман, установите пожалуйста http://drupal.org/project/comment_notify. Это позволит вести дискуссию, я не отвечать один раз.
Это можно. Раньше как-то subscriptions-а хватало, но понятно, что заставлять всех регистрироваться - плохой выход :) Вечером поставлю.

graker
Аватар пользователя graker

neochief пишет:
Роман, установите пожалуйста http://drupal.org/project/comment_notify. Это позволит вести дискуссию, я не отвечать один раз.
Установил. Для тестирования первым подписал на эту тему вас :)

Гость (гость)
Аватар пользователя Гость

Да, вроде пашет, спасибо :)

Иван (гость)
Аватар пользователя Иван

А можно задать минимальное число для node?

graker
Аватар пользователя graker

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

Иван (гость)
Аватар пользователя Иван

graker пишет:
В админке, в настройках типа содержимого можно задать минимальное число слов для тела ноды.

А подскажите пожалуйста подробнее где это искать, у меня друпал7... только начал изучать и не получается

graker
Аватар пользователя graker

Не работаю с Друпал 7 :)

Иван (гость)
Аватар пользователя Иван

ну а в других версиях? они ведь похожи наверно, я даже не знаю где примерно смотреть..

graker
Аватар пользователя graker

В шестерке — admin/content/node-type/<тип ноды>.

Иван (гость)
Аватар пользователя Иван

спасибо!

graker
Аватар пользователя graker

На здоровье :)

Отправить комментарий

CAPTCHA
Пройдите, пожалуйста, проверку. Она нужна, чтобы отличать людей от спам-роботов. А если не хотите проходить эту проверку регулярно — зарегистрируйтесь.
Image CAPTCHA
Введите цифры, изображенные на картинке (без пробелов).