2015-03-19 1 views
25

(я не могу найти его, но опять же я не знаю, как искать.)Использование HTML5 (DataList) автозаполнения с «содержит» подход, а не только «начинается с»

I хотите использовать <input list=xxx> и <datalist id=xxx>, чтобы получить автозаполнение, но я хочу, чтобы браузер соответствовал всем параметрам с помощью подхода «содержит», а не «начинается с», что кажется стандартным. Есть ли способ?

Если не просто, есть ли способ показать сильные предложения, которые я хочу показать, а не те, которые совпадают с браузером? Скажем, я набираю «foo», и я хочу показать опции «bar» и «baz». Могу ли я принуждать их к пользователю? Если я просто заполню datalist этими (с JS), браузер все равно выполнит проверку «начинается с» и отфильтрует их.

Я хочу, чтобы конечный контроль над тем, как показывают параметры набора данных. НЕ над своим интерфейсом, гибкостью, доступностью и т. Д., Поэтому я не хочу полностью переделывать его. Даже не предлагайте плагин jQuery.

Если я могу проверить элемент формы элемента управления, почему бы не автозаполнение, не так ли?

Редактировать: Теперь я вижу, что Firefox действительно использует подход «содержит» ... Это даже не стандарт? Любой способ заставить это? Могу ли я изменить способ Firefox?

редактировать: Я сделал это, чтобы показать, что я хотел: http://jsfiddle.net/rudiedirkx/r3jbfpxw/

+2

Нет помощи по этому вопросу? Трудно поверить ... это было первое, о чем я думал, когда мне нужно было использовать datalist. –

+0

проблема в том, что datalist не редактируется, по крайней мере, в ie11. ther я получаю эту ошибку: '0x800a13b5 - ошибка времени выполнения JavaScript: присваивание свойствам только для чтения запрещено в строгом режиме. –

+0

@NinaScholz Когда вы получите эту ошибку? Назначение чего к чему? Можете ли вы сделать скрипку? – Rudie

ответ

11

'contains' approach

Возможно, это то, что вы ищете (часть 1 вашего вопроса).

Идет с ограничением «начинается с» и изменяется при выборе.

'use strict'; 
 
function updateList(that) { 
 
    if (!that) { 
 
     return; 
 
    } 
 
    var lastValue = that.lastValue, 
 
     value = that.value, 
 
     array = [], 
 
     pos = value.indexOf('|'), 
 
     start = that.selectionStart, 
 
     end = that.selectionEnd, 
 
     options; 
 

 
    if (that.options) { 
 
     options = that.options; 
 
    } else { 
 
     options = Object.keys(that.list.options).map(function (option) { 
 
      return that.list.options[option].value; 
 
     }); 
 
     that.options = options; 
 
    } 
 

 
    if (lastValue !== value) { 
 
     that.list.innerHTML = options.filter(function (a) { 
 
      return ~a.toLowerCase().indexOf(value.toLowerCase()); 
 
     }).map(function (a) { 
 
      return '<option value="' + value + '|' + a + '">' + a + '</option>'; 
 
     }).join(); 
 
     updateInput(that); 
 
     that.lastValue = value; 
 
    } 
 
} 
 

 
function updateInput(that) { 
 
    if (!that) { 
 
     return; 
 
    } 
 
    var value = that.value, 
 
     pos = value.indexOf('|'), 
 
     start = that.selectionStart, 
 
     end = that.selectionEnd; 
 

 
    if (~pos) { 
 
     value = value.slice(pos + 1); 
 
    } 
 
    that.value = value; 
 
    that.setSelectionRange(start, end); 
 
} 
 

 
document.getElementsByTagName('input').browser.addEventListener('keyup', function (e) { 
 
    updateList(this); 
 
}); 
 
document.getElementsByTagName('input').browser.addEventListener('input', function (e) { 
 
    updateInput(this); 
 
});
<input list="browsers" name="browser" id="browser" onkeyup="updateList();" oninput="updateInput();"> 
 
<datalist id="browsers"> 
 
    <option value="Internet Explorer"> 
 
    <option value="Firefox"> 
 
    <option value="Chrome"> 
 
    <option value="Opera"> 
 
    <option value="Safari"> 
 
</datalist>

Редактировать

Другой подход отображения контента поиска, чтобы дать понять, что происходит. Это работает и в Chrome. Вдохновленный Show datalist labels but submit the actual value

'use strict'; 
 
var datalist = { 
 
     r: ['ralph', 'ronny', 'rudie'], 
 
     ru: ['rudie', 'rutte', 'rudiedirkx'], 
 
     rud: ['rudie', 'rudiedirkx'], 
 
     rudi: ['rudie'], 
 
     rudo: ['rudolf'], 
 
     foo: [ 
 
      { value: 42, text: 'The answer' }, 
 
      { value: 1337, text: 'Elite' }, 
 
      { value: 69, text: 'Dirty' }, 
 
      { value: 3.14, text: 'Pi' } 
 
     ] 
 
    }, 
 
    SEPARATOR = ' > '; 
 

 
