├── .babelrc ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── src ├── index.css └── index.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env" 4 | ] 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Twinkle Cats - Simple Task Manager 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |

Twinkle Cats - Simple Task Manager

23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 |
31 | 32 |
33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dom-project1", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack", 8 | "start": "webpack-dev-server" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "babel-core": "^6.26.3", 15 | "babel-loader": "^7.1.4", 16 | "babel-preset-env": "^1.7.0", 17 | "css-loader": "^0.28.11", 18 | "mini-css-extract-plugin": "^0.4.0", 19 | "webpack": "^4.8.3", 20 | "webpack-cli": "^2.1.3", 21 | "webpack-dev-server": "^3.1.4" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: 'Roboto Condensed', sans-serif; 3 | font-size: 16px; 4 | color: #222; 5 | } 6 | 7 | .single-task { 8 | min-height: 75px; 9 | padding: 5px; 10 | background: salmon; 11 | position: relative; 12 | margin-bottom: 10px; 13 | } 14 | 15 | .task-control-panel { 16 | width: 100%; 17 | min-height: 40px; 18 | background: rgba(0, 0, 0, 0.5); 19 | position: absolute; 20 | left: 0; 21 | bottom: 0; 22 | } 23 | 24 | .color-circle { 25 | width: 25px; 26 | height: 25px; 27 | border-radius: 50%; 28 | } 29 | 30 | .inner-textarea { 31 | resize: none; 32 | position: absolute; 33 | background: #ddd; 34 | box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.35); 35 | top: 0; 36 | left: 0; 37 | font-family: 'Roboto Condensed', sans-serif; 38 | font-size: 16px; 39 | padding: 5px; 40 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | 3 | 4 | window.onload = function() { 5 | 6 | const taskField = document.querySelector('#taskField') 7 | const addTaskBtn = document.querySelector('#addTaskBtn') 8 | const allTasksParent = document.querySelector('#allTasks') 9 | 10 | taskField.addEventListener('keypress', function(event) { 11 | if (event.keyCode === 13) { 12 | createNewTask(allTasksParent, event.target.value) 13 | this.value = '' 14 | } 15 | }) 16 | 17 | } 18 | 19 | function createNewTask(parent, task) { 20 | 21 | let col = create({'class': 'col-sm-3'}) 22 | 23 | let singleTask = create({'class': 'single-task d-flex'}) 24 | 25 | let singleTaskP = create('p') 26 | singleTaskP.innerHTML = task 27 | singleTask.appendChild(singleTaskP) 28 | 29 | let span = create('span', {'class': 'ml-auto'}) 30 | span.innerHTML = `` 31 | span.addEventListener('click', function() { 32 | parent.removeChild(col) 33 | }) 34 | singleTask.appendChild(span) 35 | 36 | let taskControler = createTaskController(singleTask) 37 | taskControler.style.visibility = 'hidden' 38 | singleTask.appendChild(taskControler) 39 | 40 | singleTask.onmouseenter = function() { 41 | taskControler.style.visibility = 'visible' 42 | 43 | } 44 | 45 | singleTask.onmouseleave = function() { 46 | taskControler.style.visibility = 'hidden' 47 | } 48 | 49 | col.appendChild(singleTask) 50 | parent.appendChild(col) 51 | 52 | } 53 | 54 | function createTaskController(parent) { 55 | let controlPannel = create({'class': 'task-control-panel d-flex align-items-center'}) 56 | 57 | let colorPallete = createColorPallete(parent) 58 | controlPannel.appendChild(colorPallete) 59 | 60 | let editBtn = createEditBtn(parent) 61 | controlPannel.appendChild(editBtn) 62 | 63 | return controlPannel 64 | } 65 | 66 | function createEditBtn(parent) { 67 | let span = create('span', {'class': 'ml-auto mr-2'}) 68 | span.innerHTML = `` 69 | span.style.color = '#fff' 70 | span.addEventListener('click', function() { 71 | 72 | let p = parent.querySelector('p') 73 | let textArea = create('textarea', {'class': 'inner-textarea'}) 74 | textArea.style.width = parent.offsetWidth + 'px' 75 | textArea.style.height = parent.offsetHeight + 'px' 76 | textArea.innerHTML = p.innerHTML 77 | 78 | textArea.addEventListener('keypress', function(event) { 79 | 80 | if (event.keyCode === 13) { 81 | 82 | event.stopPropagation() 83 | 84 | if (this.value) { 85 | p.innerHTML = this.value 86 | parent.removeChild(this) 87 | 88 | } else { 89 | alert ('Please Put Some Data') 90 | } 91 | } 92 | }) 93 | 94 | parent.appendChild(textArea) 95 | }) 96 | 97 | return span 98 | } 99 | 100 | function createColorPallete(parent) { 101 | const colors = ['palegreen', 'skyblue', 'powderblue', 'salmon', 'grey', 'red'] 102 | 103 | let colorDiv = create({'class': 'd-flex'}) 104 | 105 | colors.forEach(color => { 106 | let div = create({'class': 'color-circle ml-1'}) 107 | div.style.background = color 108 | div.addEventListener('click', function() { 109 | parent.style.background = color 110 | }) 111 | colorDiv.appendChild(div) 112 | }) 113 | 114 | return colorDiv 115 | } 116 | 117 | 118 | window.create = function () { 119 | 120 | if (arguments.length === 0) { 121 | return document.createElement('div'); 122 | } 123 | 124 | if (arguments.length === 1 && typeof arguments[0] != 'object') { 125 | return document.createElement(arguments[0]); 126 | } 127 | 128 | var tag = arguments[0]; 129 | var attr = arguments[1] || arguments[0]; 130 | 131 | if (arguments.length === 1 && typeof arguments[0] === 'object') { 132 | tag = 'div'; 133 | } 134 | 135 | var element = document.createElement(tag); 136 | 137 | for (var i in attr) { 138 | element.setAttribute(i, attr[i]); 139 | } 140 | 141 | return element; 142 | } 143 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | 4 | module.exports = { 5 | 6 | entry: './src/index.js', 7 | 8 | output: { 9 | filename: 'bundle.js', 10 | path: path.resolve(__dirname, 'dist'), 11 | publicPath: '/dist' 12 | }, 13 | 14 | mode: 'development', 15 | 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.js$/, 20 | use: 'babel-loader', 21 | exclude: /node_modules/ 22 | }, 23 | { 24 | test: /\.css$/, 25 | use: [MiniCssExtractPlugin.loader, 'css-loader'] 26 | } 27 | ] 28 | }, 29 | 30 | plugins: [ 31 | new MiniCssExtractPlugin({ 32 | filename: 'style.css' 33 | }) 34 | ] 35 | } --------------------------------------------------------------------------------