Создаем кнопочку отмены на текстовом поле

Создаем кнопочку отмены на текстовом поле

Сегодня я расскажу о создании jQuery-плагина, который из обыкновенного текстового инпута делает инпут как на картинке слева.

Начнем. Без лишних слов.

 

 

 

Примерчики

Текстовое поле с возможностью отмены вы можете увидеть на яндексе (если в качестве браузера используете Safari или Google Chrome)

Или на вебораме (они по-моему даже крестик используют одинаковый):

UPD. Как выяснилось, заслуги авторов вышеупомянутых сайтов в этом мало. Дело в том, что если у текстового указано type = 'search', то такой крестик автоматически будет появляться в браузерах Хром и Сафари. Спасибо анонимному читателю за информацию.

Еще такую функцию можно увидеть в Виндуз Виста:

 

Что и зачем?

Принцип работы крестика элементарен как кирпич. Крестик появляется, когда в текстовом поле есть какой-то текст. При нажатии на крестик, текст из поля стирается. Не надо долго зажимать Backspace или совершать другие телодвижения, вроде Ctrl+A, Del.

Особенно такая функция полезна при использовании мобильных девайсов вроде iPod Touch или iPhone. Более того, в i-девайсах такая функция является привычной: в адресной строке браузера там всегда появляется крестик и им постоянно и с удовольствием пользуешься.

За работу

В первый день я создал HTML:

<div class="inputWrapper">
<input id="searchInput" type="text" />
</div>

Во второй подключил jQuery. 

В третий нарисовал крестик: .

В четвертый создал макет для jQuery-плагина.

В пятый написал плагин. Комменты привожу в коде.

(function($) {
$.fn.AddXbutton = function(options) {
var defaults = {
img: 'x.gif'//расположение картинки крестика по-умолчанию (относительно страницы, на которой находится инпут)
};
var opts = $.extend(defaults, options);
$(this)
.after($('<input type="image" id="xButton" src="' + opts['img'] + '" />') //после текстового инпута вставляем image-input
.css({ 'display': 'none', 'cursor': 'pointer', 'marginLeft': '-15px' })// делаем его стильным
.click(function() { //вешаем обработчик на клик
$('#searchInput').val('').focus();
$('#xButton').hide();
}))
.keyup(function() { //на кейап мы проверяем, показывать нам крестик или нет
if ($(this).val().length > 0) {
$('#xButton').show(); //если текст какой-нибудь есть, но показываем
} else {
$('#xButton').hide();
}
});
if ($(this).val() != '') $('#xButton').show(); //если при загрузке страницы в текстовом поле что-то есть, крестик надо сразу показать (например, при обновлении страницы)
};
})(jQuery);

Все. Теперь вызываем функцию AddXbutton при загрузке страницы:

$(document).ready(function() {
$('#searchInput').AddXbutton({ img: 'images/x.gif' });
$('#searchInput').focus();
});

Спасибо за внимание!

Смотрим демо Загружаем архив с примером Загружаем плагин

UPD. Спасибо читателям за дельные замечания. Благодаря вам наш несложный плагин эволюционировал и стал более толковым.

Новый код плагина:

(function($) {
$.fn.AddXbutton = function(options) {
var defaults = {
img: 'x.gif'
};
var opts = $.extend(defaults, options);
$obj = $(this);
$(this).each(
function(i) {
$(this).after(
$('<input type="image" id="xButton' + i + '" src="' + opts['img'] + '" />')
.css({ 'display': 'none', 'cursor': 'pointer', 'marginLeft': '-15px' })
.click(function() {
$obj.val('').focus();
$("#xButton" + i).hide();
}))
.keyup(function() {
if ($(this).val().length > 0) {
$("#xButton" + i).show();
} else {
$("#xButton" + i).hide();
}
if ($(this).val() != '') $("#xButton" + i).show();
});
});
};
})(jQuery);

Демо [Updated] Плагин [Updated]


Расскажите друзьям

Оцените статью:
  • 1
  • 2
  • 3
  • 4
  • 5

Комментарии — 51

Zona
Все гениальное просто! спасибо за статейку. Такие юзабильные штуки очень радуют как и при реализации, так и заказчиков :)
#
Zona
RipWay
Да, прикольная штука.
Сашко
Интересная плюшка, мелочь, а приятно.
Нада будет взять на заметку.
Glader
Гораздо быстрее при наборе нажать Ctrl+A, Del, чем тянуться за мышью и попадать в этот крестик.
#
Glader
Neutron
Glader, ну это видимо дело привычки... бывает удобно развалившись в кресле и неспешно сёрфя мышкой, лень поднимать руку на клавиатуру и что-то печатать... а при комбинации ctrl-a и del - ещё и две руки просятся - ctrl-a нга левую и del на правую...
так что думаю полезна штука... тем более никто не отменял комбинацию клавишь если вам удобно пользоваться клавой, в данном случае ещё и "мышатникам" добавили удобство
C0vax
Из таких мелочей и складывается удачный дизайн, юзабилити - называйте как хотите.
Вообще конечно в десктопных прогах много таких мелочей, которые сделают сайты удобнее и красивее... дело в том что не все это замечают и применяют
Анатолий Rr Буров
Из-за использования id для инеднификации элементов нельзя иметь на странице несколько таких полей. Неправильный плагин получается.
CriggerMarg
Можно id и генерировать, вы не находите?
#
CriggerMarg
Mohinder
Только вот если с помощью контекстного меню и мыши вставить текст крестик не покажется, может лучше вешать на change?
#
Mohinder
Mohinder
Ах нет, глупость сказал =)
#
Mohinder
v1ex
Благодарю, давно хотел сделать подобную вещь, но руки у самого никак не доходили.
Glader
А почему "отписаться от комментариев" не работает? Почините пожалуйста!
#
Glader
Женя
Спасибо, Анатолий, за дельное замечание. Плагин поправил, пост обновил.

