Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Мини библиотека для контроля ввода текста в TEXTAREA / INPUT (https://javascript.ru/forum/project/37140-mini-biblioteka-dlya-kontrolya-vvoda-teksta-v-textarea-input.html)

devote 09.04.2013 12:32

Мини библиотека для контроля ввода текста в TEXTAREA / INPUT
 
Привет всем!

Представляю вам очередную свою наработку. Хотя она уже и не новая, написано давно была в виде небольшого плагинчика. Но тут я решился уделить на нее время и немного ее переписать (хотя переписал полностью).

И так, библиотека позволяет контролировать входные данные в текстовые поля, такие как INPUT и TEXTAREA. В использовании очень проста, особенно для тех кто хорошо знаком с регулярными выражениями. Она не требует писать какого либо кода, не засоряет HTML мусором.

Я уже упоминал о ней в некоторых топиках этого форума, поэтому для кого-то она уже будет знакома. А тут я просто опишу ее возможности.

Библиотека работает посредством делегирования, она не вешает на каждый элемент события, а слушает лишь один у корневого элемента. Что позволяет использовать ее для динамично вставленных элементов. Отлавливает события вставки текста из буфера обмена (кроме FireFox, в котором нет реализации clipboardData).

Есть три основных атрибута с которыми она работает и по которым определяет свои действия:
data-let-input
  • Позволяет указать какие данные разрешено вводить в текстовое поле. Тут вы можете указать регулярное выражение в котором будет собран набор разрешенных символов.
    Пример:
    /^[0-9.]$/ // разрешено вводить только числа и знак точка
    /^[a-z]$/i // разрешено вводить только латиницу, любого регистра
    // и т.д.
    
data-let-template
  • Более сложный атрибут, тут нужно указать шаблон вводимых данных регулярными выражениями. И к сожалению тут нужно учитывать некие правила. Правила заключаются в том что шаблон должен иметь структуру псевдо-проверки. Например мы хотим разрешить вводить номер телефона, в формате 123-45-67. Для этого придется написать не просто обычную регулярку вида:
    /^\d{3}-\d{2}-\d{2}$/
    
    а немного иную, так как проверка будет происходить постепенно а не полным фрагментом текста, придется это учесть и писать регулярное выражение вида:
    /^(|\d{1,3}|\d{3}-\d{0,2}|\d{3}-\d{2}-\d{0,2})$/
    

    Тот кто понимает регулярные выражения, думаю поймут что было сделано в этом регулярном выражении. Происходит тут следующее, регулярное выражение указывает что валидной является пустая строка и частичные строки вида: "1", "12", "123", "123-", "123-4", "123-45", "123-45-", "123-45-6", "123-45-67". Одним словом собираем строку по кусочкам.
data-let-length
  • Этот атрибут является альтернативой атрибута maxlength, его поведение идентично. И реализовано оно лишь для браузера IE и Opera, в которых атрибут maxlength не реагирует на элемент TEXTAREA.
Это три встроенных атрибута которые библиотека обрабатывает по умолчанию. Но есть возможность добавить собственные атрибуты для обработки. С помощью которых, вы легко сможете расширить функционал библиотеки. Делается это очень просто. При загрузке библиотеки, в глобальном пространстве появляется объект с именем letJS. Это не конструктор а обычный объект, имеющий метод setHandler в качестве первого параметра имя атрибута или массив имен атрибутов и в качестве второго параметра функция обработчик.
Вот небольшой пример:
letJS.setHandler('data-let-phone', function(event, unchanged) {
    if (!this.value) {
        this.value = event.rule;
    }
    if (unchanged) {
        if (event.type === 'blur') {
            if (this.value === event.rule) {
               this.value = '';
            }
            return;
        } else {
            this.focus();
        }
    } else if (event.insertValue) {
        var parts = event.insertValue.split('');
        for(var i = 0; i < parts.length; i++) {
            this.value = this.value.replace(/^([^_]+)_/, '$1' + parts[i]);
        }
    } else if (event.cropValue) {
        this.value = this.value.replace(/(\+7.*)\d([^\d]*)$/, '$1_$2');
    }
    var pos = this.value.indexOf('_');
    event.selection(pos > 0 ? pos : this.value.length);
    return false;
});
Тут я написал небольшой плагинчик, реализующий проверку ввода телефонного номера, в тег мы помещаем атрибут со значением вида (+7 (___) ___-__-__):
<input type="text" data-let-input="/^[0-9]+$/" data-let-phone="+7 (___) ___-__-__" placeholder="Ваш номер телефона" />


Все очень просто. Если нужно убрать обработчик, достаточно передать null вместо функции, пример:
letJS.setHandler('data-let-phone', null);


А теперь расскажу что получает функция обработчик и как/для чего это нужно использовать.

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

Первый параметр имеет объект со свойствами:
originalEvent
  • Объект Event, оригинальный объект пойманного события
type
  • Тип пойманного события
attr
  • Какой атрибут сейчас получил обработку, нужно если вы один обработчик вешаете на несколько атрибутов
rule
  • Тут находит значение атрибута attr
target
  • Элемент на котором поймали событие
selection
  • Это функция позволяющая указать куда установить каретку курсора, имеет два параметра, первый start(стратовая позиция), второй end(конечная позиция).
value
  • Текущее значение в элементе над которым манипулируем.
insertValue
  • Значение которое хотят вставить в наше поле ввода
cropValue
  • Значение которое хотят вырезать из нашего поля ввода
expectedValue
  • Ожидаемое значение, то есть то, которое получится в результате после манипуляций.
regExp
  • Тут хранится объект RexExp в случае если в атрибуте было указано значение в виде регулярного выражения, в противном случае null
insertStart
  • Стартовая позиция каретки, указывающей на то, от начала какого символа будет вставлено новое значение.
insertEnd
  • Конечная позиция каретки, указывающей на то, до начала какого символа будет вставлено новое значение.
cropStart
  • Стартовая позиция каретки, указывающей на то, от начала какого символа будет вырезано значение.
cropEnd
  • Конечная позиция каретки, указывающей на то, до начала какого символа будет вырезано значение.
Второй параметр это просто булевое значение, которое имеет true в том случае если в поле ввода ничего не меняли, а просто сместили каретку на другую позицию.

--------------------------------------------------------------------

Пока на этом все. Скачать как обычно все можете у меня на гите: https://github.com/devote/letJS

Вопросы, пожелания пишем! Всем спасибо!

devote 09.04.2013 12:32

reserved

nerv_ 09.04.2013 19:36

Цитата:

Сообщение от devote
Я уже упоминал о ней в некоторых топиках этого форума

видели :)

