Дизайн материала для веб - как сделать автозаполнение ввода - PullRequest
2 голосов
/ 29 апреля 2020

Я использую Google материал для веб-дизайна . И я хотел бы использовать их выбрать компонент в качестве компонента автозаполнения. То, к чему я стремлюсь, это автозаполнение , которое вы можете увидеть в реакции mui. Я удалил атрибуты ввода disabled и readonly, но я все еще не могу ничего написать в поле ввода.

<div class="mdc-select demo-width-class">
  <div class="mdc-select__anchor">
    <span class="mdc-select__ripple"></span>
    <input type="text" class="mdc-select__selected-text">
    <i class="mdc-select__dropdown-icon"></i>
    <span class="mdc-floating-label">Pick a Food Group</span>
    <span class="mdc-line-ripple"></span>
  </div>

  <div class="mdc-select__menu mdc-menu mdc-menu-surface mdc-menu-surface--fullwidth">
    <ul class="mdc-list">
      <li class="mdc-list-item mdc-list-item--selected" data-value="" aria-selected="true"></li>
      <li class="mdc-list-item" data-value="grains">
        <span class="mdc-list-item__text">
          Bread, Cereal, Rice, and Pasta
        </span>
      </li>
      <li class="mdc-list-item" data-value="vegetables">
        <span class="mdc-list-item__text">
          Vegetables
        </span>
      </li>
      <li class="mdc-list-item" data-value="fruit">
        <span class="mdc-list-item__text">
          Fruit
        </span>
      </li>
    </ul>
  </div>
</div>

Как включить поле ввода для записи в него, чтобы можно было адаптировать и сделать поле ввода автозаполнения?

Ответы [ 4 ]

0 голосов
/ 08 мая 2020

Это то, чего я смог достичь, надеюсь, это поможет в вашей реализации. Я не полностью реализовал фильтр logi c и все, но смог войти в него и одновременно отобразить выпадающий список.

const menuElement = document.querySelector(".mdc-menu");
// const menu = new mdc.menu.MDCMenu(menuElement);

const inputLabel = document.querySelector(".mdc-text-field");
const inputElem = inputLabel.querySelector("input");
const dropdownIcon = document.querySelector(".mdc-select__dropdown-icon");
let isMenuOpen = false;

inputLabel.addEventListener("click", () => {
  inputElem.focus();
  // menu.open = true;
  if (!isMenuOpen) {
    menuElement.classList.remove("list-menu-close");
    menuElement.classList.add("list-menu-open");
    dropdownIcon.classList.add("dropdown-icon-up");
  } else {
    menuElement.classList.remove("list-menu-open");
    menuElement.classList.add("list-menu-close");
    dropdownIcon.classList.remove("dropdown-icon-up");
  }
  isMenuOpen = !isMenuOpen;
});

inputElem.addEventListener("blur", () => {
  menuElement.classList.remove("list-menu-open");
  menuElement.classList.add("list-menu-close");
  dropdownIcon.classList.remove("dropdown-icon-up");
  isMenuOpen = false;
});

    <div class="dropdown-container">
      <label class="mdc-text-field mdc-text-field--filled">
        <span class="mdc-text-field__ripple"></span>
        <input
          class="mdc-text-field__input"
          type="text"
          aria-labelledby="my-label-id"
        />
        <i class="mdc-select__dropdown-icon"></i>
      </label>
      <div>
        <div class="mdc-menu mdc-menu-surface list-menu">
          <ul
            class="mdc-list"
            role="menu"
            aria-hidden="true"
            aria-orientation="vertical"
            tabindex="-1"
          >
            <li class="mdc-list-item" role="menuitem">
              <span class="mdc-list-item__text">A Menu Item</span>
            </li>
            <li class="mdc-list-item" role="menuitem">
              <span class="mdc-list-item__text">Another Menu Item</span>
            </li>
          </ul>
        </div>
      </div>
    </div>
.dropdown-container {
  position: relative;
}

.list-menu {
  position: absolute;
  top: 60px;
}

.list-menu-open {
  display: block;
  opacity: 1;
}

.list-menu-close {
  display: none;
  opacity: 0;
}

.dropdown-icon-up {
  transform: rotate(180deg) translateY(-5px);
}

0 голосов
/ 04 мая 2020

, так как вы упомянули, что хотели бы видеть ответ без использования реакции, таким образом, в простом javascript. Мне удалось сделать именно это. Я объединил css и разметку из ответа @Sifat Haque и полную рабочую логику автозаполнения c из w3schools . Хотя это может показаться простым, это было довольно сложно сделать эту работу.

const select = new mdc.select.MDCSelect(document.querySelector('.mdc-select'));

function autocomplete(inp, arr) {
   var currentFocus;
 
  inp.addEventListener("input", autocomp);
  inp.addEventListener("click", autocomp);

  inp.addEventListener("focus", autocomp);

  function autocomp(e) {
    var a, b, i, val = this.value;
    closeAllLists();
    currentFocus = -1;

    a = document.createElement("ul");
    a.setAttribute("id", this.id + "autocomplete-list");
    a.setAttribute("class", "autocomplete-items mdc-list");

    document.getElementById("autocomp").appendChild(a);

    for (i = 0; i < arr.length; i++) {
      if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase() || (val.trim()).length == 0) {
        b = document.createElement("li");
        b.setAttribute("class", "mdc-list-item")
        b.innerHTML = "<span class='mdc-list-item__text'>" + arr[i] + "</span>";
        b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";

        b.addEventListener("click", function(e) {
          inp.value = this.getElementsByTagName("input")[0].value;
          closeAllLists();
        });
        a.appendChild(b);
      }
    }
  }
  inp.addEventListener("keydown", function(e) {
    var x = document.getElementById(this.id + "autocomplete-list");
    if (x) x = x.getElementsByTagName("li");
    if (e.keyCode == 40) {
      currentFocus++;
      addActive(x);
    } else if (e.keyCode == 38) { //up
      currentFocus--;
      addActive(x);
    } else if (e.keyCode == 13) {
      e.preventDefault();
      if (currentFocus > -1) {
        if (x) x[currentFocus].click();
      }
    }
  });

  function addActive(x) {
    if (!x) return false;
    removeActive(x);
    if (currentFocus >= x.length) currentFocus = 0;
    if (currentFocus < 0) currentFocus = (x.length - 1);
    x[currentFocus].classList.add("autocomplete-active");
    x[currentFocus].classList.add("mdc-list-item--selected");
  }

  function removeActive(x) {
    for (var i = 0; i < x.length; i++) {
      x[i].classList.remove("autocomplete-active");
      x[i].classList.remove("mdc-list-item--selected");
    }
  }

  function closeAllLists(elmnt) {
    var x = document.getElementsByClassName("autocomplete-items");
    for (var i = 0; i < x.length; i++) {
      if (elmnt != x[i] && elmnt != inp) {
        x[i].parentNode.removeChild(x[i]);
      }
    }
  }

}

/*An array containing all the foods :*/
var foods = ["fruit", "vegetables", "grains", "fries"];

/*initiate the autocomplete function on the "myInput" element, and pass along the foods array as possible autocomplete values:*/
autocomplete(document.getElementById("name-input"), foods);

function makeActive(element) {
  document.getElementById("name-input").focus();
  element.classList.add("mdc-select--focused");
  element.classList.add("mdc-select--activated")
}
* {
  box-sizing: border-box;
}

.autocomplete {
  position: relative;
  display: inline-block;
}

input {
  border: 1px solid transparent;
  background-color: #f1f1f1;
  padding: 10px;
  font-size: 16px;
}

input[type=text] {
  background-color: transparent;
  width: 100%;
  margin-left: -200px;
  margin-top: 30px;
  z-index: -2;
}

input[type=text]:active {
  border: none;
}

.autocomplete-items {
  position: absolute;
  border: 1px solid #d4d4d4;
  border-bottom: none;
  border-top: none;
  z-index: 99;
  /*position the autocomplete items to be the same width as the container:*/
  top: 100%;
  left: 0;
  right: 0;
  max-height: 200px;
  /*overflow-y: scroll; */
}

