链接 IndexedDB 和 JQuery:如何通过定位选定行中的 table 数据来删除 table 行?

Linking IndexedDB and JQuery: How to delete a table row by targeting the table data in a selected row?

我正在尝试使用 IndexedDB (IDB) link 我的 jQuery table。目前,我能够将项目添加到浏览器 UI 并成功添加到 IDB,这会生成一个标识符键。当项目从 IDB 中提取时,我将标识符键存储在每个项目 table(参见屏幕截图)最右侧的隐藏列中。

我想要做的是从 UI 和 IDB 中删除项目。我在 main.js 第 26 行的代码(屏幕截图的右下角)成功地从 UI 中删除了该项目,但是第 32 行的代码并未按要求从 IDB 中删除该项目。

我 运行 两个 alert/console.log 变量(第 34 行)报告正确的密钥标识符已存储在变量中,但似乎运行异常它根据在 table 中选择的行多次报告它(即,如果我删除“运动”,它会在三个单独的警报中报告 36?)。然后变量没有被正确删除。但是,如果我 运行 第 35 行并将文字键标识符(即“36”)而不是变量传递给它,则该项目将被删除。

非常欢迎任何建议,谢谢!

截图[1]

Table 和代码 https://i.stack.imgur.com/Etb2S.png

此处提供完整代码(请注意,我在 JS 页面上包含了所有单独的文件)https://codepen.io/QuiveringCoward/pen/gOMqpRv

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>jQuery Add / Remove Table Rows</title>
        <!-- link to CSS-->
        <link rel="stylesheet" href="./style.css">
        <!-- link to JQuery-->
        <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
        
        <!--link to JS-->
        <script src="./main.js"></script>
        <script src="../lib/indexedDB.js"></script>
    </head>
<body>
    <!-- user inputs for tasks -->
    <h1> Simplicity | Simplify Your Life </h1>
    <form id="todo-list">
        
        <label for=task>Task</label>
        <input type="text" id="task" placeholder="Task" required="required">
        
        <label for=task>Description</label>        
        <input type="text" id="description" placeholder="Description">
        
        <label for=task>Due Date</label>        
        <input type="date" id="date" placeholder="Due Date" required="required">
        
        <label for=task>Time</label>        
        <input type="time" id="time" placeholder="00:00">

        <label for=task>Frequency</label>        
        <select id="frequency" name="frequency" class="todo-frequency">
            <option value="Daily">Daily</option>
            <option value="Weekly">Weekly</option>
            <option value="Monthly">Monthly</option>
        </select>
        
        <label for=task>Location</label>        
        <input type="text" id="location" name="location" placeholder="Location">
        
        <label for=task>Priority</label>        
        <select id="priority" name="priority" class="todo-priority">
            <option value="1-high">1 - High</option>
            <option value="2-medium">2 - Medium</option>
            <option value="3-low">3 - Low</option>
        </select>
        
        <br>
        <br>
          <!-- add task button -->  
        <input type="submit" class="add-task" value="Add Task">
        <br>
        <br>
        <label for=search>Search Table</label>
        <input type="text" id="search" placeholder="Search here...">

    </form>
    <h2>Todo List</h2>
    <table id="todo-table">
        <!-- headers for todolist-->
        <thead> 
            <tr>
                <th>Select</th>
                <th>Task</th>
                <th>Description</th>
                <th>Due Date<span> &#8597;</span></th>
                <th>Time</th>
                <th>Frequency</th>
                <th>Location</th>
                <th>Priority<span> &#8597;</span></th>
                <th class="key" id="key"></th>
            </tr>
        </thead>
        <tbody>
            <!-- where the JS will append the tasks -->
        </tbody>
    </table>
    <!-- submit button for todolist -->
    <button type="button" class="delete-task">Delete Task(s)</button>
    <br>
    <br>
    <button type="button" id="all-tasks">All Tasks</button>
    <button type="button" id="daily-tasks">Daily Tasks</button>
    <button type="button" id="weekly-tasks">Weekly Tasks</button>
    <button type="button" id="monthly-tasks">Monthly Tasks</button>

    <script src="./AddItemPage/AddItem.js"></script>
    <script src="./AddItemPage/AddItemDAO.js"></script>
    <script src="./ListItemsPage/ListItems.js"></script>
    <script src="./ListItemsPage/ListItemsDAO.js"></script>
    
</body> 
</html>
//*************** OTHER PAGES STORED LOCALLY **************//

// AddItem.js
$("#todo-list").submit(function(event){

    event.preventDefault();

    setDatabaseName("Luke's Todo List", ["UsersObjectStore", "ItemsObjectStore"]);

    setCurrObjectStoreName("ItemsObjectStore");

    startDB(function () {
        saveItemData();
        alert("Item has been saved successfully!");
    })
})

// AddItemDAO.js

function saveItemData() {


    var data = {

    };

    insertOne(data, function(lastID){
        event.preventDefault();
        return false;
    });

}

// ListItems.js
setDatabaseName("Luke's Todo List", ["UsersObjectStore", "ItemsObjectStore"]);
setCurrObjectStoreName("ItemsObjectStore");
startDB(function() {
    showAllItems();
});

//ListItemsDAO.js
function showAllItems() {
    selectAll(function(results) {
        var len = results.length, i;

        for(i = 0; i < len; i++) {
            $("#todo-table").append(
                '<tr id="' + results[i].id +'" class="' + results[i].frequency + " " + results[i].priority +'">\
                    <td> <input type="checkbox" name="record"></td>\
                    <td class="task">' + results[i].task + '</td>\
                    <td class="description">' + results[i].description + '</td>\
                    <td class="date">' + results[i].date + '</td>\
                    <td class="time">' + results[i].time + '</td>\
                    <td class="frequency">' + results[i].frequency + '</td>\
                    <td class="location">' + results[i].location + '</td>\
                    <td class="priority">' + results[i].priority + '</td>\
                    <td class="key" id="key">' + results[i].id + '</td>\
                 </tr>'
            )
        }
    });
}

