Search code examples
vue.jsselectedprimevue

Condition on selected option doesn't work


I'm using PrimeVue Datatable to show my products, in case of updating a product, i want to show the values of the product to update in the modal inputs, including size and whether the product is included in the best selling list or no, the condition for selected size works fine, but it doesn't work for bestSelling, i made sure that form.bestSelling is either 1 or 0, but the :selected binding condition doesn't work:

Index.vue

<Column field="size" header="Size"></Column>

<Column header="Best Selling">
   <template #body="slotProps">
       <p>
         {{ slotProps.data.bestSelling == 1 ? "Yes": "No" }}
       </p>
   </template>
</Column>

UpdateProduct.vue

import { useForm } from "@inertiajs/vue3";
const props = defineProps(["product"]);

const form = useForm("UpdateProduct", {
    name: props.product.name,
    nameAr: props.product.nameAr,
    description: props.product.description,
    descriptionAr: props.product.descriptionAr,
    size: props.product.size,
    quantityPerPacket: props.product.quantityPerPacket,
    bestSelling: props.product.bestSelling,
});

onMounted(() => {
    form.reset();
});

<div class="field">
   <select v-model="form.size">
      <option :selected="form.size == 'Large'">Large</option> // works
      <option :selected="form.size == 'Medium'">Medium</option> // works
      <option :selected="form.size == 'Small'">Small</option> // works
   </select>
</div>

<div class="field">
  <select v-model="form.bestSelling">
    <option :selected="form.bestSelling == 1">Yes</option> // doesn't work
    <option :selected="form.bestSelling == 0">No</option> // doesn't work
  </select>
</div>

I even did this and the option says true if its yes:

<option>{{ form.bestSelling == 1 }}</option> // returns true

even if i do this, still will not be selected:

<option :selected="form.bestSelling == 1"> // won't be selected even if the condition is definitely true
 {{ form.bestSelling == 1 }} 
</option>

Solution

  • Instead of setting the selected attribute of <option>, set its value attribute and let Vue figure it out through the v-model on the <select>:

    <div class="field">
      <select v-model="form.bestSelling">
        <option :value="1">Yes</option>
        <option :value="0">No</option>
      </select>
    </div>
    

    Here it is in a snippet:

    const { createApp, ref } = Vue;
    
    const App = { 
      template: `  <div class="field">
        <select v-model="form.bestSelling">
          <option :value="1">Yes</option>
          <option :value="0">No</option>
        </select>
      </div>
      form.value is {{form.bestSelling}}
      `,
      data() {
        return {
          form: {bestSelling: 1}
        };
      }
    }
    const app = createApp(App)
    app.mount('#app')
    <div id="app"></div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

    Though for a binary value, you might be better off with a switch, a checkbox or radio buttons.