How would I be able to multiple select and pass da

2019-06-15 12:57发布

I need to pass the data in the given format.

rules : [{
        name:null,
        section:null,
        data   : [{head:null,value:null}]
    }],

This is the problem I am facing. Hope somebody could help me sort out a solution. The snippet is given. I need to pass data in the format given above. If another array is needed inside rules[], it is also fine

Is another array needed for head and value inside data[]. This will be also fine, if needed. Hoping for a help. Please help me to have a solution.

Please change the select to read the issues

    addForm = new Vue({
      el: "#addForm",
      data: {
        rules: [{
          name: null,
          section: null,
          data: [{
            head: null,
            value: null
          }]
        }],

      },
      methods: {
        addNewRules: function() {
          this.rules.push({
            name: null,
            section: null,
            data: [{
              head: null,
              value: null
            }]
          });
        },
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
   

        <div id="addForm">
      
    
    <div class="card-content" v-for="(bok, index) in rules" :key="index">
         <p>This is the first part which is fine for me</p>
            <div class="row">
              <div class="col-md-6">
                <div class="form-group label-floating">
                  <label class="control-label">Act</label>
                  <select class="form-control" v-model="bok.name">
                    <option value="Act,1972">Act,1972</option>
                    <option value="Rule,2012">Rule,2012(CEMR)</option>
                    <option value="Act,1961">Act,1961</option>
                  </select>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group label-floating">
                <label class="control-label">Section</label>
                <input type="text" class="form-control" v-model="bok.section">
              </div>
            </div>
    
       
        
    
    <div class="row" v-if="bok.name == 'Act,1972'">
           <p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Arms</label>
                  <input type="text" class="form-control" v-model="bok.data[0].head" required="">
                </div>
              </div>
            </div>
    
        
            <div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Item</label>
                  <input type="text" class="form-control" v-model="bok.data[0].head" required="">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Quantity Seized</label>
                  <input type="text" class="form-control" v-model="bok.data[0].head" required="">
                </div>
              </div>
            </div>
    
       
            <div class="row" v-if="bok.name == 'Act,1961'">
 <p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
            to do this?</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Select</label>
                  <select class=" form-control" v-model="bok.data[0].head" multiple="">
                    <option value="1">life</option>
                    <option value="2">Enment</option>
                  </select>
                </div>
              </div>
            </div>
       
            <div class="row" v-if="bok.data[0].head == 1">
 <p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Area1</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Area2</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value">
                </div>
              </div>
            </div>
            <div class="row" v-if="bok.data[0].head == 2">
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">No.</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Model</label>
                  <input type="text" class="form-control" required="">
                </div>
              </div>
            </div>
          </div>
          <a @click="addNewRules">Add Another Rule</a>
        </div>

3条回答
放荡不羁爱自由
2楼-- · 2019-06-15 13:29

hey why don't you go with multi-select checkbox drop-down and apply v-model on checkbox. ? Link: How to use Checkbox inside Select Option

查看更多
smile是对你的礼貌
3楼-- · 2019-06-15 13:30

My approach is basically change the type of the data[0].head and data[0].value depending on the options you selected.

So for example, if you select Rule,2012, then data[0].head would be an object with item and qty as its items. And if you select Act,1961, data[0].head would be an array of numbers (e.g. ['1', '2']) and data[0].value would be an object with area_1 and area_2 or number and model or all the four items.

See and try the code snippet to see the code I added/changed.

(Or compare your code with mine and you'd see the changes.)

addForm = new Vue({
      el: "#addForm",
      data: {
        rules: [{
          name: null,
          section: null,
          data: [{
            head: null,
            value: null
          }]
        }],

      },
      methods: {
        addNewRules: function() {
          this.rules.push({
            name: null,
            section: null,
            data: [{
              head: null,
              value: null
            }]
          });
        },

        removeRuleDataValueProps: function(i) {
          var d = this.rules[i].data[0];

          if (jQuery.inArray('1', d.head) < 0) {
            Vue.delete(d.value, 'area_1');
            Vue.delete(d.value, 'area_2');
          }

          if (jQuery.inArray('2', d.head) < 0) {
            Vue.delete(d.value, 'number');
            Vue.delete(d.value, 'model');
          }
        },

        _setRuleDataHeadDataType: function(i) {
          var d = this.rules[i].data[0],
            h = d.head,
            _h = d._head,
            _restore = true;

          if (undefined === _h) {
            d._head = h;
            _restore = false;
          }

          switch (this.rules[i].name) {
            case 'Rule,2012':
              var a = Array.isArray(h);
              if (a || null === h || 'object' !== typeof h) {
                Vue.set(d, 'head', {});
              }

              break;

            case 'Act,1961':
              if (!Array.isArray(h)) {
                Vue.set(d, 'head', []);
              }

              break;

            default:
              if (_restore && undefined !== _h) {
                d.head = _h;
              }

              break;
          }
        },

        _setRuleDataValueDataType: function(i) {
          var d = this.rules[i].data[0],
            v = d.value,
            _v = d._value,
            _restore = true;

          if (undefined === _v) {
            d._value = v;
            _restore = false;
          }

          switch (this.rules[i].name) {
            case 'Act,1972':
            case 'Act,1961':
              var a = Array.isArray(v);
              if (a || null === v || 'object' !== typeof v) {
                Vue.set(d, 'value', {});
              }

              if (_restore) {
                this.removeRuleDataValueProps(i);
              }

              break;

            default:
              if (_restore && undefined !== _v) {
                d.value = _v;
              }

              break;
          }
        },

        setRuleDataType: function(i, k) {
          if (this.rules[i] && this.rules[i].data[0]) {
            if (!k || 'head' === k) {
              this._setRuleDataHeadDataType(i);
            }

            if (!k || 'value' === k) {
              this._setRuleDataValueDataType(i);
            }
          }
        }
      }
    })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
   

        <div id="addForm">
      
    <h3>Try the different options and see the JSON output changes.</h3>
    <div class="card-content" v-for="(bok, index) in rules" :key="index">
         <p>This is the first part which is fine for me</p>
            <div class="row">
              <div class="col-md-6">
                <div class="form-group label-floating">
                  <label class="control-label">Act</label>
                  <!-- Here we change the type of `bok.data[0].head` depending on the selected option. -->
                  <select class="form-control" v-model="bok.name" @change="setRuleDataType(index)">
                    <option value="Act,1972">Act,1972</option>
                    <option value="Rule,2012">Rule,2012(CEMR)</option>
                    <option value="Act,1961">Act,1961</option>
                  </select>
                </div>
              </div>
            <!--</div>-->
            <div class="col-md-6">
              <div class="form-group label-floating">
                <label class="control-label">Section</label>
                <input type="text" class="form-control" v-model="bok.section">
              </div>
            </div>
    
       
        
    <!-- Here, `bok.data[0].head` is expected to be a `string`. -->
    <div class="row" v-if="bok.name == 'Act,1972'">
           <p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Arms</label>
                  <input type="text" class="form-control" v-model="bok.data[0].head" @change="setRuleDataType(index, 'value')" required="">
                </div>
              </div>
            </div>
    
            <!-- Here, `bok.data[0].head` is an `object` with 'item' and 'qty'. -->
            <div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Item</label>
                  <input type="text" class="form-control" v-model="bok.data[0].head.item" required="">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Quantity Seized</label>
                  <input type="text" class="form-control" v-model="bok.data[0].head.qty" required="">
                </div>
              </div>
            </div>
    
            <!-- Here, `bok.data[0].head` would be an array of numbers. -->
            <div class="row" v-if="bok.name == 'Act,1961'">
 <p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
            to do this?</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Select</label>
                  <select class=" form-control" v-model="bok.data[0].head" @change="removeRuleDataValueProps(index)" multiple="">
                    <option value="1">life</option>
                    <option value="2">Enment</option>
                  </select>
                </div>
              </div>
            </div>
       
            <div class="row" v-if="jQuery.inArray('1', bok.data[0].head) > -1">
 <p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Area1</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value.area_1">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Area2</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value.area_2">
                </div>
              </div>
            </div>
            <div class="row" v-if="jQuery.inArray('2', bok.data[0].head) > -1">
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">No.</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value.number">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Model</label>
                  <input type="text" class="form-control" required="" v-model="bok.data[0].value.model">
                </div>
              </div>
            </div>

            <h3>The JSON value of <code>bok</code></h3>
            <textarea rows="3" cols="75%" readonly>{{ JSON.stringify(bok) }}</textarea>
          </div>
          <a @click="addNewRules">Add Another Rule</a>
        </div>

查看更多
【Aperson】
4楼-- · 2019-06-15 13:51

My opinion,

  1. Based on the HTML you provied, create one data property=ruleTemplate (it makes sure v-model with related form controls).

  2. When add new rules, push one clone of the template to the rules

  3. When you need the data, just convert the rules to the specific format like this.getFormattedRules in below demo.

Below is the demo:

addForm = new Vue({
      el: "#addForm",
      data: {
        ruleTemplates: {
          name: '',
          section: '',
          subMenu: {
          'Act,1972': '',
          'Rule,2012': {'item': '','qty': ''},
          'Act,1961': {'head':[], options:{'option1':'', 'option2':''}}
          }
        },
        rules: [{
            name: '',
            section: '',
            subMenu: {
            'Act,1972': '',
            'Rule,2012': {'item': '','qty': ''},
            'Act,1961': {'head':[], options:{'option1':'', 'option2':''}}
            }
          }
        ],
      },
      computed: {
        formatedJson: function () {
          let handler1972 = function (data) {
            return [{'head': 'Arms', 'value': data}]
          }
          let handler2012 = function (data) {
            return [{'head': 'item', 'value': data.item},{'head': 'qty', 'value': data.qty}]
          }
          let handler1961 = function (data) {
            return [{'head': 'option1', 'value': data.options.option1},{'head': 'option1', 'value': data.options.option2}]
          }
          let handlers = {'Act,1972': handler1972, 'Rule,2012': handler2012, 'Act,1961': handler1961
          }
          return this.rules.map((rule) => {
            let formatedRule = new Object()
            // convert the rule to the specific format
            formatedRule.name = rule.name
            formatedRule.section = rule.section
            handler = handlers[rule.name]
            formatedRule.data = handler ? handler(rule.subMenu[rule.name]) : []
            return formatedRule
          })
        }
      },
      methods: {
        addNewRules: function() {
          this.rules.push(Object.assign({},this.ruleTemplates))
        }
      }
    })
.show-format {
  position:absolute;
  top:2px;
  right -4px;
  background-color:gray
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
   
   <div id="addForm">
    <div class="show-format">Format: {{formatedJson}}</div>
    <div class="card-content" v-for="(bok, index) in rules" :key="index">
         <p>This is the first part which is fine for me</p>
            <div class="row">
              <div class="col-md-6">
                <div class="form-group label-floating">
                  <label class="control-label">Act</label>
                  <select class="form-control" v-model="bok.name">
                    <option value="Act,1972">Act,1972</option>
                    <option value="Rule,2012">Rule,2012(CEMR)</option>
                    <option value="Act,1961">Act,1961</option>
                  </select>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group label-floating">
                <label class="control-label">Section</label>
                <input type="text" class="form-control" v-model="bok.section">
              </div>
            </div>
    
       
        
    
    <div class="row" v-if="bok.name == 'Act,1972'">
           <p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Arms</label>
                  <input type="text" class="form-control" v-model="bok.subMenu['Act,1972']" required="">
                </div>
              </div>
            </div>
    
        
            <div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Item</label>
                  <input type="text" class="form-control" v-model="bok.subMenu['Rule,2012']['item']" required="">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Quantity Seized</label>
                  <input type="text" class="form-control" v-model="bok.subMenu['Rule,2012']['qty']" required="">
                </div>
              </div>
            </div>
    
       
            <div class="row" v-if="bok.name == 'Act,1961'">
 <p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
            to do this?</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Select</label>
                  <select class=" form-control" v-model="bok.subMenu['Act,1961'].head" >
                    <option value="1">life</option>
                    <option value="2">Enment</option>
                  </select>
                </div>
              </div>
            </div>
       
            <div class="row" v-if="bok.subMenu['Act,1961'].head == 1">
 <p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Area1</label>
                  <input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option1">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Area2</label>
                  <input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option2">
                </div>
              </div>
            </div>
            <div class="row" v-if="bok.subMenu['Act,1961'].head == 2">
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">No.</label>
                  <input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option1">
                </div>
              </div>
              <div class="col-md-4">
                <div class="form-group label-floating">
                  <label class="control-label">Model</label>
                  <input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option2">
                </div>
              </div>
            </div>
          </div>
          <a @click="addNewRules" style="background-color:green">Add Another Rule</a>
        </div>

查看更多
登录 后发表回答