Skip to content

Instantly share code, notes, and snippets.

@hmboyd
Created January 12, 2022 00:38
Show Gist options
  • Save hmboyd/055acc284dc901e2ebaa11e9e08b3ac3 to your computer and use it in GitHub Desktop.
Save hmboyd/055acc284dc901e2ebaa11e9e08b3ac3 to your computer and use it in GitHub Desktop.
// Import the sql() function from the backend package file to a web module. We’ll call our web module data.jsw.
import { sql } from '@velo/wix-data-sql-backend';
To get, insert, update, and remove tasks from the to-do list, include the following code in the file:
export async function getAllTasks(visitorId) {
try {
const results = await sql('SELECT _id, title, isComplete FROM MyTasks WHERE visitorId = "' + visitorId + '"');
return results.payload.data.rows;
} catch (error) {
console.error(error);
}
}
export async function insertTask(taskObj) {
try {
await sql('INSERT INTO MyTasks (title, isComplete, visitorId) values ("' + taskObj.title + '", false , "' + taskObj.visitorId + '")');
} catch (error) {
console.error(error);
}
}
export async function updateTask(taskID, newStatus) {
try {
await sql('UPDATE MyTasks SET isComplete = ' + newStatus + ' Where _id = "' + taskID + '"');
} catch (error) {
console.error(error);
}
}
// This function returns a promise to allow calling it several times without waiting for each call to complete.
export function removeTask(taskID) {
try {
const removePromise = sql('DELETE FROM MyTasks WHERE _id = "' + taskID + '"');
return removePromise;
} catch (error) {
console.error(error);
}
}
Add the following page elements to your site:
Text input for adding a task.
Button to trigger the addition.
Button to clear marked tasks.
Repeater with a task complete button and text for displaying the task.
Import the getAllTasks(), insertTask(), updateTask(),and removeTask()functions from the web module to your page code.
import { getAllTasks, insertTask, updateTask, removeTask } from 'backend/data';
Import the local() module from wix-storage.
import { local } from 'wix-storage';
Declare variables for a font style and size and the visitor ID.
const htmlFontFamily = `madefor-display`;
const htmlFontSize = `14px`;
let visitorId;
Initialize the repeater data and call the registerHandlers() and setVisitor() functions.
$w.onReady(function () {
$w('#repeater').data = [];
registerHandlers();
setVisitor();
});
When the repeater’s data is assigned and ready, display the task text retrieved from the database collection in each of the repeater’s items. If the task is complete, label the button in the repeater with an ‘X’ and call the changeCompleteStatus() function with the item and itemData.
function registerHandlers() {
$w('#repeater').onItemReady(($item, itemData) => {
$item('#taskTitle').text = itemData.title;
if (itemData.isComplete === true) {
$item('#taskCompleteButton').label = 'X';
}
getHTMLtag($item('#taskTitle'), itemData.isComplete);
$item('#taskCompleteButton').onClick(() => changeCompleteStatus($item, itemData));
});
}
Call the createNewTask() function when the Add Task button is clicked or when a site visitor presses the Enter key in the task input.
$w('#addButton').onClick(() => createNewTask());
$w('#taskInput').onKeyPress((event) => {
if (event.key === 'Enter') {
createNewTask();
}
});
Call the clearCompletedTasks() function when the Clear Marked Tasks button is clicked.
$w('#clearButton').onClick(() => clearCompletedTasks());
Include the following code to create a new task, change the complete button status, and clear the completed tasks.
async function createNewTask() {
const toInsert = {
title: $w('#taskInput').value,
isComplete: false,
visitorId
};
$w('#taskInput').value = null;
try {
await insertTask(toInsert);
await fetchData();
} catch (error) {
console.error(error);
}
}
async function changeCompleteStatus($item, itemData) {
try {
if ($item('#taskCompleteButton').label === 'X') {
$item('#taskCompleteButton').label = '';
getHTMLtag($item('#taskTitle'), false);
await updateTask(itemData._id, false);
} else {
$item('#taskCompleteButton').label = 'X';
getHTMLtag($item('#taskTitle'), true);
await updateTask(itemData._id, true);
}
} catch (error) {
console.error(error);
}
}
// Call the remove function asynchronously and store the promise returned by each call in the removePromises array. We use Promise.all in order to wait for all calls to complete before returning from the function.
async function clearCompletedTasks() {
let removePromises = [];
let remainedTasks = [];
$w('#repeater').forEachItem(async ($item, itemData) => {
if ($item('#taskCompleteButton').label === 'V') {
const removePromise = removeTask(itemData._id);
removePromises.push(removePromise);
} else {
remainedTasks.push(itemData);
}
});
try {
await Promise.all(removePromises);
} catch (error) {
console.error(error);
}
$w('#repeater').data = remainedTasks;
}
Check whether the task was completed and format the task text accordingly (strike through the task text):
function getHTMLtag(taskTitle, del) {
if (del) {
taskTitle.html = `<p style="font-family:${htmlFontFamily}; font-size:${htmlFontSize}"><del>${taskTitle.text}</del></p>`;
} else {
taskTitle.html = `<p style="font-family:${htmlFontFamily}; font-size:${htmlFontSize}">${taskTitle.text}</p>`;
}
}
Get the visitor ID from Wix local storage. Call the fetchData() function to get all the tasks associated with the specified visitor ID and set the repeater’s data with the tasks.
function setVisitor() {
visitorId = local.getItem('visitor-id');
if (!visitorId) {
visitorId = Math.random().toString(36);
local.setItem('visitor-id', visitorId);
}
fetchData();
}
async function fetchData() {
$w('#loaderImage').expand();
try {
$w('#repeater').data = await getAllTasks(visitorId);
$w('#loaderImage').collapse();
} catch (error) {
console.error(error);
}
}
Release Notes
1.0 Initial version.
Tags
SQL, wixData
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment