Извлеките данные из файла JSON с помощью javascript и вставьте их в раскрывающийся список

У меня есть файл JSON, в котором много данных, таких как:

[  {  
       "manufacturer": "Samsung",
       "gadget": "Smart Phone",
       "model": "Note 9"
   },
   {  
       "manufacturer": "Apple",
       "gadget": "Smart Phone",
       "model": "iPhone 5"
   }, 
...]

Мне нужно получить эти данные с помощью javascript, а затем отправить их в тег select в файле HTML.

Вот как выглядит мой HTML, я бы также включил js, но я понятия не имею, как запустить или инициализировать JSON и отправить его в HTML...

<main>
  <section id = "welcome-section-shop">
    <div id = "welcome-header">
      <h2>Web shop</h2>
    </div>
  </section>
  <section class = "shop-section">
    <div id = "shop-header">
      <div id = "shop-div">
        <h1>Step 1: Select manufacturer</h1>
        <hr id = "shop-hr">
        <select class = "select-option" id = "select" name = "select">
          <option value = "">Select manufacturer</option>
        </select>
        <h1>Step 2: Select gadget type</h1>
        <hr id = "shop-hr">
        <select class = "select-option" id = "select" name = "select">
          <option value = "">Select gadget</option>
        </select>
        <h1>Step 3: Select model</h1>
        <hr id = "shop-hr">
        <select class = "select-option" id = "select" name = "select">
          <option value = "">Select model</option>
        </select>
      </div>
    </div>
  </section>
</main>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
998
3

Ответы 3

Для вашего кода

    <section id = "welcome-section-shop">
    <div id = "welcome-header">
        <h2>Web shop</h2>
    </div>
</section>

<section class = "shop-section">
    <div id = "shop-header">
        <div id = "shop-div">

            <h1>Step 1: Select manufacturer</h1><hr id = "shop-hr">
            <select class = "select-option" id = "select1" name = "select">
                <option value = "">Select manufacturer</option>
            </select>
            <h1>Step 2: Select gadget type</h1><hr id = "shop-hr">
            <select class = "select-option" id = "select2" name = "select">
                <option value = "">Select gadget</option>
            </select>
            <h1>Step 3: Select model</h1><hr id = "shop-hr">
            <select class = "select-option" id = "select3" name = "select">
                <option value = "">Select model</option>
            </select>

        </div>

    </div>
</section>
<script>
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var data = xhttp.responseJSON;
            for(var i in data){
                var option1 = document.createElement('option');
                var option2 = document.createElement('option');
                var option3 = document.createElement('option');
                option1.text = data[i]["manufacturer"];
                option2.text = data[i]["gadget"];
                option3.text = data[i]["model"];
                document.getElementById('select1').appendChild(option1);
                document.getElementById('select2').appendChild(option2);
                document.getElementById('select3').appendChild(option3);

            }
        }
    };
    xhttp.open("GET", "filename", true);
    xhttp.send();
</script>

Вы можете использовать объект XMLHttpRequest для отправки запроса AJAX, и после того, как вы получите данные с сервера, вы можете добавить параметры к элементу выбора, используя итерацию данных JSON.

HTML

<select id = "abc">
</select>

JS

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
   var data = xhttp.responseJSON;
   for(var i in data){
       var op = document.createElement('option');
       op.text=data[i].text;
       op.value=data[i].value;
       document.getElementById('abc').appendChild(op);
   }
  }
};
xhttp.open("GET", "filename", true);
xhttp.send();

