代码之家  ›  专栏  ›  技术社区  ›  Paddy Hallihan

基于以前的下拉选择更新下拉列表

  •  5
  • Paddy Hallihan  · 技术社区  · 6 年前

    在每个产品页面上,每个属性都有一个下拉列表,其中包含一个 'attribute_price' .

    'hidden_attribute_value' .

    因此,并非所有尺寸和颜色的组合都是一种选择。例如,我们可能有 'small_red' 'medium_red' 但是没有 'large_red'

    所以如果他们选择 'large' 'red' 不应该是颜色的选项。

    到目前为止我得到的是:

    $("select.attribute_price").on("change", function(){
    
        var id = event.target.id;
        // determine which dropdown was changed (size or colour)
        var attribute_value = document.getElementById(id).value+'_';
        // get the value of the dropdown that they selected
    
        var other_attribute_ids = []
        var i;
        var other_attributes = document.getElementsByClassName("attribute_price");
        for(i=0; i<other_attributes.length; i++){
            if(other_attributes[i].id != id){
                var other_attribute_id = document.getElementById(other_attributes[i].id).id;
                other_attribute_ids.push(other_attribute_id);
            }
        }
        // create an array of all of the other dropdown ids excluding the one they changed
    
        var all_attribute_ids = []
        var i;
        var all_attributes = document.getElementsByClassName("hidden_attribute_value");
        for(i=0; i<all_attributes.length; i++){
            all_attribute_ids.push(all_attributes[i].id);
        }
        // create an array of all of the possible values that it can be
    
    });
    

    所以我有一个变量 'attribute_value' 比如“红”或“蓝”。

    我有一个数组叫做 'all_attribute_values' 其中包含所有可能组合的隐藏输入的ID。它们的值类似于“small\u red”或“small\u blue”。

    'other_attribute_ids' 它具有其他尚未选择的下拉菜单的id。

    所以如果 不包含 从中删除该选项 '其他属性\u ID'

    5 回复  |  直到 5 年前
        1
  •  1
  •   Ercan Peker    6 年前

    可以生成要测试的随机属性。

    $(document).ready(function () {
        /* generates random attributes */
        var div_attributes = $('#div_attributes');
        var select_colors = $('#select_colors');
        var select_sizes = $('#select_sizes');
        var select_attr0 = $('#select_attr0');
        var select_attr1 = $('#select_attr1');
    
        $('#btnGenerate').on('click', function () {
            var result = "";
    
            //
            var index = getRandomArbitrary(1, select_sizes.find('option').get().length);
            var random_attribute = select_sizes.find('option').eq(index).attr('value');
            result += random_attribute;
    
            //
            index = getRandomArbitrary(1, select_colors.find('option').get().length);
            random_attribute = select_colors.find('option').eq(index).attr('value');
            result += '_' + random_attribute;
    
            //
            index = getRandomArbitrary(1, select_attr0.find('option').get().length);
            random_attribute = select_attr0.find('option').eq(index).attr('value');
            result += '_' + random_attribute;
    
            //
            index = getRandomArbitrary(1, select_attr1.find('option').get().length);
            random_attribute = select_attr1.find('option').eq(index).attr('value');
            result += '_' + random_attribute;
    
            $('<div>' + result + '</div>').appendTo(div_attributes);
    
            div_attributes.find('div').each(function () {
                var item = $(this);
                attributes.push(item.text());
            });
            SetFirstSelect();
        });
    
        var attributes = [];
        //sets first select
        SetFirstSelect();
        function SetFirstSelect() {
            $.each(attributes, function (i, val) {
                var attribute = val.split('_')[0];
                $('.attribute_price').eq(0).find('option[value="' + attribute + '"]').show();
            });
        }
        //control attributes array
        var selected_val = [];
        $('.attribute_price').on('change', function () {
            var item = $(this);
            var index = item.index('.attribute_price');
            selected_val[index] = item.val();
            var select = $('.attribute_price').eq(index + 1);
            var selected_attribute = item.val();
            for (var i = index + 1; i < $('.attribute_price').get().length; i++) {
                $('.attribute_price').eq(i).find('option').hide();
                $('.attribute_price').eq(i).prop('selectedIndex', 0)
            }
            var selected_val_str = selected_val[0];
            for (var i = 1; i <= index; i++) {
                selected_val_str += '_' + selected_val[i];
            }
            $.each(attributes, function (j, val) {
                if (val.indexOf(selected_val_str) >= 0) {
                    var attribute1 = val.split('_')[index + 1];
    
                    select.find('option[value="' + attribute1 + '"]').show();
                }
            });
        });
    
        function getRandomArbitrary(min, max) {
            return Math.floor(Math.random() * (max - min) + min);
        }
    });
    .attribute_price option {
                display: none;
            }
            
            .container {
            margin:30px;
            }
            
            .row > div {
            padding:10px;
            }
            .btn {
            margin-top:20px;
            }
    <script
      src="https://code.jquery.com/jquery-3.3.1.min.js"
      integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
      crossorigin="anonymous"></script>
      <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    
    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
       <div class="container">
            <div class="row">
            <div style="width:50%; float:left">
                    <input type="button" class="btn btn-primary" id="btnGenerate" value="generate random attributes" />
                    <div id="div_attributes"></div>
                </div>
                <div style="width:50%; float:left">
                    <div class="form-group">
                        <label>Sizes</label>
                        <select class="form-control attribute_price" id="select_sizes">
                            <option value="">select size</option>
                            <option value="small">small</option>
                            <option value="large">large</option>
                            <option value="medium">medium</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>color</label>
                        <select id="select_colors" class="form-control attribute_price">
                            <option value="">select color</option>
                            <option value="black">black</option>
                            <option value="yellow">yellow</option>
                            <option value="red">red</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>attrType0</label>
                        <select id="select_attr0" class="form-control attribute_price">
                            <option value="">select attr0</option>
                            <option value="attr00">attr00</option>
                            <option value="attr01">attr01</option>
                            <option value="attr02">attr02</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>attrType1</label>
                        <select id="select_attr1" class="form-control attribute_price">
                            <option value="">select attr1</option>
                            <option value="attr10">attr10</option>
                            <option value="attr11">attr11</option>
                            <option value="attr12">attr12</option>
                        </select>
                    </div>
                </div>
    
                
            </div>
        </div>
        2
  •  5
  •   Faiz Mohamed Haneef    6 年前

    我考虑了独立属性,因此解决方案将缩放到具有不同值的新属性。我还认为服务器响应是不可编辑的。

    我在jsfiddle中有一个快速链接来检查解决方案

    https://jsfiddle.net/nfLx6aok/1/

    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    </head>
    
    <select id="size" class="attribute_price">
      <option value="small">Small</option>
      <option value="large">Large</option>
    </select>
    
    <select id="color" class="attribute_price">
      <option value="red">Red</option>
      <option value="green">Green</option>
      <option value="black">Black</option>
    </select>
    
    <select id="pattern" class="attribute_price">
      <option value="solids">Solids</option>
      <option value="checked">Checked</option>
      <option value="dots">Dots</option>
    
    </select>
    
    <input type="hidden" id="small_red_solids" class="hidden_attribute_value">
    <input type="hidden" id="small_black_dots" class="hidden_attribute_value">
    <input type="hidden" id="large_green_checked" class="hidden_attribute_value">
    
    <script>
    
      // on page load 
      $( document ).ready(function() {
        renderOptions();
    });
    
    
      $("select.attribute_price").on("change", function () {
        renderOptions();
      });
    
      function renderOptions() {
        // create an array of all of the possible values that it can be
        // allowed_attribute_values = ['small_red', 'large_blue']
        var allowed_attribute_values = [];
        var all_attributes = document.getElementsByClassName("hidden_attribute_value");
        for (var i = 0; i < all_attributes.length; i++) {
          allowed_attribute_values.push(all_attributes[i].id);
        }
    
        function getAllPossibleValues(current_level, all_attributes) {
          var depth_index = all_attributes.length;
          var selected_combination = '';
          for (var i = 0; i < depth_index; i++) {
            if (i <= current_level) {
              selected_combination += all_attributes[i].value;
              if (i != all_attributes.length - 1) {
                selected_combination += '_';
              }
            }
          }
    
          // hide all lower options
          for (var i = current_level + 1; i < depth_index; i++) {
            var selectedIdOptions = all_attributes[i].options;
            all_attributes[i].value = null
            for (var j = 0; j < selectedIdOptions.length; j++) {
              // hide all lower options
              selectedIdOptions[j].hidden = true;
              var el = allowed_attribute_values.find(a => a.includes(selected_combination + selectedIdOptions[j].value));
              if (el) {
                selectedIdOptions[j].hidden = false;
              }
            }
          }
        }
    
        if (event) {
          var id = event.target.id;
        } else {
          var id = document.getElementsByClassName("attribute_price")[0].id;
        }
    
        var other_attributes = document.getElementsByClassName("attribute_price");
        for (var i = 0; i < other_attributes.length; i++) {
          if (other_attributes[i].id == id) {
            allPossibleValues = getAllPossibleValues(i, other_attributes);
            // we dont want to go deeper as of now
            break;
          }
        }
      }
    </script>
    
        3
  •  1
  •   Nishith    6 年前

    你有一个网站的假设下拉列表,例如衣服有属性大小,价格,颜色,品牌,你有一个对象数组包含所有这些属性为每个对象。

    我将在reactjs中解释这一点,因为我比php更熟悉它

    此时,您的所有下拉列表都将处于活动状态,现在如果用户对第一个下拉列表(即大小)进行了任何更改,您可以重置要重新选择的其他下拉列表,也可以根据处理方式传递新列表

    这是我为确定日期所做的一件类似的事情

    const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July','August', 'September', 'October', 'November', 'December']
    const Month30 = ['4', '6', '9', '11']
    const Month31 = ['1', '3', '5', '7', '8', '10', '12']
    
    class Dropdown extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          birthDay: '',
          birthMonth: '',
          birthYear: ''
        }
      }
    
      componentDidMount() {
      }
    
      getMonthTotalDays = (birthMonth, birthYear) => {
        if (birthMonth === '02') {
          if (birthYear !== '' && birthYear % 4 === 0) {
            return 29
          } else {
            return 28
          }
        } else if (Month30.includes(birthMonth)) {
          return 30
        } else {
          return 31
        }
      }
    
      handleChange = e => {
        this.setState({
          [e.target.name]: e.target.value
        }, () => {
          const { birthMonth, birthYear, birthDay } = this.state
          const days = this.getMonthTotalDays(birthMonth, birthYear)
          if (birthDay > days) {
            this.setState({ birthDay: '' })
          }
        })
    
      }
    
    
      renderMonths = () => {
        return months.map((month, i) => {
          if(i < 9){
            return (<option key={`${month}-${i}`} value={'0' + (i + 1)}>{month}</option>)
          }
          else
            return (<option key={`${month}-${i}`} value={i + 1}>{month}</option>)
        })
      }
    
      renderDay = () => {
        const { birthMonth, birthDay, birthYear } = this.state
        const daysOptions = []
        let days = this.getMonthTotalDays(birthMonth, birthYear)
    
        for (let day=1; day<=days; day++) {
          daysOptions.push(<option key={`'date-'${day}`} value={day}> { day } </option>)
        }
    
        return daysOptions
      }
    
      renderYears = () => {
        const toYear = (new Date()).getFullYear() - 16
        const yearOptions = []
        for (let year = 1960; year <= toYear; year++) {
          yearOptions.push(<option key={`year-${year}`} value={year}> { year } </option>)
        }
    
        return yearOptions
      }
    
    
      render() {
        const { birthDay, birthMonth, birthYear } = this.state
        return (
          <div>
              <label>Month</label>
              <select
                name="birthMonth"
                value={ birthMonth }
                onChange={this.handleChange}
              >
                <option disabled selected value=''>Month</option>
                { this.renderMonths() }
              </select>
              <label>Day</label>
              <select
                name='birthDay'
                value={ birthDay }
                onChange={this.handleChange}
              >
                <option disabled selected value=''>Day</option>
                { this.renderDay() }
              </select>
              <label>Year</label>
              <select
                name='birthYear'
                value={ birthYear }
                onChange={this.handleChange}
              >
                <option disabled selected value=''>Year</option>
                { this.renderYears() }
              </select>
          </div>
        )
      }
    }
    
    
    ReactDOM.render(
      <Dropdown />,
      document.getElementById('drop')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="drop"></div>
        4
  •  0
  •   Rocky Sims    6 年前

    这里有一个解决方案需要 skus 数组作为输入,并为每个属性创建一个下拉列表。当任何下拉列表值更改时,所有其他下拉列表中的选项都会更新,以仅显示与所选选项一致的选项。

    https://codepen.io/rockysims/pen/PyJbbv

    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
    <script type="text/javascript">
        skus = [{
            id: 1,
            attributes: {
                color: "red",
                size: "small",
                shape: "circle"
            }
        }, {
            id: 2,
            attributes: {
                color: "red",
                size: "medium",
                shape: "square"
            }
        }, {
            id: 3,
            attributes: {
                color: "yellow",
                size: "small",
                shape: "circle"
            }
        }, {
            id: 4,
            attributes: {
                color: "yellow",
                size: "medium",
                shape: "square"
            }
        }, {
            id: 5,
            attributes: {
                color: "yellow",
                size: "large",
                shape: "square"
            }
        }, {
            id: 6,
            attributes: {
                color: "green",
                size: "medium",
                shape: "square"
            }
        }, {
            id: 7,
            attributes: {
                color: "green",
                size: "large",
                shape: "square"
            }
        }];
    
        $(function() {
            const allOptionsByAttrName = buildAllOptionsByAttrName();
    
            //create dropdowns
            for (let attrName in allOptionsByAttrName) {
                const dropdownId = attrName + "Dropdown";
                const options = allOptionsByAttrName[attrName];
                let html = "";
                html += attrName + ": ";
                html += buildDropdownHtml(dropdownId, options);
                html += "<br/>";
                $("#dropdowns").append(html);
            }
    
            //on dropdown changes, update options of all dropdowns
            for (let changedAttrName in allOptionsByAttrName) {
                $("#" + changedAttrName + "Dropdown").on('change', function() {
                    //build pickedOptionByAttrName
                    const pickedOptionByAttrName = {};
                    for (let attrName in allOptionsByAttrName) {
                        const dropdown = $("#" + attrName + "Dropdown");
                        pickedOptionByAttrName[attrName] = dropdown.val();
                    }
    
                    refreshAvailableOptions(pickedOptionByAttrName);
                });
            }
        });
    
        function buildAllOptionsByAttrName() {
            const allOptionsByAttrName = {};
            for (let sku of skus) {
                for (let attrName in sku.attributes) {
                    allOptionsByAttrName[attrName] = allOptionsByAttrName[attrName] || [];
                    if (allOptionsByAttrName[attrName].indexOf(sku.attributes[attrName]) == -1) {
                        allOptionsByAttrName[attrName].push(sku.attributes[attrName]);
                    }
                }
            }
    
            return allOptionsByAttrName;
        }
    
        function buildDropdownHtml(dropdownId, options) {
            let html = "";
            html += "<select id='" + dropdownId + "'>";
            html += "<option value=''>";
            html += "";
            html += "</option>";
            for (let option of options) {
                html += "<option value='" + option + "'>";
                html += option;
                html += "</option>";
            }
            html += "</select>";
    
            return html;
        }
    
        function refreshAvailableOptions(pickedOptionByAttrName) {
            for (let attrName in pickedOptionByAttrName) {
                //build availableOptions
                const dropdown = $("#" + attrName + "Dropdown");
                const options = $("#" + attrName + "Dropdown option");
                const availableOptions = buildAvailableOptions(pickedOptionByAttrName, attrName);
                availableOptions.push(""); //nothing picked option
    
                //show available options and hide others
                options.each(function() {
                    const option = $(this);
                    const optionIsAvailable = availableOptions.indexOf(option.val()) != -1;
                    if (optionIsAvailable) {
                        option.show();
                    } else {
                        option.hide();
                    }
                });
            }
        }
    
        function buildAvailableOptions(pickedOptionByAttrName, attrNameToBuildFor) {
            //build availableSkus
            const availableSkus = skus.filter(function(sku) {
                let available = true;
                for (let attrName in pickedOptionByAttrName) {
                    if (attrName != attrNameToBuildFor) {
                        const pickedOption = pickedOptionByAttrName[attrName];
                        if (pickedOption) {
                            available = available && sku.attributes[attrName] == pickedOption;
                        }
                    }
                }
    
                return available;
            });
    
            //build availableOptions
            const availableOptions = [];
            for (let sku of availableSkus) {
                if (availableOptions.indexOf(sku.attributes[attrNameToBuildFor]) == -1) {
                    availableOptions.push(sku.attributes[attrNameToBuildFor]);
                }
            }
    
            return availableOptions;
        }
    </script>
    
    <div id="dropdowns">
    </div>
    

    如果不希望动态创建下拉列表,请注释掉下面的for循环 //create dropdowns <div id="dropdowns"></div> 包括以下内容:

    <div id="dropdowns">
        color: 
        <select id="colorDropdown">
            <option value=""></option>
            <option value="red">red</option>
            <option value="yellow">yellow</option>
            <option value="green">green</option>
        </select><br/>
        size: 
        <select id="sizeDropdown">
            <option value=""></option>
            <option value="small">small</option>
            <option value="medium">medium</option>
            <option value="large">large</option>
        </select><br/>
        shape:
        <select id="shapeDropdown">
            <option value=""></option>
            <option value="circle">circle</option>
            <option value="square">square</option>
        </select><br>
    </div>
    
        5
  •  0
  •   ACD    6 年前

    如果您可以在PHP中确定其他类别的哪些选项可用于某些下拉类别值选择。对于每个选定值,可以增量地将每个选项标记为已排除,以使其保持禁用状态:

    JS公司:

    $(document).ready(function () {
        $(".dropdown").change(function(){
            var val = $(this).val();
            var id = $(this).attr('id');
    
            $.get('get_options.php', {category: id, value:val}, function(data) {
    
                $(".dropdown:not(#"+id+")").each(function() {
    
                    var cat = $(this).attr('id');
                    $(this).find('option').each(function() {
    
                        var cat_val = $(this).val();
                        var options = data[cat];
                        var exluded = $(this).attr('exlude');
    
                        if ($.inArray(cat_val, options) !== -1) {
    
                            $(this).attr('exlude', exluded-1);
                            if(exluded == 1) {
                                $(this).prop('disabled', false);
                            }
                        } else {
    
                            $(this).attr('exlude', exluded+1);
                            $(this).prop('disabled', true);
                        }
                    });
                });
            }, 'json');
        });
    });
    

    HTML格式:

    <div id="dropdowns">
    color: 
    <select id="color" class="dropdown">
        <option value=""></option>
        <option value="red">red</option>
        <option value="yellow">yellow</option>
        <option value="green">green</option>
    </select><br/>
    size: 
    <select id="size" class="dropdown">
        <option value=""></option>
        <option value="small">small</option>
        <option value="medium">medium</option>
        <option value="large">large</option>
    </select><br/>
    shape:
    <select id="shape" class="dropdown">
        <option value=""></option>
        <option value="circle">circle</option>
        <option value="square">square</option>
        <option value="triangle">triangle</option>
    </select><br>
    

    **示例数据:**如果用户首先选择颜色,则返回其他下拉类别的所有可用选项。

    {"size": ["small","large"],"shape":["circle"]}
    

    或在php中:

    $data = array(
        'size' => array(
            'small', 'large'
        ),
        'shape' => array(
            'circle'
        ),
    );
    
    echo json_encode($data);