5

I learn vue.js and I created a basic form in HTML and CSS:

<!DOCTYPE HTML>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>                       
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/pl.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<link rel="stylesheet" href="https://dl.dropboxusercontent.com/s/ggg4zmxzjgz4i9b/style.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/css/bootstrap-datetimepicker.min.css" />
</head>
<body>
<div id="app">
<div class="col-xs-5" id="mail_div">
    <label for="mail">Mail:</label>
    <input v-model="mail" placeholder="E-mail adress:" type="text" class="form-control" id="mail">
</div>
<div class="col-xs-5" id="date_div">
    <label for="date">Date:</label>
    <div class='input-group date' id='datetimepicker1'>
    <input v-model="date" placeholder="Pick a date:" type='text' class="form-control" />
    <span class="input-group-addon">
        <span class="glyphicon glyphicon-calendar"></span>
    </span>
    </div>
</div>
<div class="col-xs-5" id="adress_div">
    <label for="adress">Adress:</label>
    <input v-model="adress" placeholder="Adress of the point:"type='text' class="form-control" id="adress">
</div> 
<div class="col-xs-5" id="company_div">
    <label for="company">Company:</label>
    <input v-model="company" placeholder="Company name:"type='text' class="form-control" id="company">
</div> 
<div class="col-xs-5" id="fliers_div">
    <label for="fliers">Number:</label>
    <input v-model="fliers" placeholder="Write the number:" type='number' class="form-control" id="fliers">   
</div>    
<div id="table">
<table class="table">
    <thead>
        <th scope="col">Mail</th>
        <th scope="col">Date</th>
        <th scope="col">Adress</th>
        <th scope="col">Company</th>
        <th scope="col">Number</th>
    </thead>
    <tbody>
        <tr>
          <th scope="row">{{ mail }}</th>
          <td>{{ date }}</td>
          <td>{{ adress }}</td>
          <td>{{ company }}</td>
          <td>{{ fliers }}</td>
        </tr>
    </tbody>
</table>
</div>
<div id="button">
    <div id="button_container_1">
        <button type="button" class="btn btn-primary">Add a row</button>
    </div>
    <div id="button_container_2">
        <button type="button" class="btn btn-success">Download</button>
    </div>
</div>
</div>


<script src="https://dl.dropboxusercontent.com/s/3cml0fff7nbfpot/script.js"></script>
<script type="text/javascript">

    $(function () {
        $('#datetimepicker1').datetimepicker({locale:'pl'});
    });

</script>
</body>

And here's my .js file, which is not doing a lot so far:

var app = new Vue({
 el: '#app',
 data: {
  mail:'',
  date:'',
  adress:'',
  company:'',
  fliers:''
}
})

This code updates the row of the table dynamically when I submit data. The effect I want to achieve should let me enter the data for more rows after pressing the blue button. How to do this using vue.js? I've found some tutorials for dynamic tables in vue.js, but I haven't been able to found easy to grasp solutions for my case.

Piotr Koller
  • 599
  • 3
  • 8
  • 17

3 Answers3

20

You should make the following changes:

  1. Declare an array in the data property (lets call it rowData)

  2. Declare a method in methods: (lets call it addItem)

  3. Inside the method, populate a javascript object from the attributes (mail, date, address)

  4. Push the object in the rowData array and clear the model attributes
var app = new Vue({
  el: '#app',
  data: {
    mail:'',
    date:'',
    adress:'',
    company:'',
    fliers:'',
    rowData:[] //the declared array
  },
  methods:{
    addItem(){
      var my_object = {
        mail:this.mail,
        date:this.date,
        adress:this.adress,
        company: this.company,
        fliers: this.fliers
      };
      this.rowData.push(my_object)

      this.mail = '';
      this.date = '';
      this.adress = '';
      this.company = '';
      this.fliers = '';
    }
  }
})
  1. Then update your html like this:
<tr v-for="item in rowData" >
  <th scope="row">{{ item.mail }}</th>
  <td>{{ item.date }}</td>
  <td>{{ item.adress }}</td>
  <td>{{ item.company }}</td>
  <td>{{ item.fliers }}</td>
</tr>

Every time you push a new object to the rowData array, VueJs will automatically detect and render a new row in the table.

