use the same form for create and read operation

2.9k views Asked by At

I have a master and a child component. The child component persists the data for the create mode as well as the edit mode. The child has a data section as follows which is being used when the component is in create mode

 data() {
            return {
                title: '',
                description: '',
                organizer: '',
                startdate: '',
                enddate: '',
                email: '',
                phone: ''
            }
        },

and my inputs in create mode are as follows

<input type="text" placeholder="enter event title here" class="form-control"  v-model="title">

In the edit mode, I am updating a prop value on the client as follows, which is

props:['currentevent']

The value of the currentevent is being passed from the master component to the child component and is also the value that is currently being edited.

so, the complete code for handling an input value looks like as follows

<input type="text" placeholder="enter event title here" class="form-control" v-if="currentevent" :value="currentevent.title">

<input type="text" placeholder="enter event title here" class="form-control" v-else v-model="title">

and in my save method (in the child component), I am checking if currentevent is empty or not. If it is empty then I trigger the add code otherwise, I trigger the update code.

Question : This works , but I have a large form and having to do this for each and every component is not a clean design . Can you please let me know what should I be doing ?

2

There are 2 answers

2
Rommel Santor On BEST ANSWER

I totally appreciate your predicament. The best way to handle form data is to make it create/update agnostic. Here's what I'd recommend you try:

Instead of maintaining all the data fields as disparate properties, contain them in a single object, in this case I'm calling it eventObj for clarity:

data () {
    return {
        eventObj: {}
    }
}

Then in your markup you'd reference them via the object:

<input type="text" placeholder="..." class="form-control" v-model="eventObj.title">

You'd then need to define a prop for passing in the data (as an object) from the parent component if you are editing:

props: {
    currentevent: Object
}

And then you'd just need to map the incoming prop to the child component's data:

created() {
    Object.assign(this.eventObj, this.currentevent || {})
}

Now when your inputs like <input v-model="eventObj.title"> are processed, if there is a saved title (that was passed in with currentevent) the field will be prepopulated with it, otherwise it will be blank.

I think this should help you in the right direction toward solving the complexity you're trying to figure out. There are other logistical issues involved with this kind of stuff in general, but I won't drone on. :)

0
Saurabh On

The issue I see is you want to remove the v-if/else in the form. I will recommend here is keep your local data of child to be in sync with the props passed and only use local variable in the form.

One way to do this can be put a watcher on props and whenever props changes, update local variables and only use those variables in form.

watch: {
   currentevent: function(newVal){
      title =  newVal.title,\
      description = newVal.description
      ...
   }
}