Чем заменить select html

Замена стандартного select с использованием Mootools

Иногда бывает нужно заменить стандартный HTML элемент select своим.
Обычно это необходимо, если фантазия дизайнера разыгралась и он нарисовал «кастомизированный» select и настаивает, чтобы было реализовано как он того захотел. Ну что ж, надо — сделаем.

Небольшая предыстория.
  • На него можно навести фокус
  • Можно выбирать, не открывая select, а используя клавиши-стрелки
  • Можно закрыть открытый select, нажав esc
  • Можно выбрать опцию в открытом селекте, нажав enter
  • Можно убрать фокус с select’a, нажав tab
  • Если в select’e много опций, то появляется прокрутка
  • У select’a есть событие onchange (есть и другие, но это наиболее важное)
  • В стандартном селекте можно набирать первую букву и будет переходить фокус сразу на элемент

Ближе к делу

Я не буду здесь приводить код того, что получилось — это ни к чему. Лучше сами скачайте и посмотрите, либо загляните в демо. Но я расскажу о том, что получилось.

Что получилось

  • Стандартное поведение как у «нативного» select
  • Заменяет указанный select собой
  • У него есть аж 4 события: onChange, onSelect, onShow, onHide
  • Поддерживает темы
  • Имеет понятный CSS
  • Имеет простую DOM модель
  • Прост в использовании
  • Имеет метод rebuild(), при помощи которого можно перестроить «кастомный» селектбокс, если произошли изменения в нативном select’е
  • JS код весит около 4-х килобайт в сжатом виде и 7,5 в несжатом

Какие на данный момент есть проблемы

  1. Нельзя изменить вид полосы прокрутки которая появляется в селектбоксе при большом количестве опций
  2. Пока что селектбокс может выпадать только вниз, а должен выпадать и вверх, если внизу мало места
  3. Отсутствует режим multiple
  4. Таймаут при покрутке, чтобы опция при наведении мыши при прокрутке выделялась не сразу (у нативного select’a именно так)
  5. Не меняет внешний вид при нажатии
  6. Если есть скролл, то он должен автоматически прокручиваться при выборе элементов.
  7. Если мышкой навсти на пункт меню, затем убрать мышь, то при нажатии Enter должен выбраться этот элемент

Тестировалось только в IE 7, Firefox 3.0.1, Google Chrome (гляньте кто-нибудь, в Опере и IE6 как?)

Если что-то упустил из виду — сообщайте. И, конечно, сообщайте о найденных багах, буду исправлять.

Источник

Css-only Alternative to the Select Element

PEPSized

In this tutorial, I will present you my alternative solution to the select form tag. It’s css-only and it looks simple but really nice. We will use a list of radio elements, styled as a drop-down list, that will look and behave similarly to the select element.
Of course you have to provide some fallback for mobile devices (and IE8 if you wish). I discuss that briefly in the final part of this tutorial.
Check the demo and choose your favorite beer.

Step 1 – HTML

Here is the html we use within a form

Css-only select drop-down list

To make things simple I tried to “sketch” my idea. I hope it is clear enough.

Читайте также:  METANIT.COM

Step 3 – CSS

Let’s add some css that reflect the idea presented in the scheme above. For the brevity of this tutorial I omit some parts of the css (e.g. triangle arrows) that only add some visual flavor – you’ll find the complete version in the attached files.
Note that the vendor prefixes are omitted for the same reason.
For the outer containter (“.radio-container”) we’ll have

radio-container < position: relative; height: 4em; /* 3em (being the max-height of the inner container) + 1em ("margin") */ >.radio-container:hover
.radio-options < position: absolute; max-height: 3em; width: 100%; overflow: hidden; transition: 0.7s; >.radio-options:hover
.radio-options .toggle < position: relative; cursor: pointer; padding: 0.75em; background: darkgreen; border-radius: 10px; z-index: 1; >/* li are stacked at the same position as .toggle, only .toggle is visible */ .radio-options li < position: absolute; top: 0; left: 0; width: 100%; height: 100%; >.radio-options label

