0

I am dynamically generating an HTML form with Vue. There is a New Employee button which, when clicked, appends a new form together with it's submit button to the page. The submit button calls a method which makes the field in the form read only. However when I click on any of the submit buttons it affects all the forms in the page. I want each button to be responsible for only it's own form. How do I achieve this?

This is my HTML page:

<!-- Index.html -->
<!DOCTYPE html>
<html>
<head>

<title>Form</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="crossorigin="anonymous">

</script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"> 
</script>
<script src="main.js"></script>
</head>
<body>


<div class="container" id="app">
 <button class="btn btn-success" style="margin-bottom: 15px; margin-top: 15px;"
 @click="addNewEmployeeForm"
>
    New Employee
 </button>

 <div class="panel panel-default" style="margin-bottom: 13px;">
    <div class="panel-body" v-for="(employee, index) in employees">

        <span class="pull-right" style="cursor: pointer;" @click="deleteEmployeeForm(index)">X</span>

        <h4>Add Employee (index: {{ index }} )</h4>

        <div class="employee-form">

            <form id="e-form" @submit.prevent="processForm">
                <div class="form-group">
                    <label for="inputName">Name</label>
                    <input type="text" class="form-control" placeholder="Name" v-model="employee.name" :readonly="readonly == 1 ? true : false">
                </div>
                <div class="form-group">
                    <label for="inputJob">Job</label>
                    <input type="text" class="form-control" placeholder="Job" v-model="employee.job" :readonly="readonly == 1 ? true : false">
                </div>
                <div class="form-group">
                    <label for="inputAbout">About</label>
                    <textarea class="form-control" cols="30" rows="10" placeholder="About" v-model="employee.about" :readonly="readonly == 1 ? true : false"></textarea>
                </div>

                <button class="btn btn-default">Submit</button>
            </form>

        </div>


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

</body>
</html>

And this is my JS file:

// Main.js
window.onload = function () {

var app = new Vue({
    el: '#app',
    data: {

        readonly: 0,
        employees: [
        {
            name: '',
            job: '',
            about: ''
        }
        ]
    },
    methods: {
        addNewEmployeeForm() {
            this.employees.push({
                name: '',
                job: '',
                about: ''
            })
        },
        deleteEmployeeForm( index ) {
            this.employees.splice(index, 1);
        },
        processForm: function() {
            this.readonly = (this.readonly + 1) % 2;
            //console.log({ name: this.employees[0].name, job: this.employees[0].job, about: this.employees[0].about });

        }
    }
});

}

1 Answer 1

1

Pass your employee object to the processForm method, and store the readonly flag per employee:

<form id="e-form" @submit.prevent="processForm(employee)">
....
<input type="text" class="form-control" placeholder="Name" v-model="employee.name" :readonly="employee.readOnly == 1 ? true : false">

...                


data: {
    employees: [
    {
        name: '',
        job: '',
        about: '',
        readOnly: false,
    }
    ]
},
addNewEmployeeForm() {
    this.employees.push({
        name: '',
        job: '',
        about: '',
        readOnly: false,
    })
},
processForm: function(employee) {
    employee.readonly = !employee.readonly;
    console.log({ name: employee.name, job: employee.job, about: employee.about });
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your reply. I tried this but it is not working. The forms do not become read only upon clicking submit on any of the forms
I see I made an capitalization typo in readOnly, can you confirm it is written like readOnly in the html?
I fixed the capitalization. I also removed readonly from the employees array and instead put it directly in the data object. I did a similar thing with the addNewEmployeeForm() method. It kind of works but in an unexpected way. Upon clicking the submit button, the fields are not disabled but if i move my cursor to any of the fields and type something it suddenly gets disabled.
You need the readonly in the employee array, as you want to make it readonly per employee, not everythin at once

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.