简体   繁体   English

使用javascript从JSON文件中获取数据并将其插入到下拉列表中

[英]Fetch data from JSON file using javascript and insert it into a dropdown list

I have a JSON file, which has a lot of data like: 我有一个JSON文件,其中包含很多数据,例如:

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

I need to fetch this data with javascript, and then send it to a select tag in an HTML file. 我需要使用javascript提取此数据,然后将其发送到HTML文件中的select标记。

This is how my HTML looks, I'd also include js but I don't have a clue how to start or initialize the JSON and send it to 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>

Use the fetch API to load up your json file. 使用提取API加载您的json文件。

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

I recommend using a lightweight templating library called lit-html to construct your DOM. 我建议使用名为lit-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>

You might also consider defining a custom element for your dropdowns which would take a placeholder attribute to define that string, as well as an array of string options as a property. 您可能还考虑为下拉菜单定义一个自定义元素,该元素将使用占位符属性来定义该字符串,并将字符串选项数组作为属性。 Do be aware though that at the moment, you'll have to access the value of the select with javascript, as the Form Participation API is not ready yet. 请注意,尽管目前,您还必须使用javascript访问select的值,因为Form Participation API尚未准备好。

working stackblitz 工作堆闪电战

<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>

For your code 为您的代码

    <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>

You can use XMLHttpRequest Object to send AJAX request and after you get Data from server, you can append options to the select element using a iterating through JSON data. 您可以使用XMLHttpRequest对象发送AJAX请求,并且从服务器获取数据后,可以使用遍历JSON数据的方式将选项附加到select元素。

HTML 的HTML

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

JS 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();

where your data will be like [{"text":"abc","value":"abc"},{.......] 您的数据将像[{"text":"abc","value":"abc"},{.......]

HTML: 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>         

Format the data this way: 通过以下方式格式化数据:

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

Script 脚本

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM