Click here to Skip to main content
15,884,472 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have made a todo app in vue js.It works fine except the data which is submitted and displayed in the div is changeable even after submitting the form.I want the form to save the data permanently in that div.I have managed to display the data in the divs based on form selection.But it is not permanent after submission of the form.I have searched for the solution on many sites and forums.But unfortunately, I didn't find one.

I have used vuex for storing form data.

I have put the code in single page for easy running.

Thank You in Advance.

What I have tried:

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<head>
<title>--</title>
<style>
.main{
    display: flex;
    column-gap: 5px;
	background: #e7e7e7;
    background-size: cover;
    border: 15px solid #e7e7e7;
	height: 70vh;

}
.heading{
	background: #c2c8f1;
	width: 100%;
	text-indent: 10px;
}
.details{
    display: flex;
	flex-direction: column;
	width: 100%;
	row-gap: 5px;
}

.column{
    background: #d7d7d7;
	width: 100%;
	height: 100%;
}

.add{
    border: 1px solid #0479cbf7;
	border-radius: 5px;
	color: #0479cbf7;
	align-self: center;
	margin-left: auto;
	transition: 0.3s ease-in;
	background:transparent;
}

.add:hover{
    background: #0479cbf7;
	color: white;
	cursor: pointer;
}
.add:target{
    border: 1px solid transparent;
}

.tasks{
    display: flex;
}
.tasks h2{
    margin-top: auto;
}
#app{
    margin-left: auto;
}
.el-drawer__header{
    padding: 20px 10px;
	background: #eaeaea;
	font-weight: bold;
	font-size: 25px;
}

.drawer__footer{
    display: flex;
    justify-content: center;
	margin-left: 5px;
    margin-right: 5px;
}

.el-drawer__body>*{
	text-indent: 10px;
}
.el-form-item__content{
    display: grid;
}
.el-form-item__label{
    text-align: start;
}
.drawer{
    width: 45%!important;
	font-family: sans-serif;
}
.el-form-item{
    margin-right: 20px;
}
.el-drawer__close-btn, #el-drawer__title{
    display: none!important;
}
.close{
    float: right;
}
.close:before{
    content: '\00d7';
	cursor: pointer;
}
.el-message-box__btns{
    display: flex;
}
.el-date-editor--date,.el-date-editor--time{
    width: 100%!important;
}
.desc{
    margin-left: 10px;
    margin-right: 10px;	
}
.el-textarea__inner{
    min-height: 100px!important;
}
.card{
    background:white;
	border-left: 3px solid #00ca00;
	padding-left: 10px;
	width:  80%;
	margin-left:auto;
	margin-right: auto;
}
#card1{
    border-left: 3px solid #f0667f;
}
.card p:nth-child(1){
    font-size: 20px;
	font-weight: bold;
}
.card p:nth-child(2){
    color:blue;
	font-size: 19px;

}
.card p:nth-child(3){
    color:red;
}

.card p span:before{
    content: '\01F642';
	float:right;
	visibility:hidden;

}

</style>
</head>
<body>
<div class="page">
<div id="app">
<div class="tasks" style="margin-bottom:auto;">
<h2>My Tasks</h2>
<template>
<el-button class="add" @click="dialog = true">Add Task</el-button>
<el-drawer
  title="Add New Task"
  :visible.sync="dialog"
  :before-close="submitForm"
  direction="rtl"
  custom-class="drawer"
  ref="drawer"
  >
  <div class="el-drawer__header">
  <span role="heading" title="Add New Task">Add New Task</span>
  <div class="close" @click="cancelForm()"></div>
</div>
  <div class="drawer__content">
    <el-form :model="form" :rules="rules" ref="form" class="demo-ruleForm">
      <el-form-item label="Task Name" :label-width="formLabelWidth" prop="name" required>
        <el-input v-model="form.name" autocomplete="off" placeholder="please input"></el-input>
      </el-form-item>
	  <el-form-item label="Description" :label-width="formLabelWidth" class="desc">
      <el-input type="textarea" v-model="form.desc"></el-input>
      </el-form-item>
	  <el-form-item label="Account" :label-width="formLabelWidth" prop="account" required>
        <el-input v-model="form.account" autocomplete="off" placeholder="Type account name for remote search"></el-input>
      </el-form-item>
      <el-form-item label="Assigned To" :label-width="formLabelWidth" prop="assigned" required>
        <el-select v-model="form.assigned">
          <el-option label="team1" value="team1"></el-option>
          <el-option label="team2" value="team2"></el-option>
        </el-select>
      </el-form-item>
	  <el-form-item label="Status" :label-width="formLabelWidth" prop="status" required>
        <el-select id="target" v-model="form.status">
          <el-option label="to-do" value="to-do"></el-option>
          <el-option label="in-progress" value="in-progress"></el-option>
		  <el-option label="done" value="done"></el-option>
        </el-select>
      </el-form-item>
	  <el-form-item label="Priorty" :label-width="formLabelWidth" prop="priorty" required>
        <el-select v-model="form.priorty">
          <el-option label="high" value="high"></el-option>
          <el-option label="medium" value="medium"></el-option>
		  <el-option label="low" value="low"></el-option>
        </el-select>
      </el-form-item>
	  <el-form-item label="Due Date" :label-width="formLabelWidth" prop="date" required>
	  <el-date-picker
      v-model="form.date"
      type="date"
      placeholder="Pick a Date"
      format="yyyy/MM/dd">
	  </el-date-picker>
      </el-form-item>
	  <el-form-item label="Due Time" :label-width="formLabelWidth" prop="time" required>
	    <el-time-picker
        v-model="form.time"
        :picker-options="{
        selectableRange: '00:00:00 - 23:59:59'
        }"
        placeholder="Pick a time">
        </el-time-picker>
      </el-form-item>
    </el-form>
	<el-divider></el-divider>
    <div class="drawer__footer">
      <el-button @click="cancelForm()">Cancel</el-button>
      <el-button class="btn" type="primary" @click="submitForm('form')" :loading="loading">{{ loading ? 'Submitting ...' : 'Save' }}</el-button>
    </div>
  </div>
</el-drawer>
</template>
</div>
<section class="main">
<div class="details">
<div class="heading heading1">
<h4>To Do</h4>
</div>
<div class="column first">
 <div v-for="item in gettodoItems" class="card" id="card1">
     <p class="form-item">{{ item.name }}</p>
     <p class="form-item">{{ item.account }}</p>
     <p class="form-item">{{ item.date }}</p>
 </div>
</div>
</div>
<div class="details">
<div class="heading heading2">
<h4>In Progress</h4>
</div>
<div class="column second">
 <div v-for="item in gettodoItems1" class="card" id="card2">
     <p class="form-item">{{ item.name }}</p>
     <p class="form-item">{{ item.account }}</p>
     <p class="form-item">{{ item.date }}</p>
   </div>
</div>
</div>
<div class="details">
<div class="heading heading3">
<h4>Completed in last 30 days</h4>
</div>
<div class="column third">
 <div v-for="item in gettodoItems2" class="card" id="card3">
     <p class="form-item">{{ item.name }}</p>
     <p class="form-item">{{ item.account }}</p>
     <p class="form-item">{{ item.date }}</p>
 </div>
</div>
</div>

</section>
</div>
</div>
<script src="assets/vendor/jquery/js/jquery-3.6.0.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/element-ui/lib/umd/locale/en.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.2.0/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>
<script src="assets/vendor/element/js/form.js"></script>



<script>


ELEMENT.locale(ELEMENT.lang.en)

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    form: {
      name: '',
	  desc: '',
	  account: '',
	  assigned: '',
      status: '',
      priorty:'',
	  date: '',
	  time: ''
    },
	tasks: []
  },
  mutations: {
    ADD_ITEM(state, payload) {
      // mutate state
      state.tasks.push(payload)
    }
  },
  actions: {
    addItem ({ commit },payload) {
      commit('ADD_ITEM', payload)
    }
  },
  getters: {
	todoItems: state => {
      return state.tasks.filter(form => form.status === 'to-do')
    },
	todoItems1: state => {
      return state.tasks.filter(form => form.status === 'in-progress')
    },
	todoItems2: state => {
      return state.tasks.filter(form => form.status === 'done')
    }
  }
})


var Main = {
  data() {
    return {
      dialog: false,
      loading: false,
      form: {
        name: '',
		desc: '',
        account: '',
        assigned: '',
        status: '',
		priorty:'',
        date: '',
        time: ''
      },
	  rules: {
          name: [
            { required: true, message: 'Please input Task Name', trigger: 'blur' },
            { min: 3, max: 15, message: 'Length should be 3 to 5', trigger: 'blur' }
          ],
          account: [
            { required: true, message: 'Please input Account Name', trigger: 'change' }
          ],
          assigned: [
            { required: true, message: 'Please select Member Name', trigger: 'change' }
          ],
          status: [
            { required: true, message: 'Please Enter status', trigger: 'change' }
          ],
          priorty: [
            { required: true, message: 'Please select priorty', trigger: 'change' }
          ],
          date: [
            { type: 'date', required: true, message: 'Please pick a Date', trigger: 'change' }
          ],
          time: [
            { type: 'date', required: true, message: 'Please pick a time', trigger: 'change' }
          ]
        },
      formLabelWidth: '110px',
      timer: null,
    };
	
  },
  store,
  methods: {
      timeformat: function() {
	    this.form.date = moment(this.form.date).fromNow();
	  },
  
	  cancelForm() {
        this.dialog = false
        this.loading = false   
	    clearTimeout(this.timer);

      },
	  
      submitForm(formName) {
	    
        this.$refs[formName].validate((valid) => {
          if (valid) {
             this.$confirm('Do you want to submit?')
        .then(_ => {
          this.loading = true;
          this.timer = setTimeout(() => {
            // animation takes time
            setTimeout(() => {
			  alert('Form Submitted')
              this.loading = false;
			  this.dialog = false;
			  this.$store.dispatch('addItem', this.form)

            }, 400);
          }, 2000);
        })
        .catch(_ => {
         
		});	

          } else {
            console.log('error submit!!');
            return false;
          }
        });
      }
    },
	computed: {
     gettodoItems() {
        return this.$store.getters.todoItems
     },
	 gettodoItems1() {
        return this.$store.getters.todoItems1
     },
	 gettodoItems2() {
        return this.$store.getters.todoItems2
     }
    },
    watch: {
        form: function() {
            console.log(this.form)
        }
		}
}

var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')

</script>


</body>
</html>
Posted
Updated 14-Mar-21 9:14am
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900