Guest User

ToDo Single File Component Vue.js

a guest
Apr 4th, 2020
1,131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <template>
  2.   <body>
  3.   <div id="app">
  4.     <section class="todo-wrapper">
  5.       <h1 class="todo-title">{{ today.day }}<br>{{ today.date }}</h1>
  6.       <form @keydown.enter.prevent="">
  7.         <input type="text" class="input-todo" v-bind:class="{ active: new_todo }" placeholder="Improve Pull-Ups" v-model="new_todo" v-on:keyup.enter="addItem">
  8.         <div class="btn btn-add" v-bind:class="{ active: new_todo }"  @click="addItem">+</div>
  9.       </form>
  10.       <div v-if="pending.length > 0">
  11.         <p class="status busy">You have {{ pending.length }} pending item<span v-if="pending.length>1">s</span></p>
  12.         <transition-group name="todo-item" tag="ul" class="todo-list">
  13.           <li v-for="(item, index) in pending" v-bind:key="item.title">
  14.             <input class="todo-checkbox" v-bind:id="'item_' + item.id" v-model="item.done" type="checkbox">
  15.             <label v-bind:for="'item_' + item.id"></label>
  16.             <span class="todo-text">{{ item.title }}</span>
  17.             <span class="delete" @click="deleteItem(item)"></span>
  18.           </li>
  19.         </transition-group>
  20.       </div>
  21.  
  22.       <transition name="slide-fade">
  23.         <p class="status free" v-if="!pending.length" ><img src="https://nourabusoud.github.io/vue-todo-list/images/beer_celebration.svg" alt="celebration">All phyiscal goals achieved!</p>
  24.       </transition>
  25.  
  26.       <div v-if="completed.length > 0 && showComplete">
  27.         <p class="status">Completed tasks: {{ completedPercentage }}</p>
  28.         <transition-group name="todo-item" tag="ul" class="todo-list archived">
  29.           <li v-for="(item, index) in completed" v-bind:key="item.title">
  30.             <input class="todo-checkbox" v-bind:id="'item_' + item.id" v-model="item.done" type="checkbox">
  31.             <label v-bind:for="'item_' + item.id"></label>
  32.             <span class="todo-text">{{ item.title }}</span>
  33.             <span class="delete" @click="deleteItem(item)"></span>
  34.           </li>
  35.         </transition-group>
  36.       </div>
  37.       <div class="control-buttons">
  38.         <div class="btn btn-secondary" v-if="completed.length > 0" @click="toggleShowComplete"><span v-if="!showComplete">Show</span><span v-else>Hide</span> Complete</div>
  39.         <div class="btn btn-secondary" v-if="todoList.length > 0" @click="clearAll">Clear All</div>
  40.       </div>
  41.     </section>
  42.   </div>
  43.   </body>
  44. </template>
  45.  
  46. <script>
  47. import * as $ from "jquery";
  48. var collListItem;
  49.  
  50.     export default {
  51.         name: 'PhysicalGoals',
  52.         data() {
  53.             return {
  54.                 todoList: [
  55.                 ],
  56.                 new_todo: '',
  57.                 showComplete: false,
  58.             };
  59.         },
  60.         computed: {},
  61.         mounted() {
  62.             this.getTodos();
  63.         },
  64.         watch: {
  65.             todoList: {
  66.                 handler: function (updatedList) {
  67.                     localStorage.setItem('todo_list', JSON.stringify(updatedList));
  68.                 },
  69.                 deep: true
  70.             }
  71.         },
  72.         computed: {
  73.             pending: function () {
  74.               console.log("pending");
  75.               if (!this.todoList) {
  76.                 return [];
  77.               }
  78.               return this.todoList.filter((item) => !item.done);
  79.             },
  80.             completed: function () {
  81.               console.log("completed");
  82.               if (!this.todoList) {
  83.                 return [];
  84.               }
  85.               return this.todoList.filter((item) => item.done);
  86.             },
  87.             completedPercentage: function () {
  88.               console.log("completedPercentage")
  89.                 // return (Math.floor((this.completed.length / this.todoList.length) * 100)) + "%";
  90.             },
  91.             today: function () {
  92.                 var weekday = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  93.                 var today = new Date();
  94.                 var dd = today.getDate();
  95.                 var mm = today.getMonth() + 1; //January is 0!
  96.                 var yyyy = today.getFullYear();
  97.  
  98.                 if (dd < 10) {
  99.                     dd = '0' + dd
  100.                 }
  101.  
  102.                 if (mm < 10) {
  103.                     mm = '0' + mm
  104.                 }
  105.  
  106.                 today = {
  107.                     day: weekday[today.getDay()],
  108.                     date: mm + '-' + dd + '-' + yyyy,
  109.                 }
  110.  
  111.                 return (today);
  112.             }
  113.         },
  114.         methods: {
  115.             getTodos() {
  116.               let siteUrl = 'https://site.sharepoint.com/sites/Playercard/';
  117.               var clientContext = new SP.ClientContext(siteUrl);
  118.               var oList = clientContext.get_web().get_lists().getByTitle('PhysicalGoals');
  119.               var camlQuery = new SP.CamlQuery();
  120.               var playerID = this.$store.state.selectedPlayer.ID;
  121.               console.log("playerID getTodos: " + playerID);
  122.               camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'playerID\'/>' +
  123.                       '<Value Type=\'Text\'>'+playerID+'</Value></Eq></Where></Query></View>');
  124.  
  125.               collListItem = oList.getItems(camlQuery);
  126.               clientContext.load(collListItem);
  127.  
  128.               clientContext.executeQueryAsync(
  129.                       Function.createDelegate(this, this.onQuerySucceededNew),
  130.                       Function.createDelegate(this, this.onQueryFailedNew)
  131.               );
  132.             },
  133.             onQuerySucceededNew(){
  134.               console.log("onQuerySucceededNew!");
  135.               var listItemEnumerator = collListItem.getEnumerator();
  136.  
  137.               while (listItemEnumerator.moveNext()) {
  138.                 var oListItem = listItemEnumerator.get_current();
  139.                 this.todoList = oListItem.get_item('Title');
  140.                 console.log("this.todoList: " + this.todoList);
  141.               }
  142.               console.log("this.todoList: " + this.todoList);
  143.               console.log("this.todoList.toString(): " + this.todoList.toString());
  144.               console.log("this.todoList.length): " + this.todoList.length);
  145.  
  146.             },
  147.             onQueryFailedNew(){
  148.               console.log('Request failed. ' + args.get_message() +
  149.                       '\n' + args.get_stackTrace());
  150.             },
  151.             // add a new item
  152.             addItem() {
  153.               var siteUrl = 'https://site.sharepoint.com/sites/Playercard/';
  154.  
  155.               var clientContext = new SP.ClientContext(siteUrl);
  156.               var oList = clientContext.get_web().get_lists().getByTitle('PhysicalGoals');
  157.  
  158.               var itemCreateInfo = new SP.ListItemCreationInformation();
  159.               var oListItem = oList.addItem(itemCreateInfo);
  160.  
  161.               var playerID = this.$store.state.selectedPlayer.ID;
  162.               var playerName = this.$store.state.selectedPlayer.Name;
  163.  
  164.               console.log("playerID: " + playerID);
  165.               console.log("playerName: " + playerName);
  166.               console.log("Title: " + this.new_todo);
  167.  
  168.               oListItem.set_item('Title', this.new_todo);
  169.               oListItem.set_item('playerID', playerID);
  170.               // oListItem.set_item('PlayerName', playerName);
  171.  
  172.               oListItem.update();
  173.  
  174.               clientContext.load(oListItem);
  175.  
  176.               clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
  177.                 // validation check
  178.                 if (this.new_todo) {
  179.                     this.todoList.unshift({
  180.                         id: this.todoList.length,
  181.                         title: this.new_todo,
  182.                         done: false,
  183.                     });
  184.                 }
  185.                 // reset new_todo
  186.                 this.new_todo = '';
  187.                 // save the new item in localstorage
  188.                 // return true;
  189.             },
  190.             deleteItem(item) {
  191.                 // this.todoList.splice(this.todoList.indexOf(item), 1);
  192.               let siteUrl = 'https://site.sharepoint.com/sites/Playercard/';
  193.               let clientContext = new SP.ClientContext(siteUrl);
  194.               let oList = clientContext.get_web().get_lists().getByTitle('PhysicalGoals');
  195.               var title = this.todoList[1];
  196.               var playerID = this.$store.state.selectedPlayer.ID;
  197.               console.log("playerID: " + playerID);
  198.  
  199.               let camlQuery = new SP.CamlQuery();
  200.  
  201.               camlQuery.set_viewXml('<View><Query><Where><And><Eq><FieldRef Name=\'Title\'/>' +
  202.                       '<Value Type=\'Text\'>'+title+'</Value></Eq><Eq><FieldRef Name=\'playerID\'/><Value Type=\'Text\'>'+playerID+'</Value></Eq></And></Where></Query></View>')
  203.  
  204.  
  205.               var collListItem = oList.getItems(camlQuery);
  206.               clientContext.load(collListItem);
  207.               console.log("collListItem: " + collListItem);
  208.  
  209.               // First we much execute the query to retrieve the items
  210.               clientContext.executeQueryAsync(()=> {
  211.                         // Now colListItem is a collection, we must iterate through it
  212.                         var listItemEnumerator = collListItem.getEnumerator();
  213.  
  214.                         while (listItemEnumerator.moveNext()) {
  215.                           var item = listItemEnumerator.get_current();
  216.                           // if we try item.deleteObject() the collection will be modified and it will throw an exception
  217.                           oList.getItemById(item.get_id()).deleteObject();
  218.                         }
  219.                         // Finally execute the delete statements
  220.                         clientContext.executeQueryAsync(
  221.                                 () => console.log('Item(s) deleted')),
  222.                                 () => console.log('Failed to delete item(s)');
  223.                       },
  224.                       ()=>console.log('Failed to retrieve items'));
  225.             },
  226.             toggleShowComplete() {
  227.                 this.showComplete = !this.showComplete;
  228.             },
  229.             clearAll() {
  230.                 this.todoList = [];
  231.             },
  232.             onQuerySucceeded: function(){
  233.               console.log("Succeeded!")
  234.             },
  235.  
  236.             onQueryFailed: function(sender, args){
  237.               console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
  238.             },
  239.         }
  240.     }
  241. </script>
  242.  
  243. <style scoped>
  244.   *{
  245.     box-sizing: border-box;
  246.   }
  247.  
  248.   body{
  249.     font-size: 15px;
  250.     font-family: 'Open Sans', sans-serif;
  251.     color: #444;
  252.     background-color: #fefefe;
  253.     background-image: linear-gradient(#fc6c48 0%, #ef5081 100%);
  254.     background-repeat: no-repeat;
  255.     background-size: cover;
  256.     padding: 50px 20px;
  257.     margin: 0;
  258.     min-height: 100vh;
  259.     position: relative;
  260.   }
  261.  
  262.   .todo-wrapper{
  263.     width: 600px;
  264.     max-width: 100%;
  265.     min-height: 500px;
  266.     margin: 20px auto 40px;
  267.     border: 1px solid #eee;
  268.     border-radius: 4px;
  269.     padding: 40px 20px;
  270.     -webkit-box-shadow: 0 0 15px 0 rgba(0,0,0,0.05);
  271.     box-shadow: 0 0 15px 0 rgba(0,0,0,0.05);
  272.     background-color: #f4f7fc;
  273.     overflow: hidden;
  274.     position: relative;
  275.   }
  276.  
  277.   .todo-title{
  278.     font-size: 1.2em;
  279.     color: #f65c65;
  280.     font-weight: normal;
  281.   }
  282.  
  283.   form{
  284.     overflow: overlay;
  285.   }
  286.  
  287.   form label{
  288.     display: block;
  289.     text-align: center;
  290.     font-size: 1.2em;
  291.   }
  292.  
  293.   .btn, input {
  294.     line-height: 2em;
  295.     border-radius: 3px;
  296.     border: 0;
  297.     display: inline-block;
  298.     margin: 15px 0;
  299.     padding: 0.2em 1em;
  300.     font-size: 1em;
  301.   }
  302.  
  303.   input[type='text'] {
  304.     border: 1px solid #ddd;
  305.     min-width: 80%;
  306.     transition: all ease-in 0.25s;
  307.   }
  308.  
  309.   input:focus{
  310.     outline: none;
  311.     border: 1px solid #a3b1ff;
  312.   }
  313.  
  314.   input::placeholder{
  315.     color: rgba(0,0,0,0.3);
  316.     font-style: italic;
  317.   }
  318.  
  319.   .btn{
  320.     text-align: center;
  321.     font-weight: bold;
  322.     cursor: pointer;
  323.     border-width: 1px;
  324.     border-style: solid;
  325.   }
  326.  
  327.   .btn-add {
  328.     background: #ddd;
  329.     color: #fefefe;
  330.     border-color: #ddd;
  331.     min-width: 17%;
  332.     pointer-events: none;
  333.     transition: all ease-in 0.25s;
  334.     font-size: 2.2em;
  335.     line-height: 0.5em;
  336.     padding: 0.3em 0.3em;
  337.     float: right;
  338.   }
  339.  
  340.   .btn-add.active{
  341.     background: #6664ff;
  342.     border-color: #6664ff;
  343.     pointer-events: visible;
  344.   }
  345.  
  346.   .btn-add.active:hover{
  347.     background: #4442f6;
  348.     border-color: #4442f6;
  349.   }
  350.  
  351.   .btn-add:active{
  352.     transform: scale(0.95);
  353.   }
  354.   .control-buttons{
  355.     position: absolute;
  356.     bottom: 20px;
  357.     left: 50%;
  358.     transform: translateX(-50%);
  359.     width: 100%;
  360.     text-align: center;
  361.   }
  362.   .btn-secondary{
  363.     display: inline-block;
  364.     position: relative;
  365.     border: 0;
  366.     padding: 0;
  367.     margin: 0 10px;
  368.   }
  369.  
  370.   .btn-secondary:after{
  371.     position: absolute;
  372.     content: '';
  373.     width: 0;
  374.     height: 3px;
  375.     background-color: #f4586e;
  376.     bottom: 0px;
  377.     left: 0;
  378.     transition: all ease-in 0.25s;
  379.   }
  380.  
  381.   .btn-secondary:hover:after{
  382.     width: 100%;
  383.   }
  384.  
  385.  
  386.   ul.todo-list{
  387.     padding: 0;
  388.     margin-bottom: 30px;
  389.   }
  390.  
  391.   ul.todo-list li{
  392.     position: relative;
  393.     list-style-type: none;
  394.     display: block;
  395.     margin: 10px 0;
  396.     background: #e0e8f5;
  397.     border-radius: 3px;
  398.     padding-left: 38px; /* custom checkbox width + 16 */
  399.     padding-top: 12px;
  400.     padding-bottom: 12px;
  401.     padding-right: 49px; /* delete button + 5 */
  402.     overflow: hidden;
  403.   }
  404.  
  405.   ul.todo-list.archived li{
  406.     background: #fff;
  407.   }
  408.  
  409.   .todo-text{
  410.     position: relative;
  411.     display: inline-block;
  412.     padding: 0 0.5em;
  413.   }
  414.  
  415.  
  416.   ul.todo-list li .delete{
  417.     position: absolute;
  418.     height: 100%;
  419.     top: 50%;
  420.     right: 0;
  421.     transform: translateY(-50%);
  422.     cursor: pointer;
  423.     opacity: 0;
  424.     width: 0;
  425.     background-color: #f56468;
  426.     color: #fff;
  427.     transition: all ease-in 0.25s;
  428.   }
  429.  
  430.   ul.todo-list li .delete:after{
  431.     position: absolute;
  432.     content: '';
  433.     width: 16px;
  434.     height: 16px;
  435.     top: 50%;
  436.     left: 50%;
  437.     background-image: url('https://nourabusoud.github.io/vue-todo-list/images/trash.svg');
  438.     background-repeat: no-repeat;
  439.     background-position: center;
  440.     background-size: contain;
  441.     transform: translate(-50%, -50%) scale(0.5);
  442.     transition: all ease-in 0.25s;
  443.   }
  444.  
  445.   ul.todo-list li:hover .delete{
  446.     width: 44px;
  447.     opacity: 1;
  448.   }
  449.  
  450.   ul.todo-list li:hover .delete:after{
  451.     transform: translate(-50%, -50%) scale(1);
  452.   }
  453.  
  454.   .todo-checkbox{
  455.     position: absolute;
  456.     opacity: 0;
  457.     display: none;
  458.   }
  459.  
  460.   .todo-checkbox + label {
  461.     position: absolute;
  462.     cursor: pointer;
  463.     left: 10px;
  464.     top: 50%;
  465.     transform: translateY(-50%);
  466.     width: 22px;
  467.     height: 22px;
  468.     border-radius: 2px;
  469.     border: 1px solid #cfdcec;
  470.     background-color: #fff;
  471.   }
  472.  
  473.   .todo-checkbox:checked + label:after{
  474.     position: absolute;
  475.     content: '';
  476.     top: 30%;
  477.     left: 50%;
  478.     height: 3px;
  479.     width: 6px;
  480.     border: solid #fc6c48;
  481.     border-width: 0 0 2px 2px;
  482.     transform-origin: center center;
  483.     transform: rotate(-45deg) translate(-50%, -50%);
  484.   }
  485.  
  486.   .todo-checkbox:checked + label:after{
  487.     display: block;
  488.   }
  489.  
  490.   .todo-checkbox:checked ~ .todo-text{
  491.     color: #888;
  492.     text-decoration: line-through
  493.   }
  494.  
  495.   .status.free{
  496.     font-weight: bold;
  497.     text-align: center;
  498.     margin: 40px 0;
  499.   }
  500.   .status.free img{
  501.     display: block;
  502.     width: 50px;
  503.     margin: 10px auto;
  504.     vertical-align: middle;
  505.   }
  506.  
  507.   .todo-item-enter-active, .todo-item-leave-active {
  508.     transition: opacity ease 0.25s, transform ease-in-out 0.3s;
  509.     transform-origin: left center;
  510.   }
  511.  
  512.   /* .todo-item-leave-active below version 2.1.8 */
  513.   .todo-item-enter, .todo-item-leave-to {
  514.     opacity: 0;
  515.     transform: translateX(100%);
  516.   }
  517.  
  518.  
  519.   .slide-fade-enter-active, .slide-fade-leave-active {
  520.     transition: all 0.3s ease;
  521.   }
  522.   /* .slide-fade-leave-active below version 2.1.8 */
  523.   .slide-fade-enter, .slide-fade-leave-to {
  524.     transform: scale(1.1);
  525.     opacity: 0;
  526.   }
  527.  
  528.  
  529.   /* Footer */
  530.   footer{
  531.     position: absolute;
  532.     width: 100%;
  533.     text-align: center;
  534.     color: #fff;
  535.     bottom: 20px;
  536.     left: 0;
  537.   }
  538.  
  539.   footer a{
  540.     color: #fff;
  541.   }
  542. </style>
Advertisement
Add Comment
Please, Sign In to add comment