We hide the inputs, we could just use display : none, but that would not work in browsers (some mobile ones) where clicking the label does not focus the associated input.

Step 4 – What happens on hover – CSS continued

Now let’s look closer at what happens on hover, already : .radio-container gets a high z-index and .radio-options increases its max-height, we’ll add

/* li elements have a normal flow within the .radio-options container */ .radio-options:hover li < position: relative; >.radio-options:hover label

Step 5 – input:checked

To style the checked option we will use the general sibling selector. It uses a tilde character combinator (E ~ F) and matches elements that are siblings of a given element. The first element (E) has to occur before the second (F) one and they have to share the same parent (li items in our case).
If one of the radio is checked, we’ll see its label instead of the toggle :

.radio-options input:checked ~ label < position: absolute; top: 0; left: 0; right: 0; opacity: 1; /* is above the .toggle so is visible */ z-index: 2; /* has tha same styles as .toggle */ padding: 0.75em; background: darkgreen; border-radius: 10px; >

On hover it returns to the normal flow

.radio-options:hover input:checked ~ label

Step 6 – What about mobile devices

Since our element is activated on hover you’ll have to provide some fallback for touch devices. One solution is to leave the radio labels visible all the time not only on hover.
Here is my solution to keep the drop-down list, I detect the touch devices with a custom modernizr build and add the following script

$(document).ready(function() < if (Modernizr.touch) < $(".radio-options").bind("click", function(event) < if (!($(this).parent('.radio-container').hasClass("active"))) < $(this).parent('.radio-container').addClass("active"); event.stopPropagation(); >>); $(".toggle").bind("click", function()< $(this).parents('.radio-container').removeClass("active"); return false; >); > >);

In my css I modify every :hover definition like that

.no-touch .radio-container:hover, .active.radio-container < z-index: 9999; >.no-touch .radio-options:hover, .active .radio-options < max-height: 100em; >.no-touch .radio-options:hover li, .active .radio-options li < position: relative; >.no-touch .radio-options:hover label, .active .radio-options label < opacity: 1; transition: 0.5s; >. 

Step 7 – What about IE8

Again, it’s up to you, the fallback solutions are not the main part of this tutorial. Here is my approach:

I have to add to my css the .checked class declarations, e.g. (see the attached files for the complete version):

.radio-options .checked label < position: absolute; top: 0; left: 0; right: 0; padding: 0.75em; background: #1b9e4d; visibility: visible; z-index: 2; >. 

That’s all. I hope you’ll find this technique useful, let me know what you think. Thanks.

Читайте также:  Css span border top

Terms of use :

You may use the effects demonstrated in tutorials in your own work, both commercial or non-commercial without any attribution. You may not reproduce entire nor large parts of our tutorials. The outcome of our tutorials may not be re-saled nor redistributed.

Tags

About the author

PeHaa

I’m a front-end developer, WordPress developer and trainer. Otherwise coding, cooking and doing yoga. Polish, married to a french guy Joe Vains with whom we live in the very center of Paris.
Follow @PeHaa on twitter and on CodePen.

Discussion

Comments (16)

Great, would be nice to give a way to forward selection responses to the server or something so we can use it as a regular form element.

A native select element will work with a mouse as well as with only a keyboard but alas your alternative won’t (as noticed one of my colleague on Twitter) so it won’t behave similarly to the select element yet.
The relevant accessibility technique is “Ensuring keyboard control for all functionality” ( http://www.w3.org/TR/WCAG20-TECHS/G202.html ). Also another idea of improvement would be to tag the text that introduces the radio buttons as a group (div.toggle) instead with a legend element and enclose this legend and the group of input[type=”radio”]+ label in a fieldset.

Actually it works perfectly fine with a keyboard. Still, a) you don’t notice, when the element is focused and b) the option list doesn’t flip open. Maybe, these problems could be solved with an additional :focus selector for the radio buttons.

