web2app-spa
Version:
This template is primarily designed to easily convert HTML pages and URLs into a Capacitor/Cordova based iOS/Android app that can be used as Single-page application (SPA).
383 lines (296 loc) • 12.8 kB
HTML
<html>
<head>
<title>To-do list app</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="basic/basic.min.css">
<script src="basic/basic.min.js" type="text/javascript" charset="utf-8"></script>
<script>
/*
TO-DO LIST APP (FOR MOBILE):
- An application that keeps a to-do list.
- When the application is closed, the information is stored in local storage.
Handbook: https://bug7a.github.io/basic.js-handbook/
This template, can be used to develop mobile applications with:
- Apache Cordova Framework or
- Ionic/Capacitor Native Runtime.
*** USAGE WITH CORDOVA FRAMEWORK:
CREATE APP DOCUMENTS:
https://cordova.apache.org/docs/en/latest/guide/cli/index.html
TUTORIAL VIDEOS:
- How to make an Android application? (Language: Turkish)
https://www.youtube.com/watch?v=B6x7yKhKZbY
- How to make an iOS application? (Language: Turkish)
https://www.youtube.com/watch?v=WZZwiI_5WQA
SETTINGS FOR YOUR CORDOVA PROJECT:
- Add these settings to your cordova project config.xml file:
<preference name="DisallowOverscroll" value="true" />
<preference name="Orientation" value="portrait" />
PLUGIN LIST:
https://cordova.apache.org/plugins/
*** USAGE WITH IONIC / CAPACITOR NATIVE RUNTIME:
CREATE APP DOCUMENTS:
https://capacitorjs.com/docs/getting-started
TUTORIAL VIDEOS:
- How to make an Android and iOS application?
https://youtu.be/rx-z6-_FwU8
SETTINGS FOR CAPACITOR PROJECT:
- Set "bundledwebRuntime": true in "capacitor.config.json" file.
Then Capacitor will create a "capacitor.js" file.
PLUGIN LIST:
https://capacitorjs.com/docs/apis
PLUGIN USAGE:
- Just add "Capacitor.Plugins." before plugin name.
NOTE: Because it doesn't work as a module.
EXAMPLE CODE:
const showConfirm = async () => {
const { value } = await Capacitor.Plugins.Dialog.confirm({
title: 'Confirm',
message: `Are you sure you'd like to press the red button?`,
});
console.log('Confirmed:', value);
};
showConfirm();
NOTE: Dont forget to install the Dialog plugin to test example code: npm install @capacitor/dialog
*/
const USED_WIDTH = 500
const MAX_ZOOMABLE_WIDTH = 700
let taskList = []
let taskDataList = []
// BOX: Container box of home content.
let homePage
// Shortcut names for frequently used objects.
let txtNewTask
let lblSelectedCount
// First running function.
const start = function() {
// Support all resolutions.
page.fit(USED_WIDTH, MAX_ZOOMABLE_WIDTH)
// Restore saved information.
loadTaskDataList()
// UI: HOME PAGE:
// BOX: Container box of home content. Parameters: left, top, width, height.
homePage = createBox()
that.width = USED_WIDTH
that.height = getDefaultContainerBox().height
that.color = "white"
that.top = 0
that.center("left")
// UI: ADD NEW TASK:
// BOX: Container box for adding new task.
homePage.boxNewTask = createBox(10, 10, 480, 80)
homePage.add(that)
that.color = "whitesmoke"
that.border = 0
that.round = 16
// TEXTBOX: Where the new task is written.
homePage.boxNewTask.txtNewTask = createTextBox(20, 15, 380)
homePage.boxNewTask.add(that)
that.minimal = 1
that.color = "transparent"
that.inputElement.setAttribute("placeholder", "Add a task")
that.inputElement.addEventListener("change", addTask);
//that.onChange(addTask)
// Set shortcut name.
txtNewTask = homePage.boxNewTask.txtNewTask
// LABEL: Add new task label button.
homePage.boxNewTask.lblAddButton = createLabel()
homePage.boxNewTask.add(that)
that.text = "+"
that.textAlign = "center"
that.color = "#23BCC1BB"
that.textColor = "rgba(255, 255, 255, 0.95)"
that.height = 50
that.width = that.height
that.fontSize = 36
that.round = 25
that.aline(txtNewTask, "right", 5)
that.onClick(addTask)
// UI: TASK ITEMS:
// BOX: Scrollable container box of task items.
homePage.boxTaskItemList = createBox(10, 100, 480, getDefaultContainerBox().height - 110)
homePage.add(that)
that.color = "white"
that.border = 0
that.scrollY = 1
// UI: DELETE TASKS:
// BOX: Container box for delete tasks.
homePage.boxDeleteTask = createBox(10, 10, 480, 80)
homePage.add(that)
that.color = "whitesmoke"
that.round = 16
that.visible = 0
// BOX: Background box for delete image.
homePage.boxDeleteTask.boxBackground = createBox(0, 0, 55, 55)
homePage.boxDeleteTask.add(that)
that.color = "#ED6D5230"
that.round = 30
that.center()
that.onClick(removeSelectedTasks)
// IMAGE: Delete image.
homePage.boxDeleteTask.boxBackground.imgDelete = createImage(0, 0, 35, 35)
homePage.boxDeleteTask.boxBackground.add(that)
that.load("assets/todo-app/trash.svg")
that.opacity = 0.9
that.center()
// LABEL: Count of selected items on delete image.
homePage.boxDeleteTask.lblCount = createLabel()
homePage.boxDeleteTask.add(that)
that.left = homePage.boxDeleteTask.boxBackground.left + 41
that.top = homePage.boxDeleteTask.boxBackground.top - 4
that.width = "auto"
that.height = "auto"
that.color = "white"
that.text = "0"
that.textColor = "#141414"
that.fontSize = 16
that.spaceY = 2
that.spaceX = 7
that.border = 1
that.borderColor = "#141414"
that.element.style.fontFamily = "opensans-bold"
that.round = 50
that.opacity = 0.7
// Set shortcut name.
lblSelectedCount = homePage.boxDeleteTask.lblCount
// When page reopens, create old records.
refreshTasks()
// Run each time the page size changes.
page.onResize(resizeHomePage)
}
const resizeHomePage = function() {
page.fit(USED_WIDTH, MAX_ZOOMABLE_WIDTH)
homePage.height = getDefaultContainerBox().height
homePage.boxTaskItemList.height = getDefaultContainerBox().height - 110
homePage.center("left")
}
const addTask = function() {
const taskText = txtNewTask.text
if (taskText != "") {
addTaskItem(taskText)
addTaskData(taskText)
txtNewTask.text = ""
}
}
// Clear all tasks and recreate based on data list.
const refreshTasks = function() {
// Clear all tasks.
taskList = []
homePage.boxTaskItemList.html = ""
for (let i = (taskDataList.length - 1); i >= 0; i--) {
addTaskItem(taskDataList[i])
}
}
// Add new task item object.
const addTaskItem = function(taskText) {
const newItem = createTaskItem(taskText)
homePage.boxTaskItemList.add(newItem)
taskList.unshift(newItem)
// After the automatic size calculation is complete, reposition the objects.
newItem.lblText.onResize(repositionTasks)
// NOTE: .onResize() has been added for each item of the tasks;
// when a task's text changes size, all tasks are repositioned.
}
// Add new task data.
const addTaskData = function(taskText) {
taskDataList.unshift(taskText)
saveTaskDataList()
updateBarBudgeCallback()
}
// Create new task item object.
const createTaskItem = function(taskText) {
// BOX: Task item container box.
const box = createBox(0, 0, 480, 100)
that.color = "white"
that.round = 4
that.onClick(selectTask)
// Let vertical position change be with motion.
that.setMotion("top 0.2s")
// LABEL: Task text.
box.lblText = createLabel(50, 10, 410, "auto")
box.add(that)
that.color = "transparent"
that.text = taskText
// BOX: Selection circle.
box.boxTick = createBox(15, 15, 20, 20)
box.add(that)
that.round = 10
that.border = 1
that.color = "whitesmoke"
that.borderColor = "lightgray"
// Define a variable inside the object.
box.isSelected = 0
makeBasicObject(box)
return box
}
const selectTask = function(clickedTask) {
// If item is selected:
if (clickedTask.isSelected) {
// Unselect it.
clickedTask.isSelected = 0
clickedTask.boxTick.color = "whitesmoke"
clickedTask.boxTick.border = 1
clickedTask.lblText.textColor = basic.TEXT_COLOR
lblSelectedCount.text = num(lblSelectedCount.text) - 1
} else {
// Select it.
clickedTask.isSelected = 1
clickedTask.boxTick.color = "tomato"
clickedTask.boxTick.border = 0
clickedTask.lblText.textColor = "tomato"
lblSelectedCount.text = num(lblSelectedCount.text) + 1
}
// Show/hide delete task box by selected count.
if (num(lblSelectedCount.text) > 0) {
homePage.boxDeleteTask.visible = 1
} else {
homePage.boxDeleteTask.visible = 0
}
}
const removeSelectedTasks = function() {
let newTaskDataList = []
let newTaskList = []
for (let i = 0; i < taskList.length; i++) {
// If item is selected:
if(taskList[i].isSelected) {
// Remove it.
taskList[i].remove()
} else {
// Add it to the new list.
newTaskDataList.push(taskDataList[i])
newTaskList.push(taskList[i])
}
}
taskDataList = newTaskDataList
taskList = newTaskList
saveTaskDataList()
updateBarBudgeCallback()
repositionTasks()
// Clean and hide delete task box.
lblSelectedCount.text = "0"
homePage.boxDeleteTask.visible = 0
}
const saveTaskDataList = function() {
storage.save("todoApp-taskDataList", taskDataList)
}
const loadTaskDataList = function() {
taskDataList = storage.load("todoApp-taskDataList") || []
}
// Because object positioning uses the coordinate system.
const repositionTasks = function() {
let top = 0
for (let i = 0; i < taskList.length; i++) {
taskList[i].top = top
taskList[i].height = taskList[i].lblText.height + 20
top += taskList[i].height
}
}
const updateBarBudgeCallback = function() {
if (window.top.updateBottomBarTasksUIBudge) window.top.updateBottomBarTasksUIBudge(taskList.length || 0);
}
</script>
</head>
<body>
</body>
</html>