// Indexed DB library wrapper

    //This is an indexeddb wrapper javascript library
    
    //Global variables
    var db, indexedDB, IDBTransaction, currObjectStoreName, databaseName, objectStores;
    
    //startDB creates connection with the databaseName
    //and create database and object stores
    function startDB(successCallback, failureCallback) {
        try {
            indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
            IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
            IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
        }
        catch(e) {
            console.log('Initial IndexedDB error: ' + e);
            failureCallback();
        }
        
        if(!window.indexedDB) {
            failureCallback();
            return;
        }

        var request = indexedDB.open(databaseName, 1);
            
        //The onupgradeneeded property is triggered when a database 
        //of a bigger version number than the existing stored database is loaded.
        request.onupgradeneeded = function(event) {
            console.log('onupgradeneeded method is invoked');
            db = event.target.result;
            for(i=0; i < objectStores.length; i++) {
                db.createObjectStore(objectStores[i], { keyPath: 'id', autoIncrement: true });
            }
        };

        request.onsuccess = function(event) {
            db = event.target.result;
            successCallback && successCallback();
        };

        request.onerror = function(event) {
            console.log('User don\'t allow IndexedDB to use offline storage.');
            failureCallback();
        };
    }

    //Just print any indexeddb related error message in console window
    function indexedDBError(event) {
        console.log('An error occurred in IndexedDB', event);
    }
    
    //setDatabaseName sets the Database name and Object Stores required for a website
    function setDatabaseName(dbName, objStores) {
        databaseName = dbName;
        objectStores = objStores;
        console.log('Database : ', dbName);
    }
    
    //setCurrObjectStoreName set the current object store to store or retrieve data
    function setCurrObjectStoreName(objStoreName) {
        currObjectStoreName = objStoreName;
        console.log('Current Object Store Name : ', currObjectStoreName);
    }

    //selectAll retrieves all data from the current object store
    function selectAll(successCallback) {
        var transaction = db.transaction([currObjectStoreName], IDBTransaction.READ_ONLY || 'readonly'),
            objectStore, request, results = [];
            
        transaction.onerror = indexedDBError;
        objectStore = transaction.objectStore(currObjectStoreName);
        request = objectStore.openCursor();

        request.onerror = indexedDBError;
        request.onsuccess = function(event) {
            // event.target means request
            var cursor = event.target.result;
            if(!cursor) {
                if(successCallback) {
                    successCallback(results);
                }
                return;
            }
            results.push(cursor.value);
            cursor.continue();
        };
    }
    
    //insertOne inserts data into the current object store
    //This function also creates unique id for each data
    function insertOne(data, successCallback) {
        var transaction = db.transaction([currObjectStoreName], IDBTransaction.READ_WRITE || 'readwrite'),
            objectStore, request, lastID;
        
        objectStore = transaction.objectStore(currObjectStoreName);
        request = objectStore.add(data);
        request.onsuccess = function(event) {
            lastID = event.target.result;
        }
        request.onerror = indexedDBError;
        
        transaction.onerror = indexedDBError;

        transaction.oncomplete = function(event) {
            console.log('Data was inserted succesfully');
            if(successCallback) {
                successCallback(lastID);
            }
        };
    }
    
    //deleteOne inserts data into the current object store
    function deleteOne(id, successCallback) {
        var transaction = db.transaction([currObjectStoreName], IDBTransaction.READ_WRITE || 'readwrite'),
            objectStore, request;
            
        objectStore = transaction.objectStore(currObjectStoreName);
        request = objectStore.delete(id);
        request.onerror = indexedDBError;
        request.onsuccess = function(event) {
            var result = event.target.result;
        };
        transaction.onerror = indexedDBError;
        transaction.oncomplete = function() {
            console.log('Data with ' + id + ' was deleted successfully');
            if(successCallback) {
                successCallback();
            }
        };
    }
    
    //updateOne updates a specific data in the current object store
    function updateOne(data, successCallback) {
        var transaction = db.transaction([currObjectStoreName], IDBTransaction.READ_WRITE || 'readwrite'),
            objectStore, request, lastID;
        
        objectStore = transaction.objectStore(currObjectStoreName);
        request = objectStore.put(data);
        request.onsuccess = function(event) {
            lastID = event.target.result;
        }
        request.onerror = indexedDBError;
        
        transaction.onerror = indexedDBError;

        transaction.oncomplete = function(event) {
            console.log('Data with ' + lastID + ' was deleted successfully');
            if(successCallback) {
                successCallback(lastID);
            }
        };
    }
    
    //selectOne select just one data
    function selectOne(id, successCallback) {
        var transaction = db.transaction([currObjectStoreName], IDBTransaction.READ_ONLY || 'readonly'),
            objectStore, request;
            
        transaction.onerror = indexedDBError;
        objectStore = transaction.objectStore(currObjectStoreName);
        request = objectStore.get(parseInt(id));

        request.onerror = indexedDBError;
        request.onsuccess = function(event) {
            // event.target means request
            
            var record = request.result;
            
            if(record) {
                
                if(successCallback) {
                    
                    successCallback(record);
                }
                return;
            }
        };
    }
    

我发现还有一个函数可以调用来从IndexedDB中删除数据,它叫做deleteOne(),你所要做的就是找到需要删除的数据的键。我用这段代码解决了

$("table tbody").find('input[name="record"]:checked').each(function() {
     deleteOne(parseInt($(this).closest('tr')[0].id))
});