Источник

Как заменить тег select на другой?

F5z7z3BO.png

Вообщем есть такая форма

 

Как можно сделать чтобы это отображалась в виде кнопок, а не в виде выпадающего списка
т.е нажал на Услуги Youtube и значение value=»11″ передалось с данной функцией removeQuantity()

Простой 1 комментарий

webinar

coolswood

 

coolswood

coolswood

santavits, Не с этой функцией. Функция, что вы скинули, не принимает параметров. Значит существует другая функция, которая принимает value из option.

$('#category').on('change', function() < var selected = this.value;
$('#category').on('change', function() < var selected = this.value; dataString = 'action=get-services&category-id='+selected; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#service").html(''); $("#service").append(data); > else < $("#service").html(''); > > >); >); function getBalance() < dataString = 'action=get-user-balance'; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#user-balance").html(data); $("#current-balance").html(data); >> >); > function generateNewAPI() < dataString = 'action=generate-new-api'; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, beforeSend: function()< $("#user-api").val('Создание нового ключа API..'); >, success: function(data) < if(data) < $("#user-api").val(data); >> >); > function selectService(ServiceID) < dataString = 'action=select-service&service-id='+ServiceID; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < if(data == 'hashtag') < $("#additional").html('
Хэштег
'); > else if(data == 'comments') < $("#additional").html('
Комментарии
'); > else if(data == 'mentions') < $("#additional").html('
Имя пользователя
'); > else < $("#additional").html(''); $("#order_quantity").prop("readonly", false); >> else < $("#additional").html(''); $("#order_quantity").prop("readonly", false); >> >); var autoModeAllowedForServices = [3,4,5,6,7,8,11,12,14,25,30,31,32,33,36,40,41,43,44,48,49,52,64,66,92,94]; var iServiceId = parseInt(ServiceID); var $form = $('form#new-order'); if (autoModeAllowedForServices.indexOf(iServiceId) !== -1) < $form.find('.form-group[data-name=order-mode]').show(); >else < $form.find('.form-group[data-name=order-mode]').find('select[name=mode]').val('link').change(); $form.find('.form-group[data-name=order-mode]').hide(); >> function reloadService() < $("#service").html(''); //$("#category").append(''); $("#sel").remove(); $("#category").prepend(''); > function nullQuantity() < $("#quantity").val(0); >function orderModeUpdated(el, ServiceID) < var $form = $(el).parents('form'); if ($(el).val()==='auto')< $form.find('.form-group[data-name=link]').find('.form-tip').html('Ссылка на аккаунт'); $form.find('.form-group[data-name=link]').find('input[name=link]').attr('placeholder','Ссылка на аккаунт'); $form.find('.form-group[data-name=posts-count]').show(); $form.find('.form-group[data-name=quantity]').find('.form-tip').html('Количество накрутки на одну'); $form.find('.form-group[data-name=quantity]').find('input[name=quantity]').attr('placeholder','Сколько крутить на одну'); $form.find('.form-group[data-name=dispersion]').show(); $form.find('.form-group[data-name=posts-exists-count]').show(); >else < $form.find('.form-group[data-name=link]').find('.form-tip').html('Ссылка'); $form.find('.form-group[data-name=link]').find('input[name=link]').attr('placeholder','Ссылка'); $form.find('.form-group[data-name=posts-count]').hide(); $form.find('.form-group[data-name=quantity]').find('.form-tip').html('Количество'); $form.find('.form-group[data-name=quantity]').find('input[name=quantity]').attr('placeholder','Сколько крутить'); $form.find('.form-group[data-name=dispersion]').hide(); $form.find('.form-group[data-name=posts-exists-count]').hide(); >> function removeQuantity() < $("#min_quantity").html("0"); $("#max_quantity").html("0"); $("#service-description").html(""); $("#price").html("0"); $("#order_quantity").val(0); $("#order_link").val(""); $("#description").fadeOut(); >function updateMinQuantity(ServiceID) < dataString = 'action=get-min-quantity&service-id='+ServiceID; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#min_quantity").html(data); >> >); > function eAjax(el, action)< if ($(el).hasClass('disable')) return false; $(el).addClass('disable'); var params = JSON.parse($(el).attr('data-params') || '<>'); var data = $.extend(params, ); $.ajax( < type: "POST", url: "requests.php", data: data, cache: false, success: function(html)< $('#m_service').html(html); $(el).removeClass('disable'); >>); return false; > function updatePrice(ServiceID, Quantity, PostsCount) < var dataString = 'action=get-price&service-id='+ServiceID+'&quantity='+Quantity+'&postsCount='+PostsCount; if(Quantity >0) < $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#price").html(data); >> >); > else < $("#price").html(0); >> function updateMaxQuantity(ServiceID) < dataString = 'action=get-max-quantity&service-id='+ServiceID; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#max_quantity").html(data); >> >); > function updateLinkMaxQuantity(ServiceID, Link) < dataString = 'action=get-link-quantity&service-id='+ServiceID+'&link='+Link; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#max_quantity").html(data); >> >); > function updateDescription(ServiceID) < dataString = 'action=get-description&service-id='+ServiceID; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#description").fadeIn(); $("#service-description").html(data); >> >); > $("#show-order-example").click(function() < if($("#example-create-order").is(':visible')) < $("#show-order-example").html('Показать пример.'); $("#example-create-order").hide( "slow" ); >else < $("#show-order-example").html('Скрыть пример.'); $("#example-create-order").show( "slow" ); >>); $("#show-referral-url").click(function() < if($("#referral-url").is(':visible')) < $("#show-referral-url").html('Показать партнерскую ссылку.'); $("#referral-url").hide( "slow" ); >else < $("#show-referral-url").html('Скрыть партнерскую ссылку.'); $("#referral-url").show( "slow" ); >>);

coolswood

$('.select').on('click', function() < var selected = this.value; dataString = 'action=get-services&category-id='+selected; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < $("#service").html(''); $("#service").append(data); > else < $("#service").html(''); > > >); > );

сейчас button нужен перед самой формой вот код

   
Сервис
Ссылка
Количество

coolswood

santavits, для начала правильно перенесите html из моего примера. https://jsfiddle.net/a6twfeay/13/
это

 
 

Даниил Сугоняев, Теперь при клике на button вообще никаких действий не происходит, может из за того что не указана не где функункция removeQuantity?

coolswood

coolswood

success: function(data)< if(data) < $("#service").html(''); $("#service").append(data); > else < $("#service").html(''); > >
success: function(data) < if(data) < alert('Все работает!') >else < alert('Печалька) >>
$('.select').on('click', function() < var selected = this.value; dataString = 'action=get-services&category-id='+selected; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < alert('Все работает!') >else < alert('Печалька) >> >); >);
  
Сервис
Ссылка
Количество

coolswood

$('.select').on('click', function() < var selected = this.value; dataString = 'action=get-services&category-id='+selected; $.ajax(< type: "POST", url: "requests.php", data: dataString, cache: false, success: function(data)< if(data) < console.log('Успех') >else < console.log('Не оч') >> >); >);

и скиньте что показывает консоль после нажания кнопки, вызывается она F12
https://yadi.sk/i/mlOoB_jP3WXCVD

kSqeGjuR.png

Даниил Сугоняев,

а при нажатие на button в консоль вообще ничего не пишется

coolswood

santavits, это синтаксическая ошибка, написано что вы пропустили скобку на 264 линии в new-order.php. Сначала разберитесь с ошибками

KorniloFF

Трэш полный.
Нужно снять все обработчики с селекта и перевесить их на баттоны.
Далее проверить все обращения на предмет наличия select в них. Если код рабочий - всё должно работать.

Источник

Оцените статью