form の input@list (datalist) を利用して、マウスのホイールと連動させてみる

input@list は、文字列ではなく、datalist 要素を返す
iPad からならどうしよう?
そもそも datalist の option要素の selected属性は、スクリプト以外で変更できないのだから
属性値の取得に、hasAttribute を使うまででもないか。
selected属性があるものを querySelector で見つけた方が楽だったり。


fedora17 Firefox 14.0.1 input@type で date が text で取得される
about:config html5.enable: true の設定項目そのものが無い。

<!DOCTYPE html>
<meta charset="UTF-8">
<title>DataList を補間する</title>
<style>
input[type="text"]:focus,
input[type="date"]:focus {
  background : #fee;
  border : 2px #f00 inset;
  border-radius : 4px;
 }
</style>

<form>
  <p>
    場所:
    <input type="text" name="@kaijou" list="kaijou">
    <datalist id="kaijou">
      <option>自宅
      <option>公民館
      <option>集会所
      <option>地区センター
    </datalist>
    *input 要素にフォーカスをあて、<em>マウスのホイールを動かします</em>
  </p>
</form>

<script>


(function () {

  var selector = new Function;
  var memory = null;
  var texts = [];
  var len;


  function wheelHandler (event) {
    if (selector.disabled) return;
      
    var detail = event.detail;
    var element = event.target;
    var doc = element.ownerDocument;
    var active = doc.activeElement;
    var list, idx;
      
    if (active !== element) {
      memory = null;
      return;
    }
    if (! (list = active.list)) { // list が有るか?
      return;
    }
    if (memory !== element) {
      memory = element;
      texts = Array.prototype.map.call (list.options, getText); // option.text を集める
      len = texts.length - 1;
    }
    idx = texts.indexOf (element.value) + ((detail < 0) ? -1: 1);

    element.value = texts[ range (0, idx, len) ] || '';
    event.preventDefault ();
  }


  function range (a, b, c) {
    return Math.min (Math.max (a, b), c);
  }


  function getText (e) {
    return e.value || e.text || '';
  }
  

  function selected (e) {
//  var status = e.attributes.getNamedItem('selected');
    var status = e.hasAttribute ('selected');

    if (status)
      this.value = getText (e);
    return status;  
  }
  

  function setDfaultSelected (e) {
    e.value = e.defaultValue;
    if ('' == e.value)
      Array.prototype.some.call (e.list.options, selected, e);
  }


  function resetValue () {
    Array.prototype.forEach.call (
      document.querySelectorAll ('input[list]'), setDfaultSelected);
  }
  

  function initialize () {
    resetValue ();
    window.addEventListener ('DOMMouseScroll', wheelHandler, false);
  }

//__________________________________________________
  
  selector.initialize = initialize;
  selector.resetValue = resetValue;
  selector.disabled   = false;

  this.ComplementByMouseWheel = selector;

}) ();

ComplementByMouseWheel.initialize ();

</script>