Извините, Glader. В ближайшее время отписку поправим.
Дмитрий
Оперативно работает :-)
Только хотел намекнуть на изменения в этой строчке кода


 $('#searchInput2').val('').focus(); 


А Ву уже все исправил :-)

Молодец!!!
Александр
Классно придумали, радует глаз. Вот только если текст вставлять к примеру ctrl v или другим способом - то крест не срабатывает.
Женя
Если вставлять Ctrl+V, то событие keyup срабатывает. Но вставка значений с помощью мыши действительно не работает.
И я, честно говоря, не знаю как отловить эту вставку с помощью мыши.
Smozjo
и если стоит плагин например:
jquery.form.js

то при проверки формы и выдаче ошибки плагином, ваш крестик съезжает : ((
#
Smozjo
Женя
Это связано с относительным позиционированием крестика. Здесь лежит версия плагина, которая вам подойдет.
В этой версии присваивается абсолютное позиционирование к крестику и добавляется верхний маргин:
...
.css({ 'display': 'none', 'cursor': 'pointer', 'marginLeft': '-15px', 'position':'absolute', 'marginTop':'5px' })
...
Инна
Функцыя очень полезная! ясебе поставил и очень довольный!
Smozjo
Срасибо, Евгений, но к сожалению та же ошибка, наверное потомуч то крестик создается сразу, а ошибочный label создается после ухода с поля и крестик сдвигается потому что оказывается после ошибочного label
#
Smozjo
Евгений
В таком случае могу посоветовать в плагине вместо $(this).after написать $(this).before, то есть вставить инпут с крестиком перед полем. А стили попробуйте уже сами описать.
Smozjo
Спасибо за наводку, сделал путем вычисления ширины и вставки крестика методом before с margin равному ширине.
#
Smozjo
Мавр
побольше б таких кнопочек! Уж больно понравилось!
Илья
Классная вешица.. Только я не пойму почму у себя ее не поставили?))
#
Илья
Anonimous
дык ставим и радуемся :) (Safari или Google Chrome)
#
Anonimous
Anonimous
черт html скушался... ставить надо y inрut type='search'
#
Anonimous
Zhenya
Подскажите, как сделать, чтобы сама кнопка (input type submit) была задействована при нажатии Enter. Сейчас у меня получается так, что после ввдения текста, человек жмет Enter и нажимается крестик, который все очищает :)

Но если человек нажмет Tab, Enter либо мышью на кнопку, то всё ок.
#
Zhenya
Женя
Anonim, я не понял что вы написали про инпут type=search.
Такого тайпа у инпута быть не может:
http://www.w3.org/TR/html401/interact/forms.html#input-control-types

Zhenya, форму можно понять. Как выяснилось, input type='image' является сабмит батоном, а не просто кнопкой. Поэтому изменив следующие строчки в плагине:
$('<input type="button" id="xButton' + i + '" src="' + opts['img'] + '" />')
    .css({ 'background': 'transparent url(' + opts['img'] + ') left top no-repeat','width':'10px','height':'10px', 'border': 'none', 'display': 'none', 'cursor': 'pointer', 'marginLeft': '-15px', 'position': 'absolute', 'marginTop': '5px' })

Мы будем вставлять input type = button. А форма уже будет сабмититься, используя Ваш сабмит батон.