.autocomplete-items li {
  padding: 10px;
  cursor: pointer;
  background-color: #fff;
  border-bottom: 1px solid #d4d4d4;
}

.mdc-select__menu {
  margin-top: -30px;
  z-index: 1;
  height: 150px;
  box-shadow: none;
  background-color: transparent;
  overflow-x: hidden !important;
}
<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!DOCTYPE html>
  <html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link href="https://unpkg.com/material-components-web@v4.0.0/dist/material-components-web.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">

    <script src="https://unpkg.com/material-components-web@v4.0.0/dist/material-components-web.min.js"></script>

  </head>

  <body>


    <h2>Autocomplete</h2>

    <p>Start typing:</p>

    <!--Make sure the form has the autocomplete function switched off:-->

    <form autocomplete="off" action="" method="post">

      <div class="mdc-select" onclick="makeActive(this)">
        <div class="mdc-select__anchor demo-width-class">
          <i class="mdc-select__dropdown-icon"></i>
          <div class="mdc-select__selected-text"></div>
          <span class="mdc-floating-label">Pick a Food Group</span>
          <div class="mdc-line-ripple"></div>
          <input type="text" id="name-input" name="selectione">


        </div>
        <div class="mdc-select__menu mdc-menu mdc-menu-surface">
          <div class="autocomplete" id='autocomp' style="width:200px;">
          </div>
        </div>
      </div>

      <input type="submit">
    </form>

Надеюсь, это поможет!

edit: добавлена ​​стандартная опция выбора

0 голосов
/ 05 мая 2020

Я создал демо, и оно в некоторой степени делает то, что вы хотите. У него есть две проблемы:

  1. Пользователь должен дважды щелкнуть (двойной щелчок) для ввода значений (я не могу заставить его работать одним щелчком мыши)
  2. Позиция label перекрывает выбранное значение (даже после задания другого класса или его динамического оформления)

Если у кого-нибудь есть идеи о том, как go решить эти проблемы, их идеи приветствуются.
@ Лефф, ты сам выглядишь как человек с опытом, ты можешь их решить? Если да, пожалуйста, сделайте это и, пожалуйста, просветите нас (меня).

Кроме того, Я использовал jquery в этом коде , если вы ищете всего за vanilla javascript вам, возможно, придется сделать это самостоятельно или найти человека, который может, поскольку я не являюсь экспертом в этой области, но это логичная часть. Похоже, ваша основная проблема имеет значение HTML, которое должно быть решено.

Ниже приведена демонстрация, посмотрите, поможет ли она вам.

// initialize
const select = new mdc.select.MDCSelect(document.querySelector('.mdc-select'));

// stop the original propagation so that input field remains editable
$('#food').on('click', (event) => {
  return false;
});

// Demo Data
const foodArr = ['Bread, Cereal, Rice, and Pasta', 'Vegetables', 'Fruit'];

// You'll have to use ajax here to get the data
$('#food').on('keyup', (event) => {

  //console.clear();
  let $this = $(event.currentTarget);
  let currValue = $this.val();

  let search = new RegExp(currValue, 'i'); // prepare a regex object // Your custom condition

  let matchArr = foodArr.filter(item => search.test(item)); //store the result in an array
  let $select = "";

  // check if array is empty
  if (matchArr.length > 0) {

    // map the elements of the array and create option html
    matchArr.forEach((item) => {

      $select += `<li class="mdc-list-item" data-value="${item}"> ${item}</li>`;

    })

  } else { // if array is empty, display no match

    $select += `<li class="mdc-list-item" id="no_match"> No match found!</li>`;

  }
  //console.log(matchArr);

  // if the data was selected before, unselect it
  $('.mdc-list-item--selected:first').attr({'data-value': ''});
  $('.mdc-list-item--selected:first').text('');
  $('.mdc-list-item--selected:not(:first)').removeClass('mdc-list-item--selected');

  // remove all previous option elements
  $('.mdc-list-item:not(.mdc-list-item--selected:first)').remove();

  // add new option elements
  $('.mdc-list-item--selected').after($select);

  // start the click function, so that dropdown doesn't close
  $this.click();
});

