0
votes

I have to add/post data form. But the form dynamically can increase as user 'click' on a button. I've already browse about it and there some answer i get like using $request->all() to fetch all data from input forms.

And then my problem is, my app using VueJS as front-end. Is there any some configuration on VueJS script to post all data from that dynamic form??

My Blade template that will be increase dynamically:

<div id="form-message">
{!! Form::text('rows[0][DestinationNumber]', null, [
    'id' => 'recipient',
    'class' => 'form-control',
    'v-model' => 'newMessage.DestinationNumber'
    ])
!!}
{!! Form::textarea('rows[0][TextDecoded]', null, [
    'rows' => '3',
    'id' => 'recipient',
    'class' => 'form-control',
    'v-model' => 'newMessage.TextDecoded'
    ]) 
!!}
</div>

That zero number will increase depends on how much user click add button. And then here my VueJS script

var newSingleMessage = new Vue({
el: '#newsinglemsg',
data: {
    newMessage: {
        DestinationNumber: '',
        TextDecoded: ''
    },
},
methods: {
    onSubmitForm: function(e) {
        e.preventDefault();
        var message = this.newMessage;

        this.$http.post('api/outbox', message);
        message = { DestinationNumber: '', TextDecoded: '' };
        this.submitted = true;
    }
}

});

On laravel controller, i have simple logic to test result how data passed.

$input = $request->all();
$output = dd($input);
return $output;

And, I test it using 2 additional form. So, the data should be 3 rows. The result (checked from FireBug) to be like this

{"DestinationNumber":"1234567890","TextDecoded":"qwertyuio"}

Data passed just one, and then the type is JSON. Even I use return $output->toArray(), type still JSON.

Oh yeah, once more. Idk how to make the zero number increase dynamically using javascript. When testing, i just manual add the form. Here my add click function javascript

var i = 0,
clone = $('#form-message').clone(),
recipient = document.getElementById('recipient');
recipient.setAttribute('name', 'rows['+ i +'][DestinationNumber]');
clone.appendTo('.form-message:last');
i++;

For second and next rows, name attribute not added on the input elements. Thanks

1

1 Answers

3
votes

You're mixing blade and jquery and vue in a way that is pretty confusing. Check out this JS fiddle that accomplishes all of this with Vue:

https://jsfiddle.net/cr8vfgrz/10/

You basically have an array of messages that are automatically mapped to inputs using v-for. As those inputs change, your messages array changes. Then when submit is pressed, you just post this.messages and the array of messages is sent to server. Then you can clear the array to reset the form.

Template code:

<div id="form-message">
<button class="btn btn-default" @click="addNewMessage">New Message</button>
<template v-for="message in messages">
    <input type="text" v-model="message.DestinationNumber" class="form-control">
    <textarea rows="3" v-model="message.TextDecoded" class="form-control"></textarea>
</template>
<button class="btn btn-success" @click.prevent="submitForm">Submit</button>
</div>

Vue code:

var newSingleMessage = new Vue({
    el: '#form-message',
    data: {
        messages: [
            {
                DestinationNumber: '',
                TextDecoded: ''
            }
        ],
        submitted:false
    },
    methods: {
        addNewMessage: function(){
            this.messages.push({
                DestinationNumber: '',
                TextDecoded: ''
            });
        },
        submitForm: function(e) {
            console.log(this.messages);
            this.$http.post('api/outbox', {messages:this.messages})
            .then(function(response){
                //handle success
                console.log(response);
            }).error(function(response){
                //handle error
                console.log(response)
            });
            this.messages = [{ DestinationNumber: '', TextDecoded: '' }];
            this.submitted = true;
        }
    }
});

Edit:

In the controller you can use $request->input('messages'); which will be the array of messages. You can insert multiple new Outbox model using:

Outbox::insert($request->input('messages'));

or

foreach($request->input('messages') as $message){
    Outbox::create($message);
}