-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
michaelsboost
committed
May 11, 2024
1 parent
d34bdf5
commit 4da4be0
Showing
2 changed files
with
20 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"version": "1.1.50", | ||
"settings": { | ||
"autoupdate": true, | ||
"console": true, | ||
"fontSize": "16" | ||
}, | ||
"title": "Todo App with JSON VDom", | ||
"description": "Made a simple to do app using a json based virtual dom. The styling is done in Pico CSS and tailwind css.", | ||
"meta": "", | ||
"libraries": [ | ||
"https://cdnjs.cloudflare.com/ajax/libs/picocss/2.0.6/pico.min.css", | ||
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css", | ||
"https://michaelsboost.com/TailwindCSSMod/tailwind-mod.min.js" | ||
], | ||
"markdown": "<fieldset role=\"group\">\n <input name=\"email\" type=\"email\" placeholder=\"Enter your email\" autocomplete=\"email\">\n <input type=\"submit\" value=\"Subscribe\">\n</fieldset>", | ||
"html": "<div id=\"app\" class=\"m-auto container\"></div>", | ||
"css": "", | ||
"javascript": "// Sample JSON virtual DOM structure for the todo app\nconst todoApp = {\n tag: 'div',\n attrs: { id: 'todo-app', class: 'p-4' },\n children: [\n {\n tag: 'fieldset',\n attrs: { id: 'input-container', role: \"group\" },\n children: [\n {\n tag: 'input',\n attrs: { type: 'text', placeholder: 'Add new todo', id: 'todo-input' },\n events: {\n keyup: function(event) {\n if (event.key === 'Enter') {\n addTodo();\n }\n }\n }\n },\n {\n tag: 'button',\n children: [{ tag: 'i', attrs: { class: 'fas fa-plus' } }],\n events: {\n click: function(event) {\n addTodo();\n }\n }\n }\n ]\n },\n {\n tag: 'div',\n attrs: { id: 'todo-list' },\n children: []\n }\n ]\n};\n\n// Function to render the JSON virtual DOM recursively\nfunction renderHTML(container, json) {\n // Clear existing content in the container element\n container.innerHTML = '';\n\n const renderElement = (json, parent) => {\n // Base case: if the JSON node has no tag, it's a text node\n if (!json.tag) {\n const textNode = document.createTextNode(json.text || '');\n parent.appendChild(textNode);\n return;\n }\n\n // Create the HTML element with tag\n const element = document.createElement(json.tag);\n\n // Add attributes to the element\n if (json.attrs) {\n for (const [key, value] of Object.entries(json.attrs)) {\n element.setAttribute(key, value);\n }\n }\n\n // Add text content if present\n if (json.text) {\n element.textContent = json.text;\n }\n\n // Add event listeners if present\n if (json.events) {\n for (const [eventName, eventHandler] of Object.entries(json.events)) {\n element.addEventListener(eventName, eventHandler);\n }\n }\n\n // Append the element to the parent\n parent.appendChild(element);\n\n // Add children elements recursively\n if (json.children) {\n for (const childJson of json.children) {\n renderElement(childJson, element);\n }\n }\n };\n\n // Render the element tree from the JSON structure\n renderElement(json, container);\n}\n\n// Function to add a new todo\nfunction addTodo() {\n const inputField = document.getElementById('todo-input');\n const text = inputField.value.trim();\n if (text !== '') {\n // Create the todo item JSON\n const todoItem = {\n tag: 'nav',\n attrs: { class: 'items-center -mt-4' },\n children: [\n {\n tag: 'input',\n attrs: { type: 'checkbox', role: 'switch' },\n events: {\n change: function(event) {\n // Update the value in the vDOM\n todoItem.children[0].attrs.checked = `${(event.target.checked) ? 'checked' : ''}`;\n }\n }\n },\n {\n tag: 'input',\n attrs: { type: 'text', class: 'm-4', value: text },\n events: {\n input: function(event) {\n // Update the value in the vDOM\n todoItem.children[1].attrs.value = event.target.value;\n }\n }\n },\n {\n tag: 'button',\n children: [{ tag: 'i', attrs: { class: 'fas fa-trash-alt' } }],\n events: {\n click: function(event) {\n const todoItem = event.target.closest('nav');\n const todoList = document.getElementById('todo-list');\n\n // Find index of the todo item\n const index = Array.from(todoList.children).indexOf(todoItem);\n\n // Remove todo item from the todoApp variable\n todoApp.children[1].children.splice(index, 1);\n\n // Remove todo item from the UI\n todoItem.remove();\n }\n }\n }\n ]\n };\n\n // Append the todo item to the todoApp's todo list\n todoApp.children[1].children.push(todoItem); // Assuming todo list is the second child\n\n // Re-render the todo app\n const appContainer = document.getElementById('app');\n renderHTML(appContainer, todoApp);\n\n inputField.value = '';\n }\n}\n\n\n// Rendering the todo app\nconst appContainer = document.getElementById('app');\nrenderHTML(appContainer, todoApp);" | ||
} |