где ваши данные будут как [{"text":"abc","value":"abc"},{.......]

Используйте получить API для загрузки файла json.

const handleAsJson = response => response.json();
const handleError = console.error // or some such;
fetch('/url/to/file.json')
  .then(handleAsJson)
  .catch(handleError);

Я рекомендую использовать легкую библиотеку шаблонов под названием горит-html для построения вашего DOM.

<section id = "welcome-section-shop">
    <div id = "welcome-header">
        <h2>Web shop</h2>
    </div>
</section>

<section class = "shop-section">
<div id = "shop-header">
    <div id = "shop-div">

        <h1>Step 1: Select manufacturer</h1><hr id = "shop-hr">
        <select class = "select-option" id = "manufacturer-select" name = "select">
            <option value = "">Select manufacturer</option>
        </select>
        <h1>Step 2: Select gadget type</h1><hr id = "shop-hr">
        <select class = "select-option" id = "gadget-select" name = "select">
            <option value = "">Select gadget</option>
        </select>  
        <h1>Step 3: Select model</h1><hr id = "shop-hr">
        <select class = "select-option" id = "model-select" name = "select">
            <option value = "">Select model</option>
        </select>         

    </div>

</div>
</section>

<script type = "module">
  import { render, html } from 'https://unpkg.com/lit-html/lit-html.js?module';

  const manufacturerSelect = document.getElementById('manufacturer-select')
  const modelSelect = document.getElementById('model-select')
  const gadgetSelect = document.getElementById('gadget-select')

  // converts array of items into more manageable object 
  const traverse = items => items.reduce((acc, { gadget, manufacturer, model }) => ({
    gadgets: [...acc.gadgets, gadget],
    manufacturers: [...acc.manufacturer, gadget],
    models: [...acc.models, gadget],
  }), {})

  // defines the template for an option element with interpolated string attribute and content
  const optionTpl = string => html`<option value = "${string}">${string}</option>`;
  // renders all option values to each select element
  const renderTemplates = ({ gadget, manufacturer, model }) => {
    render(html`<option value = "">Select manufacturer</option>${manufacturer.map(optionTpl)}`, manufacturerSelect)
    render(html`<option value = "">Select model</option>${model.map(optionTpl)}`, modelSelect)
    render(html`<option value = "">Select gadget</option>${gadget.map(optionTpl)}`, gadgetSelect)
  }

  const handleAsJson = response => response.json();
  const handleError = console.error // or some such;

  fetch('/url/to/file.json')
    .then(handleAsJson)
    .then(traverse)
    .then(renderTemplates)
    .catch(handleError);
</script>

Вы также можете рассмотреть возможность определения пользовательского элемента для раскрывающихся списков, который будет принимать атрибут-заполнитель для определения этой строки, а также массив строковых параметров в качестве свойства. Однако имейте в виду, что на данный момент вам нужно будет получить доступ к значению выбора с помощью javascript, поскольку API участия в формах еще не готов.

рабочий стекблиц

<section id = "welcome-section-shop">
  <div id = "welcome-header">
    <h2>Web shop</h2>
  </div>
</section>

<section class = "shop-section">
  <div id = "shop-header">
    <div id = "shop-div"></div>
  </div>
</section>


<script type = "module">
  import { render } from 'https://unpkg.com/lit-html/lit-html.js?module';
  import { LitElement, html, css } from 'https://unpkg.com/lit-element/lit-element.js?module';

const traverse = items => items.reduce(({gadgets = [], manufacturers = [], models = []}, { gadget, manufacturer, model }) => ({
  gadgets: [...gadgets, gadget],
  manufacturers: [...manufacturer, manufacturer],
  models: [...models, model],
}), {})

const optionTpl = string => html`<option value = "${string}">${string}</option>`;

customElements.define('shop-dropdown', class extends LitElement {
  static get properties() {
    return {
      placeholder: { type: String },
      items: { type: Array },
    };
  }

  static get styles() {
    return css`
      :host {
        display: block;
      }

      select {
        /*...*/
      }
    `
  }

  get value() {
    return (
      this.shadowRoot &&
      this.shadowRoot.querySelector('select') &&
      this.shadowRoot.querySelector('select').value
    );
  }

  render() {
    return html`
    <select>
      <option>${this.placeholder}</option>
      ${this.items.map(optionTpl)}
    </select>
    `
  }
});

const handleAsJson = response => response.json();
const handleError = console.error // or some such;

const renderTemplates = ({ gadgets, models, manufacturers }) => render(html`
<h1>Step 1: Select manufacturer</h1>
<hr/>
<shop-select placeholder = "Select manufacturer" .items=${manufacturers}></shop-select>

<h1>Step 2: Select gadget type</h1>
<hr/>
<shop-select placeholder = "Select gadget" .items=${gadgets}></shop-select>

<h1>Step 3: Select model</h1>
<hr/>
<shop-select placeholder = "Select model" .items=${models}></shop-select>
`, document.getElementById('shop-div'))

  fetch('/url/to/file.json')
    .then(handleAsJson)
    .then(traverse)
    .then(renderTemplates)
    .catch(handleError);
</script>

HTML:

<h1>Step 1: Select manufacturer</h1><hr id = "shop-hr">
<select class = "select-option" id = "select-manufacturer" name = "manufacturer">
  <option id = "manufacturer-placeholder" value = "">Select manufacturer</option>
</select>

<h1>Step 2: Select gadget type</h1><hr id = "shop-hr">
<select class = "select-option" id = "select-gadget" name = "gadget" disabled>
  <option id = "gadget-placeholder" value = "">Select gadget</option>
</select>  

<h1>Step 3: Select model</h1><hr id = "shop-hr">
<select class = "select-option" id = "select-model" name = "model" disabled>
  <option id = "model-placeholder" value = "">Select model</option>
</select>         

Отформатируйте данные следующим образом:

{
  "Samsung": {
    "Smart Phone": [ "Note 9", ],
    // ...
  },
  "Apple": {
    "Smart Phone: [ "iPhone 5", /* ... */ ],
    // ...
  },
  // ...
}

Скрипт

const xhr = new XMLHttpRequest()
const url = 'path/to/file.json'
xhr.onreadystatechange = function() {
  if ((this.readyState == 4) && (this.status == 200)) {
    const array = JSON.parse(this.responseText)
    const formatted = formatData(array)
    start(formatted)
  }
}

function formatData(array) {
  const res = {}
  for (let item of array) {
    const gadgets = res[item.manufacturer] || (res[item.manufacturer] = {})
    const models = gadgets[item.gadget] || (gadgets[item.gadget] = [])
    models.push(item.model)
  }
  return res
}

function start(data) {

  const selectManufacturer = document.getElementById('select-manufacturer')
  const selectGadget = document.getElementById('select-gadget')
  const selectModel = document.getElementById('select-model')
  for (let manufacturer in data) {
    selectManufacturer.appendChild(createOption(manufacturer))
  }

  let gadgets

  selectManufacturer.addEventListener('change', () => {
    gadgets = data[selectManufacturer.value]
    selectGadget.innerHTML = ''
    selectGadget.appendChild(placeholderOption('gadget'))
    for (let gadget in gadgets) {
      selectGadget.appendChild(createOption(gadget))
    }
    selectGadget.disabled = false
    selectModel.innerHTML = ''
    selectModel.appendChild(placeholderOption('model'))
    selectModel.disabled = true
    const placeholder = document.getElementById('manufacturer-placeholder')
    if (placeholder) selectManufacturer.removeChild(placeholder)
  })

  selectGadget.addEventListener('change', () => {
    const models = gadgets[selectGadget.value]
    selectModel.innerHTML = ''
    selectModel.appendChild(placeholderOption('model'))
    for (let model of models) {
      selectModel.appendChild(createOption(model))
    }
    selectModel.disabled = false
    const placeholder = document.getElementById('gadget-placeholder')
    if (placeholder) selectGadget.removeChild(placeholder)
  })

  selectModel.addEventListener('change', () => {
    const placeholder = document.getElementById('gadget-placeholder')
    if (placeholder) selectModel.removeChild(placeholder)
  })
}

function createOption(value, text) {
  if (text == undefined) text = value
  let opt = document.createElement('option')
  opt.value = value
  opt.innerHTML = text
  return opt
}
function placeholderOption(type) {
  let opt = createOption('', `Select ${type}`)
  opt.id = `${type}-placeholder`
  return opt
}

Эй быстрый вопрос! В JSON у меня есть следующие данные: 3 производителя, Samsung, Apple и Huawei, 3 разных типа гаджетов, смартфон, планшет, умные часы и 5+ разных моделей каждого типа гаджета. В этом случае, как мне организовать JSON?

Ivan Kovačić 20.02.2019 00:02

возможно вот так? { "Samsung": { "Смартфон": [ "Note 9", "Galaxy S8"], "Планшет": ["abc", "abc"], "Smart Watch": ["abc", "abc" ] }, "Apple": { "Смартфон": [ "Note 9", "Galaxy S8"], "Планшет":[], "Smart Watch": ["abc", "abc"] }, "Huawei ": { "Смартфон": [ "Note 9", "Galaxy S8"], "Планшет": ["abc", "abc"], "Smart Watch": ["abc", "abc"] } }

Ivan Kovačić 20.02.2019 00:10

Это самый простой способ сделать надежный выпадающий список. Функция formatData() отформатирует ваши данные таким образом, если они будут такими, как вы представили их в вопросе...

Nathan Xabedi 20.02.2019 00:15

Если ваш JSON организован таким образом, пропустите функцию formatData().

Nathan Xabedi 20.02.2019 00:19

В любом случае это не работает, но ваш код выглядит более чем нормально :(

Ivan Kovačić 20.02.2019 00:21

обработчик readystatechange: const data = JSON.parse(this.responseText); start(data)

Nathan Xabedi 20.02.2019 00:30

Другие вопросы по теме