// When any option is selected, show it on input field
$(document).on('click', '.mdc-list-item:not(#no_match)', (event) => {
  
  let $this = $(event.currentTarget);
  $this.addClass('mdc-list-item--selected');
  
  $('.mdc-floating-label').addClass('mdc-floating-label--float-above');
  
  $('.mdc-select__anchor').addClass('demo-width-class mdc-ripple-upgraded')
  $('.mdc-line-ripple').addClass('mdc-line-ripple--active mdc-line-ripple--deactivating')
  $('.mdc-line-ripple').css({'transform-origin': '182px center'})
  
  $('#food').val($this.attr('data-value'));
  // return false;
  // event.stopImmediatePropagation()
});

// if clicked on no match, value of input field should be empty, alternatively you can also make option disabled
$(document).on('click', '#no_match', (event) => {
  
  $('#food').val('');
  
});
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>@sauhardnc</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link href="https://unpkg.com/material-components-web@v4.0.0/dist/material-components-web.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <script src="https://unpkg.com/material-components-web@v4.0.0/dist/material-components-web.min.js"></script>
</head>

<body>
  <div class="mdc-select">
    <div class="mdc-select__anchor demo-width-class" style="width: 100%">
      <i class="mdc-select__dropdown-icon"></i>
      <input type="text" class="mdc-select__selected-text" id="food"></input>
      <!-- Give a unique id -->
      <!--<div contenteditable="true" class="mdc-select__selected-text" id="fruit"></div>-->
      <span class="mdc-floating-label">Pick a Food Group</span>
      <div class="mdc-line-ripple"></div>
    </div>

    <div class="mdc-select__menu mdc-menu mdc-menu-surface demo-width-class" style="width: 100%">
      <ul class="mdc-list">
        <li class="mdc-list-item mdc-list-item--selected" data-value="" aria-selected="true"></li>
        <li class="mdc-list-item" data-value="Bread, Cereal, Rice, and Pasta">
          Bread, Cereal, Rice, and Pasta
        </li>
        <li class="mdc-list-item" data-value="Vegetables">
          Vegetables
        </li>
        <li class="mdc-list-item" data-value="Fruit">
          Fruit
        </li>
      </ul>
    </div>
  </div>
</body>

</html>
0 голосов
/ 01 мая 2020

Вам необходимо объединить поля ввода с кнопкой выбора, чтобы получить поле ввода, а затем написать javascript, чтобы получить функцию автозаполнения. Вы можете проверить мое решение.

console.clear();
const select = new mdc.select.MDCSelect(document.querySelector('.mdc-select'));

select.listen('MDCSelect:change', () => {
  alert(`Selected option at index ${select.selectedIndex} with value "${select.value}"`);
});
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link href="https://unpkg.com/material-components-web@v4.0.0/dist/material-components-web.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <script src="https://unpkg.com/material-components-web@v4.0.0/dist/material-components-web.min.js"></script>
</head>
<body>
  <div class="mdc-select">
  <div class="mdc-select__anchor demo-width-class">
    <i class="mdc-select__dropdown-icon"></i>
    <div class="mdc-select__selected-text"></div>
    <span class="mdc-floating-label">Pick a Food Group</span>
    <div class="mdc-line-ripple"></div>
  </div>

  <div class="mdc-select__menu mdc-menu mdc-menu-surface demo-width-class">
    <ul class="mdc-list">
      <input type="text" class="mdc-list-item--selected mdc-text-field__input" id="name-input">
      <label for="name-input" class="mdc-floating-label">search....</label>
      <li class="mdc-list-item" data-value="grains">
        Bread, Cereal, Rice, and Pasta
      </li>
      <li class="mdc-list-item" data-value="vegetables">
        Vegetables
      </li>
      <li class="mdc-list-item" data-value="fruit">
        Fruit
      </li>
      
      <input type="hidden" name="input_name" value="input_value" class="my_mdc-select__value" />
    
    </ul>
  </div>
</div>


  


</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...