Отслеживайте свои задачи с помощью списка дел. Вы можете создать чек-лист для себя, своих сотрудников или клиентов.

Описание функционала

В этом примере мы позволяем посетителям сайта отслеживать свои задачи с помощью списка дел. Посетители могут добавлять задачи в список, отмечать задачи как выполненные и удалять выполненные задачи.

Пример кода

to-do

import { getAllTasks, insertTask, updateTask, removeTask } from 'backend/data';
import { local } from 'wix-storage';


const htmlFontFamily = `madefor-display`;
const htmlFontSize = `14px`;


let visitorId;


$w.onReady(function () {
    $w('#repeater').data = [];
    registerHandlers();
    setVisitor();
});


function registerHandlers() {
    $w('#repeater').onItemReady(($item, itemData) => {
        $item('#taskTitle').text = itemData.title;
        if (itemData.isComplete === true) {
            $item('#taskCompleteButton').label = 'V';
        }
        getHTMLtag($item('#taskTitle'), itemData.isComplete);
        $item('#taskCompleteButton').onClick(() => changeCompleteStatus($item, itemData));
    });
    $w('#addButton').onClick(() => createNewTask());
    $w('#taskInput').onKeyPress((event) => {
        if (event.key === 'Enter') {
            createNewTask();
        }
    });
    $w('#clearButton').onClick(() => clearCompletedTasks());
}


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);
    }
}


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 === 'V') {
            $item('#taskCompleteButton').label = '';
            getHTMLtag($item('#taskTitle'), false);
            await updateTask(itemData, false);
        } else {
            $item('#taskCompleteButton').label = 'V';
            getHTMLtag($item('#taskTitle'), true);
            await updateTask(itemData, true);
        }
    } catch (error) {
        console.error(error);
    }
}


// instead of waiting for each remove action to complete, we call the remove function asynchronously and store the promise returned by each
// call in 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;
}


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>`;
    }
}

data.jsw

import wixData from 'wix-data';


export async function getAllTasks(visitorId) {
    try {
        const results = await wixData.query('MyTasks')
            .eq('visitorId', visitorId)
            .find();
        return results.items;
    } catch (error) {
        console.error(error);
    }
}


export async function insertTask(taskObj) {
    try {
        await wixData.insert('MyTasks', taskObj);
    } catch (error) {
        console.error(error);
    }
}


export async function updateTask(task, newStatus) {
    try {
        const toUpdate = {
            ...task,
            isComplete: newStatus
        };
        await wixData.update('MyTasks', toUpdate);
    } catch (error) {
        console.error(error);
    }
}


// this function is different from the previous ones as it returns a promise
// this is done in order to allow calling it several times without waiting to each call to complete
export function removeTask(taskID) {
    try {
        const removePromise = wixData.remove('MyTasks', taskID);
        return removePromise;
    } catch (error) {
        console.error(error);
    }
}

Как создать аналогичный функционал

Мы создали коллекцию MyTasks со следующими полями:

Заголовок: название задачи

isComplete: указывает, завершена ли задача

Открыть в Редакторе >

Для простоты работы, на данный момент любой пользователь может изменять данные коллекции, но при использовании этого примера на вашем сайте всегда предпочтительнее предоставлять только необходимые разрешения для доступа к вашей коллекции.

Элементы страницы

На нашей главной индексной странице мы добавили следующие элементы:

  • TextInput: для ввода текста для новой задачи.

  • Кнопка: для добавления новой задачи в список.

  • Repeater: для отображения текущих задач. Каждый элемент содержит текстовый элемент, содержащий название задачи, и кнопку для отметки задачи как выполненной.

  • Кнопка: для удаления всех выполненных задач из списка.

Серверный код

Мы обрабатываем все операции, связанные с коллекцией, в веб-модуле data.jsw. Веб-модуль включает в себя функции для получения всех текущих задач, вставки новой задачи, обновления задачи и удаления задачи. Мы рекомендуем использовать внутренний код при доступе к коллекции из соображений безопасности.

Код на странице

Мы зарегистрировали следующие обработчики событий:

  1. onItemReady: запускается для каждой задачи, показанной в повторителе. Для каждой задачи нам нужно показать ее как выполненную или незавершенную, в соответствии с ее статусом, и зарегистрировать соответствующий переключатель в обработчике события changeCompletedStatus.

  2. createNewTask: выполняется либо при нажатии кнопки «Добавить», либо при нажатии клавиши «Ввод», когда фокус находится на элементе TextInput.

  3. clearCompletedTasks: запускается при нажатии кнопки Clear Completed.

Мы вызываем fetchData(), которая заполняет повторитель задачами, хранящимися в коллекции. Во время выполнения операции отображается gif-файл загрузчика.

← Все руководства по WixНайти другой материал →