function updateList(that) { 
 
    var lastValue = that.lastValue, 
 
     value = that.value, 
 
     array, 
 
     key, 
 
     pos = value.indexOf('|'), 
 
     start = that.selectionStart, 
 
     end = that.selectionEnd; 
 

 
    if (lastValue !== value) { 
 
     if (value !== '') { 
 
      if (value in datalist) { 
 
       key = value; 
 
      } else { 
 
       Object.keys(datalist).some(function (a) { 
 
        return ~a.toLowerCase().indexOf(value.toLowerCase()) && (key = a); 
 
       }); 
 
      } 
 
     } 
 
     that.list.innerHTML = key ? datalist[key].map(function (a) { 
 
      return '<option data-value="' + (a.value || a) + '">' + value + (value === key ? '' : SEPARATOR + key) + SEPARATOR + (a.text || a) + '</option>'; 
 
     }).join() : ''; 
 
     updateInput(that); 
 
     that.lastValue = value; 
 
    } 
 
} 
 

 
function updateInput(that) { 
 
    var value = that.value, 
 
     pos = value.lastIndexOf(SEPARATOR), 
 
     start = that.selectionStart, 
 
     end = that.selectionEnd; 
 

 
    if (~pos) { 
 
     value = value.slice(pos + SEPARATOR.length); 
 
    } 
 
    Object.keys(that.list.options).some(function (option) { 
 
     var o = that.list.options[option], 
 
      p = o.text.lastIndexOf(SEPARATOR); 
 
     if (o.text.slice(p + SEPARATOR.length) === value) { 
 
      value = o.getAttribute('data-value'); 
 
      return true; 
 
     } 
 
    }); 
 
    that.value = value; 
 
    that.setSelectionRange(start, end); 
 
} 
 

 
document.getElementsByTagName('input').xx.addEventListener('keyup', function (e) { 
 
    updateList(this); 
 
}); 
 
document.getElementsByTagName('input').xx.addEventListener('input', function (e) { 
 
    updateInput(this); 
 
});
<input list="xxx" name="xx" id="xx"> 
 
<datalist id="xxx" type="text"></datalist>

+0

Это умно! И это работает, но это выглядит так: http://screencast.com/t/igeQtYJ2 Это не очень, особенно с поиском типа «ameri». Это огромный недостаток функции автозаполнения IMO. Мы тратим время на лучшие 3D-анимации, но не улучшаем такие функции, как this = ( – Rudie

+0

, какой браузер вы используете? –

+0

Chrome на Windows. То же самое на Канарских островах. Firefox выглядит лучше, но Firefox уже использует подход «содержит». – Rudie

1

это fiddle here потрескалась, что вы просите Но я не знаю, как заставить его работать без этой зависимости, как пользовательский интерфейс выглядит немного странно, и из места, когда используется вместе с Bootstrap.

elem.autocomplete({ 
    source: list.children().map(function() { 
     return $(this).text(); 
    }).get() 
+2

В нем используется 'autocomplete' jQuery UI. ve автозаполнение вообще. Я надеялся, что автозаполнение 2016 года будет лучше = ( – Rudie

+0

Это делает забавные вещи для меня, когда используется в Bootstrap 3 страница –

1

все же эта тема опубликована около 2 лет назад.но если вы читаете эту тему, вы, возможно, необходимо проверить новую версию своего браузера:

Текущая спецификация: https://html.spec.whatwg.org/multipage/forms.html#the-list-attribute

User agents are encouraged to filter the suggestions represented by the suggestions source element when the number of suggestions is large, including only the most relevant ones (e.g. based on the user's input so far). No precise threshold is defined, but capping the list at four to seven values is reasonable. If filtering based on the user's input, user agents should use substring matching against both the suggestions' label and value.

И когда этот пост написан, поведение Firefox (51) и хром (56) уже были изменены в соответствии со спецификацией.

что означает, что операционная система должна работать только сейчас.

+0

Да, это так, но мне все равно понравилось, если бы у меня был некоторый контроль над этим. Мой следующий автозаполнение может должны быть «начинаться с», но нет возможности переопределить функциональность автозаполнения. Какой позор. – Rudie

+0

Этот ответ слишком короткий ... Пожалуйста, отразите также раздел об автозаполнении: https://www.w3.org/TR /html/sec-forms.html#autofill (особенно то, что мантия носит атрибут * Если атрибут 'autocomplete' опущен *, но также и разница между" ** ожидание ** мантия "и" ** якорь ** мантия " ") - и не пропустите это: https://www.w3.org/TR/html/sec-forms.html#ref-for-autofill-expectation-mantle-4 – yckart

+0

@yckart' autocomplete' - это просто другая история. Не связанная с этим вопросом ИМО. Вы можете отправить другой ответ или, возможно, еще один вопрос, если вы как. – tsh