Обновленный плагин можно найти здесь
Anonimous
его может быть и нету, но хром его прекрасно читает, прежде чем писать поробовали бы...
#
Anonimous
Anonimous
у яндекса какраз стоит type='search'
#
Anonimous
Женя
input type='search' появился только в html 5.
И не имеет никакого смысла ставить здесь type=search. Такой инпут ничем не отличается от input type='text'. Разница исключительно семантическая.
Anonimous
разница какраз в том, что можно не писать никак плагинов, и сделать пользователям хрома и сафари приятное, просто поставив type='search'
#
Anonimous
Женя
Действительно, Хром и Сафари ставят такие крестики в input type='search' сами. Это классно. Спасибо.
Но для всех прочих браузеров нужен плагин.
LeoK
Ребята, чтото я не понимаю - в ff 3.5 что отсутствует сие творение, как крестик
#
LeoK
LeoK
Все до боли просто - надо было не забыть набрать текст :)
#
LeoK
Vanekru
Прикольно. Спорно конечно необходимость, а так очень понравилось.
Murz
А есть ли плагин для Firefox со схожей функциональностью? Чтобы он на все сайты сам автоматом эти крестики добавлял... уж очень я привык к ним в KDE и постоянно мучаюсь когда их нету...
#
Murz
Evgenij
Murz, скиньте пожалуйста скриншоты таких крестиков в KDE. Буду премного благодарен.
Murz
Evgenij, можно на стандартных скриншотах увидеть, вот например:
http://upload.wikimedia.org/wikipedia/commons/thumb/5/54/KDE_4.png/800px-KDE_4.png
Первое поле "To" - справа у конца поля черного цвета.
И так появляется на всех текстовых полях, которые рисуются через кеды, в гномовских (и в том числе в firefox) не рисуется ;(
#
Murz
george
8 июля в 18:55 Анатолий Rr Буров
Из-за использования id для инеднификации элементов нельзя иметь на странице несколько таких полей. Неправильный плагин получается.

Как такое можно исправить?? у меня никак не получается. Помогите пожалуйста
#
george
george
немного не так сформулировал вопрос

в этом скрипте есть возможность использовать несколько Id на странице в таком виде:
$("#id1, #id2, id3, ...").AddXbutton({img:'x.gif'});
а мне нужно что можно было так:
$("#id1").AddXbutton({img:'x.gif'});
$("#id2").AddXbutton({img:'y.gif'});
$("#id3").AddXbutton({img:'z.gif'});
что бы для каждого можно было использавать свои настройки.

Помогите пожалуйста...
#
george
aeneus
george, на следующей странице туториала:

http://wintoni.us/post/123029056/jquery-plugin-patterns

посмотрите на указанной странице то, что найдётся над строкой "data store to associate options with each individual element".
Это решение для сохранения опций к каждому элементу.
#
aeneus
Дмитрий
Приветствую! Плагин нужный. У меня возник запрос функционала: дело в том, что у меня есть динамически создаваемые поля, к которым хотелось бы привязывать функцию очистки. Однако, насколько я посмотрел по коду, текущая организация не позволяет это сделать.
#
Дмитрий
Евгений
Дмитрий, это у вас не вопрос, а совершенно справедливое утверждение.

Да, возникнет проблема с идентификаторами крестика.

Надо поменять "#xButton" + i на что-то вроде "#xButton" + $obj.attr('id')
homm
Полный идиотизм. Зачем вы id генерируете, или (о ужас) храните? Вы же элемент уже создали, с ним и работайте.
#
homm
Дмитрий
Некоторый енчантсментс от меня:

$('<span id="xButton' + i + '" class="clear_all" /></span>')
.css({ 'display': 'none' })

.clear_all {
    background: url(images/clear_all.png) no-repeat top left;
    width: 10px;
    height: 10px;
    margin: 9px 0 0 -15px;
    float: left;
    text-indent: -9999px;
    cursor: pointer !important;
}

.clear_all:hover {background-position: 0 -10px;}


#
Дмитрий
Влад
Плагин не правильно себя ведет если он размещен на станице на которую пришли через GET, а именно он обнуляет значение указанное в параметре get так как ссылка крестика ведет на сам файл вызывающий скрипт не учитывая параметры GET. Если кто знает как исправить буду очень благодарен
#
Влад
HeadMad
Друзья! тут подумал что можно реализовать эту функцию попроще, я не кодер(вообще не кодер), но вот что у меня получилось:
<style type="text/css">
#pole {
	outline:0px;
	display: block;
	height: 22px;
	width: 278px;
	position: absolute;
	border: 1px solid #ccc;
	padding: 0 22px 0 0;
}
#reset {
	margin:2px 0 0 280px;
	border: none;
	position: absolute;
	height: 20px;
	width: 20px;
	background:url(reset.png) #999;
	display: none;
}
</style>
<span>
<form>
<input name="" type="text" id="pole" value="" size="20" onpropertychange="changeProp('reset','','display','block','INPUT')" oninput="changeProp('reset','','display','block','INPUT')"/>
<input name="" id="reset" value="" type="reset" onclick="changeProp('reset','','display','none','INPUT')"/>
</form>
</span>
<script type="text/javascript">
function changeProp(objId,x,theProp,theValue) { //v9.0
  var obj = null; with (document){ if (getElementById)
  obj = getElementById(objId); }
  if (obj){
    if (theValue == true || theValue == false)
      eval("obj.style."+theProp+"="+theValue);
    else eval("obj.style."+theProp+"='"+theValue+"'");
  }
}
</script>


Надеюсь, хоть кому-нибудь это поможет)))
#
HeadMad  
Кирилл
На мой взгляд так это совсем ненужная штука, больше кода хуже )
Димитрий
Подскажите почему когда я стираю текст перезагружається страница. Заранее спасибо.

<form id="form" action = "search.php" method = "post" >
    <div class="inputWrapper">
        <input id="searchInput" type="text" />
    </div>
</form>
#
Димитрий

Новый комментарий

как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть
как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть

metin2 pvp metin2 pvp serverler pvp serverler