Advertisement
Guest User

ToDo Vue.js

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