├── .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 |
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 | }
--------------------------------------------------------------------------------