Любопытства ради: зачем в коде работа с выделением? https://github.com/devote/letJS/blob/master/let.js#L23

devote 09.04.2013 22:21

Цитата:

Сообщение от nerv_
Любопытства ради: зачем в коде работа с выделением?

по большей части оно используется для того что бы получить текущею позицию каретки. А точнее только для этого и используется. Хотя изначально планировал отлавливать работу drag'n'drop, там нужно было как восстановление позиции каретки, так и восстановление выделения. Ну и конечно же получение текущих координат.

Но увы drag'n'drop идеально реализован лишь в двух браузерах, это Internet Explorer (дабы в нем он уж сто лет) и Opera... Остальные браузеры мне побороть пока не удалось, в них увы ни в какую не узнать того в какую часть текста хотят вставить фрагмент принесенный мышкой. То есть нужно получить координаты до того как его вставили (но этого не сделать в браузерах Chrome, FF, Safari). О Safari вообще другой разговор, в нем у меня событие drop не работает ни в какую.

Если есть идеи или желание допилить drag'n'drop буду рад любым идеям.

nerv_ 10.04.2013 12:24

понятно, спасибо! :)

Цитата:

Сообщение от devote
О Safari вообще другой разговор, в нем у меня событие drop не работает ни в какую.

идей нет :no:

devote 21.03.2014 14:13

Внес небольшие изменения в библиотеку. Читайте выше


Часовой пояс GMT +3, время: 01:18.