2

I need help on populating some input fields on a form with Vue 3. When a user selects an option in my dropdown the form should output the necessary inputs. Instead it will show all inputs from every option.

Here is my select dropdown

<select
 v-model="selectedInverter"
 @change="onChange($event)" >
   <option
     v-for="(item, index) in options"
     :value="item.inverter"
     :key="index" >
       {{ item.inverter }}
   </option>
</select>

And here are my options

export default {
  name: "ExampleOptions",
  data() {
    return {
      address: "",
      stakeAddress: "",
      selectedInverter: null,
      addressError: "",
      apiKey: null,
      filteredOptions: "",
      options: [
        {
          inverter: "None",
          options: []
        },
        {
          inverter: "Eagle",
          options: [
            {
              name: "Cloud ID",
              value: null,
              description:
                "The Rainforest cloud id used to access your system data",
              type: "text",
              required: true
            },
            {
              name: "User",
              value: null,
              description: "The Rainforest cloud username",
              type: "text",
              required: true
            },
            {
              name: "Password",
              value: null,
              description: "The Rainforest cloud password",
              type: "password",
              required: true
            }
          ]
        },
        {
          inverter: "Efergy",
          options: [
            {
              name: "Token",
              value: null,
              description: "The Efergy token used to access your system data",
              type: "text",
              required: true
            },
            {
              name: "Power",
              value: null,
              description:
                "The Efergy power key, usually 'PWER' or 'PWER.1234' where 1234 is the sid",
              type: "text",
              required: true
            }
          ]
        }
      ]
    };
  },

And this is my codepen example: https://codepen.io/pistell/pen/BaJPjgq

As you can see all the dropdown examples are shown at all times. How can I get the ones selected in the dropdown to show? I'm also using Tailwind CSS if that makes a difference.

1 Answer 1

1

If I understood you correctly, try like following snippet:

new Vue({
  el: "#demo",
  data() {
    return {
      address: "",
      stakeAddress: "",
      selectedInverter: null,
      addressError: "",
      apiKey: null,
      filteredOptions: "",
      // TODO: Create a way to iterate over these values and populate the HTML elements that go along with each of these
      // https://stackoverflow.com/questions/43250578/vue-js-populate-new-selects-when-changing-the-main-one
      options: [
        {
          inverter: "None",
          options: []
        },
        {
          inverter: "Eagle",
          options: [
            {
              name: "Cloud ID",
              value: null,
              description:
                "The Rainforest cloud id used to access your system data",
              type: "text",
              required: true
            },
            {
              name: "User",
              value: null,
              description: "The Rainforest cloud username",
              type: "text",
              required: true
            },
            {
              name: "Password",
              value: null,
              description: "The Rainforest cloud password",
              type: "password",
              required: true
            }
          ]
        },
        {
          inverter: "Efergy",
          options: [
            {
              name: "Token",
              value: null,
              description: "The Efergy token used to access your system data",
              type: "text",
              required: true
            },
            {
              name: "Power",
              value: null,
              description:
                "The Efergy power key, usually 'PWER' or 'PWER.1234' where 1234 is the sid",
              type: "text",
              required: true
            }
          ]
        }
      ]
    };
  },
  computed: {
    computed_items() {
      const selected = this.selectedInverter;
      return this.options.filter((item) =>  item.inverter.includes(selected));
    }
  },
  methods: {
    async registerInverter() {
      this.addressError = this.address.length > 1 ? "" : "Not a valid address";
      if (!this.addressError) {
        await this.validateAddress();
        // Values to send to Firebase
        console.log({
          address: this.address,
          api_key: this.apiKey,
          date_registered: new Date().toUTCString(),
          inverter: this.selectedInverter,
          stake_address: this.stakeAddress
        });
      }
    },
    async validateAddress() {
      // Evaluate the address and check if its valid
      console.log(this.address);
      return this.address;
    },
    onChange(event) {
      this.selectedInverter = event.target.value;
    }
  }
})
.error {
  color: red;
  margin-top: 10px;
  font-size: 0.8rem;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div class="flex items-center justify-center">
    <div class="w-full max-w-md">
      <form
        class="bg-white shadow-lg rounded px-12 pt-6 pb-8 mb-4"
        @submit.prevent="registerInverter"
      >
        <!-- @csrf -->
        <div
          class="text-gray-800 text-2xl flex justify-center border-b-2 py-2 mb-4"
        >
          Register your Inverter
        </div>
        <div class="mb-4">
          <label
            class="block text-gray-700 text-sm font-normal mb-2"
            for="address"
          >
            Wallet Address
          </label>
          <input
            class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
            name="address"
            v-model="address"
            type="text"
            required
            autofocus
            placeholder="Input your address"
          />
          <div v-if="addressError" class="error">{{ addressError }}</div>
        </div>
        <div class="mb-4">
          <label class="block text-gray-700 text-sm font-normal" for="inverter">
            Inverter Model
          </label>
          <div class="inline-block relative w-full py-4 flex-1">
            <select
              class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
              v-model="selectedInverter"
              @change="onChange($event)"
            >
              <option
                v-for="(item, index) in options"
                :value="item.inverter"
                :key="index"
              >
                {{ item.inverter }}
              </option>
            </select>
            <div
              class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"
            >
              <svg
                class="fill-current h-4 w-4"
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 20 20"
                width="20px"
              >
                <path
                  d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
                />
              </svg>
            </div>
          </div>
        </div>
        <div class="mb-4">

          <div
            v-for="(item, index) in computed_items"
            :value="item.inverter"
            :key="index"
          >
            <h2>{{ item.inverter }}</h2>
            <div
              v-for="(item, index) in item.options"
              :value="item.name"
              :key="index"
            >
              <input
                class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline mt-1 mb-1"
                :name="item.name"
                :type="item.type"
                :required="item.required"
                :placeholder="item.description"
              />
            </div>
          </div>
        </div>
        <div class="registerButton">
          <button
            class="px-4 py-2 rounded text-white inline-block shadow-lg bg-blue-500 hover:bg-green-500 focus:bg-blue-700"
            type="submit"
          >
            Register
          </button>
        </div>
      </form>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.