Home > database >  disable current selection until some value is inputed in the previous selection
disable current selection until some value is inputed in the previous selection

Time:10-14

I'm working with BootstrapVue.

I have following problem. I have a b-form-input where I'm searching for my number over my b-form-select. So I'm selecting 3 values and get a number in my input field and other way around - so it's an Autofill.

This works fine - and because of that I think I don't need to show you the code.

The problem is that I want to disable all selects (instead of the first) till the field before was selected.

I have problem that if I have multiple elements all will be updated. So if I input something in Input1 in the first element the second Input of all other elements will be !disabled

Additional Info: IDParent is a prop!

If you need any additional code, I can update my question!

<template>
  <div>
    <div class="mt-2" v-for="(IDChild, indexChild) in inputs" :key="indexChild">
      <div>
        <div class="mt-2">Number</div>
        <b-form-input type="number" v-model="IDChild.Number" :value="IDChild.Number"></b-form-input>
      </div>

      <div>
        <div class="mt-2">Input 1</div>
        <b-form-select v-model="IDChild.Input1" :value="IDChild.Input1" :options="optionsInput1" @input="searchNumber(IDChild, IDParent, indexChild)"></b-form-select>
      </div>
      <div>
        <div class="mt-2">Input 2</div>
        <b-form-select :disabled="disabledInput2" v-model="IDChild.Input2" :value="IDChild.Input2" :options="optionsInput2" @input="searchNumber(IDChild, IDParent, indexChild)"></b-form-select>
      </div>
      <div>
        <div class="mt-2">Input 3</div>
        <b-form-select :disabled="disabledInput3" v-model="IDChild.Input3" :value="IDChild.Input3" :options="optionsInput3" @input="searchNumber(IDChild, IDParent, indexChild)"></b-form-select>
      </div>
    </div>

    <!-- add new element when button was clicked -->
    <div class="mt-4 mb-5 ml-3 mr-3">
      <b-button @click="addElement"> Add Element </b-button>
    </div>
  </div>
</template>  

my script:

<script>
import json from "./json/json.json";

export default {
  name: "Test",

  methods: {
    addElement() {
      this.inputs.push({});
    },

    searchNumber(input, IDParent, indexChild) {
      input.Number = "";

      this.json.forEach((element) => {
        if (
          element.Input1 == input.Input1 &&
          element.Input2 == input.Input2 &&
          element.Input3 == input.Input3 
        ) {
          for (const key of Object.keys(element)) {
            input[key] = element[key];
          }
        }
      });

      if(input.Input1) {
        this.disabledInput2 = false;
      }
      if(input.Input2) {
        this.disabledInput3 = false;
      }
    },
  },

  props: [
    "IDParent",
    ],

  data() {
    return {
      inputs: [{}],
      json: json,
      disabledInput2: true,
      disabledInput3: true,
    };
  },
};
</script>

CodePudding user response:

What you are missing is a multi-layer model for your data which you can call in your searchNumber function and call for your :disabled attribute.

In your v-for="(IDChild, indexChild) in inputs" you could use IDChild or indexChild for that. For example you would call :disabled="disabledInput2[indexChild]". That way you would refer to disabledInput2 with the specific indexChild.

You also need to handle this in your function, for example this.disabledInput2[indexChild] = false;.

Basically it´s the same as storing multi-layer data in the same object with v-model. Let me know, if this helped you.


EDIT: Generally Example

I´ve created the following properties for this example. We have myNumberInput as an object to handle multiple input fields for numbers. mySelectionData provides a simple collection of two objects with 3 selection arrays each. myDisableData is the object that will handle multiple disabled attributes for this selections:

    myNumberInput: {},
    mySelectionData: {
        1: {
            1: [
                { name: "1A", value: 1 }, { name: "2A", value: 2 }, { name: "3A", value: 3 }
            ],
            2: [
                { name: "4A", value: 4 }, { name: "5A", value: 5 }, { name: "6A", value: 6 }
            ],
            3: [
                { name: "7A", value: 7 }, { name: "8A", value: 8 }, { name: "9A", value: 9 }
            ]
        },
        2: {
            1: [
                { name: "1B", value: 11 }, { name: "2B", value: 21 }, { name: "3B", value: 31 }
            ],
            2: [
                { name: "4B", value: 41 }, { name: "5B", value: 51 }, { name: "6B", value: 61 }
            ],
            3: [
                { name: "7B", value: 71 }, { name: "8B", value: 81 }, { name: "9B", value: 91 }
            ]
        }
    },
    myDisableData: {}

From the mySelectionData object, we will build our myDisableData with this function:

setupMyDisableData() {
      Object.keys(this.mySelectionData).forEach(parent_key => {
        Object.assign(this.myDisableData, {[parent_key]: {}})
        Object.keys(this.mySelectionData[parent_key]).forEach(child_key => {
          Object.assign(this.myDisableData[parent_key], {[child_key]: true})
        });
      });
    }

This will loop trough our "parents", assign their index to myDisableData and also loop trough the "childs" and assign their index to myDisableData with the "parent"-index as a pointer. After that we have a multi-layer object which is able to provide diabled= true or false for each selection.

The html for this example looks like this:

<div v-for="(item,index) in mySelectionData" :key="index">
        <input type="number" v-model="myNumberInput[index]" @input="enableMySelection(index, myNumberInput[index])">
        <div v-for="(child_item, child_index) in item" :key="child_index">
          <select :disabled="myDisableData[index][child_index]">
            <option v-for="(child_option, child_option_index) in child_item" :key="child_option_index" :value="child_option.value">{{child_option.name}}</option>
          </select>
        </div>
      </div>

As I don´t use BootstrapVue, my html looks different, but I guess you will get the trick. You simply now refer to the three object by the index of "parent" and "child". In this example the function enableMySelection will enable a selection depending on the number entered in the input. The function looks like this:

enableMySelection(parent_index, input_number) {
      Object.keys(this.myDisableData[parent_index]).forEach(child_key => {
        this.myDisableData[parent_index][child_key] = true;
      });
      this.myDisableData[parent_index][input_number] = false;
    }

So if you enter "2" in your first input, it will enable the second selection of the first block. If you enter 1 in the second input, it will enable the first selection in the second block.

As I said, this is just a generally example but this should be enough to help you define the structure to handle your multiple inputs and selections.

  • Related