Sovalina
  • 5,410
  • 4
  • 22
  • 39
gijoe
  • 1,159
  • 7
  • 7
  • Do you have an idea why it's not working in flask? When I open this as a localhost, I get "jinja2.exceptions.UndefinedError: 'item' is undefined" . – Piotr Koller Sep 07 '18 at 07:43
  • Unfortunately i do not use flask/python if you re referring to it. Maybe the use of this variable in javascript is already in use also in flask. Try to change the variable `item` to something else. e.x. `myrow` and all output expressions like `{{ item.mail }}` to `{{ myrow.mail }}` . But still this is an assumption. – gijoe Sep 07 '18 at 07:57
  • Probably some kind of conflict between Flask and V-For. I'll just ask another question. – Piotr Koller Sep 07 '18 at 08:12
  • Dear P-box please check this thread for a solution https://stackoverflow.com/questions/41082626/how-to-render-by-vue-instead-of-jinja – gijoe Sep 08 '18 at 12:35
  • how to create it in vue3 – Muhammad Muazzam Oct 04 '22 at 04:30
0

Basic things to use will be methods section in Vue object creation, v-for usage and @click action added to button.

<!DOCTYPE HTML>
<head>
    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>                       
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/js/bootstrap-datetimepicker.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/pl.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="https://dl.dropboxusercontent.com/s/ggg4zmxzjgz4i9b/style.css"/>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/css/bootstrap-datetimepicker.min.css" />
</head>
<body>
    <div id="app">
        <div class="col-xs-5" id="mail_div">
            <label for="mail">Mail:</label>
            <input v-model="current.mail" placeholder="E-mail adress:" type="text" class="form-control" id="mail">
        </div>
    <div class="col-xs-5" id="date_div">
    <label for="date">Date:</label>
    <div class='input-group date' id='datetimepicker1'>
        <input v-model="current.date" placeholder="Pick a date:" type='text' class="form-control" />
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-calendar"></span>
        </span>
    </div>
</div>
<div class="col-xs-5" id="adress_div">
    <label for="adress">Adress:</label>
    <input v-model="current.adress" placeholder="Adress of the point:"type='text' class="form-control" id="adress">
</div> 
<div class="col-xs-5" id="company_div">
    <label for="company">Company:</label>
    <input v-model="current.company" placeholder="Company name:"type='text' class="form-control" id="company">
</div> 
<div class="col-xs-5" id="fliers_div">
    <label for="fliers">Number:</label>
    <input v-model="current.fliers" placeholder="Write the number:" type='number' class="form-control" id="fliers">   
</div>    
<div id="table">
    <table class="table">
        <thead>
            <tr>
                <th scope="col">Mail</th>
                <th scope="col">Date</th>
                <th scope="col">Adress</th>
                <th scope="col">Company</th>
                <th scope="col">Number</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="el in arr">
                <td>{{ el.mail }}</td>
                <td>{{ el.date }}</td>
                <td>{{ el.adress }}</td>
                <td>{{ el.company }}</td>
                <td>{{ el.fliers }}</td>
            </tr>
        </tbody>
    </table>
</div>
<div id="button">
    <div id="button_container_1">
        <button type="button" class="btn btn-primary" @click="addCurrent">Add a row</button>
    </div>
    <div id="button_container_2">
        <button type="button" class="btn btn-success">Download</button>
    </div>
</div>
</div>


<script type="text/javascript">var app = new Vue({
  el: '#app',
  data: {
    current:{mail: '',
    date: '',
    adress:'',
    company:'',
    fliers:''},
    arr:[]
  },
  methods: {
    addCurrent() {
        this.arr.push(JSON.parse(JSON.stringify(this.current)));
    }
  }
})</script>
<script type="text/javascript">

    $(function () {
        $('#datetimepicker1').datetimepicker({locale:'pl'});
    });

</script>
</body>
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
Kamil Leis
  • 119
  • 7
0

You may want to check out these real examples. They have created something similar to yours.

HTML

<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>
<pre>{{messages | json}}</pre>

</div>

JS

 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;
}
}
});

Source JSFiddle

Raheel Khan
  • 464
  • 10
  • 12