Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ajsmith_codes's avatar

Vue js - add selection dynamically to form.

I would like to do something like this with a dropdown. Is it possible? I can't get it to work.

Original Code from https://jsbin.com/sasulujado/edit?html,js,output

  • - {{ input.one }} - {{ input.two }} Delete
<button @click="addRow">Add row</button>

const app = new Vue({

el: '#app',

data: { inputs: [] },

methods: { addRow() { this.inputs.push({ one: '', two: '' }) }, deleteRow(index) { this.inputs.splice(index,1) } }

My attempt:

{{ order.number }}
  </select>

  <button
 @click.prevent="deleteRow(index)">
        Delete
       </button>

         <button
        @click.prevent="addOption">
         Add
         SO
          </button>
0 likes
16 replies
MarianoMoreyra's avatar

Hi @ajsmith_codes

I'm sorry, I don't understand your question. The example provided isn't working so I don't know if that's the code you are trying to make it work or if it's a broken example.

Also please, fix the back ticks of your post so we can see the code properly formatted.

Thanks!

ajsmith_codes's avatar

Darnit! I always have trouble with the formatting.

I will work on that and getting the example working.

gitwithravish's avatar

Your code was incorrect. I fixed it. You were saving the data as input variable, but trying to access it using options variable.

HTML ✅

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <div id="app">
    

      <select v-for="(option,index) in options">
        <option type="text" v-model="option.one">123</option> 
        <option type="text" v-model="option.two">sss</option>
       
      </select>

     <button @click="deleteRow(index)">Delete</button>
    
    <button @click="addRow">Add row</button>
    
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
  
</body>
</html>

ES6 ✅

const app = new Vue({
  
  el: '#app',
  
  data: {
    options: []
  },
  
  methods: {
    addRow() {
      this.options.push({
      
        one: 'a',
        two: 'a'
      })
    },
    deleteRow(index) {
      this.options.splice(index,1)
    }
  }
})
ajsmith_codes's avatar

The code you are referencing was setup by someone else. I took it and got it to work. What I'm having trouble with is integrating it with an array in my vue.

Here is my current code:

<select v-model="order.one">
                                        <option
                                            v-for="(order, index) in salesOrders"
                                            >
                                           {{ order.number }}
                                        </option>

                                    </select>
                                    <button
                                        @click.prevent="deleteRow(index)">
                                        Delete
                                    </button>

                                    <button
                                        @click.prevent="addOption">
                                        Add
                                        SO
                                    </button>

salesOrders is populated via an ajax request.

EDIT: Forgot the code below:

    addOption() {
        this.salesOrders.push({
            one: '',
        })
    },

2nd EDIT:

    axios.get('/api/getOrders')
        .then(function (response) {
            this.salesOrders = response.data;
            // this.customer = response.data[0].id;
        }.bind(this));
ajsmith_codes's avatar

Please check it now and let me know if I'm missing something. :)

gitwithravish's avatar

How come you are using the order variable in <select v-model="order.one"> statement. Aren't you getting any errors in your console?

ajsmith_codes's avatar

I could use salesOrder instead. Does that make more sense?

gitwithravish's avatar

add selectedOrder variable

const app = new Vue({

	el: '#app',

	data: { 
		salesOrders: [],
		selectedOrder 
	},
	// other code

keep select statement like this.

<select v-model="selectedOrder">

So now whenever you will choose an option, the selectOrder variable will contain value of the selected option. Vue will automatically bind it for u :)

Docs

https://vuejs.org/v2/guide/forms.html#Select

ajsmith_codes's avatar

When I changed it, the errors went away, but the order I selected appended as a blank value at the end of the dropdown list.

I was trying to have another select populate below the first one where I can choose a second salesOrder to attach to my purchase order.

gitwithravish's avatar

Please share your entire code in one go. You are making it more confusing

ajsmith_codes's avatar
<template>

    <div
        id="new-purchase-order"
        class="left">

        <div
            class="container">

            <NewVendor
                :callMethod="updateVendors"></NewVendor>
            <div
                class="row mt-5">
                <div
                    class="col-sm-10 col-md-8 col-lg-6 mx-auto">
                    <div
                        class="card"
                    >
                        <div
                            class="card-header">
                            <h3 class="card-title text-left">
                                Add
                                Purchase
                                Order
                            </h3>

                        </div>
                        <!-- /.card-header -->
                        <div
                            class="card-body col-sm-11 mx-auto">

                            <!--                                TODO: Remove before launch-->
                            <div
                                v-if="this.errors">
                                <div
                                    class="ml-6 error">
                                    <ul class="list-unstyled">
                                        <li v-for="error in errors">
                                            {{
                                                error
                                            }}
                                        </li>
                                    </ul>
                                </div>
                            </div>


                            <form
                                @submit.prevent="addPurchaseOrder()">

                                <p class="text-danger text-left">
                                    Required
                                    fields
                                    are
                                    marked
                                    with
                                    an
                                    asterisk
                                    (*).</p>

                                <!--                                First Section-->
                                <div
                                    class="mb-3">

                                    <div
                                        class="form-group">

                                        <label
                                            class="col-form-label font-weight-bold"
                                            :class="{ 'text-danger' : this.errors.purchaseOrderNumber }">
                                            Purchase
                                            Order
                                            Number
                                            <span
                                                class="text-danger">*</span>
                                        </label>

                                        <div
                                            class="input-group">

                                            <input
                                                v-model="purchaseOrderNumber"
                                                name="purchaseOrderNumber"
                                                type="text"
                                                class="form-control"
                                                :class="{ 'border-danger' : this.errors.purchaseOrderNumber }">
                                        </div>
                                        <div
                                            class="text-danger">
                                            {{
                                                this.errors.purchaseOrderNumber
                                            }}
                                        </div>
                                    </div>


                                </div>

                                <div
                                    class="mb-3">

                                    <label

                                        class="col-form-label font-weight-bold">
                                        Sales
                                        Orders
                                    </label>

                                    <select
                                        v-model="selectedOrder.one">
                                        <option
                                            v-for="(salesOrder, index) in salesOrders"
                                        >
                                            {{
                                                salesOrder.number
                                            }}
                                        </option>

                                    </select>
                                    <button
                                        @click.prevent="deleteRow(index)">
                                        Delete
                                    </button>

                                    <button
                                        @click.prevent="addOption">
                                        Add
                                        SO
                                    </button>


                                </div>


                                <div
                                    class="mb-3">

                                    <div
                                        class="form-group">

                                        <label
                                            class="col-form-label font-weight-bold"
                                            :class="{ 'text-danger' : this.errors.vendor }">
                                            Vendor
                                            <span
                                                class="text-danger">*</span>
                                        </label>

                                        <div
                                            class="input-group">

                                            <select
                                                class='form-control'
                                                v-model='vendor'
                                                id="vendor"
                                                :class="{ 'border-danger' : this.errors.vendor }">

                                                <option
                                                    value=""
                                                    disabled>
                                                    Select
                                                    One
                                                </option>

                                                <option
                                                    v-for='vendor in vendors'
                                                    :value='vendor.id'
                                                >
                                                    {{
                                                        vendor.name
                                                    }}
                                                </option>
                                            </select>


                                        </div>
                                        <div
                                            class="text-danger">
                                            {{
                                                this.errors.vendor
                                            }}
                                        </div>

                                        <a href="#"
                                           type="button"
                                           class="btn custom-page-link font-sm"
                                           @click.prevent="$modal.show('new-vendor')">
                                            +
                                            Add
                                            New
                                            Vendor
                                        </a>
                                    </div>

                                </div>

                                <div
                                    class="mb-3">

                                    <label

                                        class="col-form-label font-weight-bold">
                                        Ship
                                        Date
                                    </label>
                                    <ul>
                                        <li v-for="(input, index) in inputs"
                                            class="pb-2">
                                            <input
                                                type="date"
                                                name="shipDate"
                                                v-model="input.one">

                                            <button
                                                @click="deleteRow(index)">
                                                Delete
                                            </button>
                                        </li>
                                    </ul>
                                    <button
                                        @click.prevent="addRow"
                                        class="btn btn-success">
                                        +
                                        Add
                                        Ship
                                        Date
                                    </button>

                                </div>

                                <div
                                    class="mb-3">

                                    <div
                                        class="form-group">

                                        <label
                                            class="col-form-label font-weight-bold">
                                            Date
                                            PO
                                            Sent
                                            to
                                            Vendor
                                        </label>

                                        <div
                                            class="input-group">

                                            <input
                                                v-model="date_sent"
                                                name="date_sent"
                                                type="date"
                                                class="form-control">
                                        </div>
                                    </div>


                                </div>

                                <div
                                    class="mb-3">

                                    <div
                                        class="form-group">

                                        <label
                                            class="col-form-label font-weight-bold">
                                            Date
                                            PO
                                            Confirmed
                                            by
                                            Vendor
                                        </label>

                                        <div
                                            class="input-group">

                                            <input
                                                v-model="po_confirmed_date"
                                                name="po_confirmed_date"
                                                type="date"
                                                class="form-control">
                                        </div>
                                    </div>


                                </div>


                                <div
                                    class="modal-footer">
                                    <button
                                        class="btn btn-primary"
                                        type="submit">
                                        Submit
                                    </button>
                                    <a href="/order-entry/salesorders"
                                       type="button"
                                       class="btn custom-page-link"
                                    >
                                        Cancel
                                    </a>


                                </div>
                            </form>

                        </div>

                        <!--                                card body-->

                    </div>
                </div>
            </div>

        </div>
    </div>

</template>
<script>
import NewVendor
    from "./NewVendor";

export default {
    components: {
        NewVendor
    },
    data() {
        return {
            errors: {},
            purchaseOrderNumber: '',
            vendors: [],
            vendor: '',
            date_sent: '',
            po_confirmed_date: '',
            inputs: [],
            shipDate: '',
            salesOrders: [],
            selectedOrder: []
        };
    },
    methods: {
        addPurchaseOrder(e) {
            if (this.purchaseOrderNumber && this.vendor) {
                axios.post('/purchasing/purchase-orders/create', {
                    number: this.purchaseOrderNumber,
                    vendor: this.vendor,
                    date_sent: this.date_sent,
                    po_confirmed_date: this.po_confirmed_date,
                    dates: this.inputs

                })
                    .then((response) => {
                        swal(
                            {
                                title: 'Created!',
                                text: 'Purchase Order has been created.',
                                type: 'success'
                            }
                        )
                            .then((ok) => {
                                if (ok) {
                                    window.location = response.data.redirect;
                                }
                            });
                    })
                    .catch(error => {
                        console.log(error)
                    });
            }
            this.errors = {};

            if (!this.purchaseOrderNumber) {
                this.errors.purchaseOrderNumber = 'Please enter a Purchase Order number.';
            }
            if (!this.vendor) {
                this.errors.vendor = 'Please choose a vendor.';
            }
        },
        addRow() {
            this.inputs.push({
                one: '',
            })
        },
        addOption() {
            this.selectedOrder.push({
                one: '',
            })
        },
        deleteRow(index) {
            this.inputs.splice(index, 1)
        },
        updateVendors: function () {
            axios.get('/api/updateVendors')
                .then(function (response) {
                    this.vendors = response.data;
                    this.vendor = response.data[0].id;
                }.bind(this));
        },

    },
    mounted() {
        axios.get('/api/getVendors')
            .then(function (response) {
                this.vendors = response.data;
                // this.customer = response.data[0].id;
            }.bind(this));
        axios.get('/api/getOrders')
            .then(function (response) {
                this.salesOrders = response.data;
                // this.customer = response.data[0].id;
            }.bind(this));
    },

};
</script>
Norbertho's avatar

so you can push a new row into dropdown but you cant delete it?

ajsmith_codes's avatar

Yes, but that's not what I'm trying to do. Sorry, I'm confusing everyone.

I need to have the user select a sales order, then another select will populate so they can choose a second sales order, or three or four, etc.

AndrykVP's avatar
AndrykVP
Best Answer
Level 2

If I understand correctly, you need to wrap your <select> in a <div v-for="">, and you need a new property to keep count of these selects:

Template:

<div class="mb-3">
    <label class="col-form-label font-weight-bold">Sales Orders</label>
    <div v-for="n in orderCount" :key="n">
        <select v-model="selectedOrders[n-1]">
            <option v-for="(salesOrder, index) in salesOrders" :key="index" :value="salesOrder.number">
                {{ salesOrder.number }}
            </option>
        </select>
        <button @click.prevent="deleteOption(n)">Delete</button>
    </div>
    <button @click.prevent="addOption">Add SO</button>
</div>

Script:

data() {
    return {
        selectedOrders: [],
        orderCount: 1,
    };
},
methods: {
    addOption() {
        this.orderCount += 1;
    },
    deleteOption(index) {
        this.selectedOrders.splice(index-1,1)

        this.orderCount -= 1;
    },
}

The selectedOrders property becomes a reactive array of values specified in the <option :value="salesOrder.number">. You'll probably need to adjust the rest of your script.

Please or to participate in this conversation.