Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
204 views
in Technique[技术] by (71.8m points)

javascript - Is my AJAX Call function correct for Removal of Table Row?

I'm having trouble figuring out why my "Remove" button is not working as intended. I'm working on a webpage. Long story short, the main page contains a table whose rows are added via user input, some SQL database queries, and Flask. I want to be able to remove rows w/o refreshing the page, so I got some help constructing an AJAX call to do just that. This is the portion meant to handle that action:

$("#button").clicked(function() {
var rowsToRemove = [];
$(".checkitem:checked").each(function() {
  var rowIndex = $(this).parent("tr").index(this);
  rowsToRemove.push(rowIndex+1);
});

delete_ajax = $.ajax({
        type : 'POST',
        method: 'POST',
        url : "/home",
        data : JSON.stringify({rowsToRemove:rowsToRemove, typeofpost: 'delete'}),
        dataType: "json",
        contentType: "application/json"
});

delete_ajax.done(function(responseObject, textStatus, jqXHR) {
    if(responseObject.status == 200) {
      reloadTable();
    }
});

delete_ajax.error(function() {
  alert("Unable to delete row(s). Please try again.");
});

});

And here is the portion that I was assisted with from the Flask side that would distinguish between delete calls and posted data:

if request.json.get('type') == 'add':
        if not request.form.get("password"):
            return apology("'Password' field required. Please enter a symbol.", 403)
        if not request.form.get("website"):
            return apology("'Website' field required. Please enter a share.", 403)

        password=request.form.get("password")

        db.execute("INSERT INTO passwords (user_id, password, cipher, website) VALUES (:userID, :password, :cipher, :website)",
                    userID=session["user_id"],
                    password=password,
                    cipher=encrypt(password),
                    website=request.form.get("website"))

        length = db.execute("SELECT COUNT(password) FROM passwords WHERE user_id = :userID", userID=session["user_id"])#.fetchone()[0]

        db.execute("UPDATE passwords SET row_id = :rowID WHERE user_id = :userID AND password = :pw",
                    rowID=length[0]["COUNT(password)"],
                    userID=session["user_id"],
                    pw=password)

        #return redirect("/home")
        return {"status":200}

    # from delete
    if request.json.get('type') == 'delete':
        length = db.execute("SELECT COUNT(password) FROM passwords WHERE user_id=:userID", userID=session["user_id"]).fetchone()[0]

        index = list(range(1, length+1))

        data_to_delete = request.json.get("data")

        rowsToRemove = db.execute("DELETE FROM passwords WHERE row_id IN :data AND user_id:=userID", data=data_to_delete, userID=session["user_id"])

        db.execute("UPDATE passwords SET row_id=:rowID WHERE user_id=:userID", rowID=index, userID=session["user_id"])

        return {"status":200}

Just in case I need to fix something I overlooked on the HTML side, I'll that as well:

<div class="form-group container">
    <table class="table table-hover thead-dark">
        <thead>
            <th><div class="checkbox">
                    <label><input type="checkbox" class="checkbox" id="checkall" name="checkall"> Select/Deselect All</label>
                </div></th>
            <th>Row</th>
            <th>Password</th>
            <th>Cipher</th>
            <th>Website</th>
        </thead>
        <tbody>
            {% for row in rows %}
                <tr>
                    <td><div class="checkbox">
                        <input type="checkbox" class="checkitem">
                    </div></td>
                    <td>{{row["row_id"]}}</td>
                    <td>{{row["password"]}}</td>
                    <td>{{row["cipher"]}}</td>
                    <td>{{row["website"]}}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    <div class="form-group form-inline container center row">
        <form  action="/home" method="/post">
            <input class="form-control" autocomplete="off" name="password" placeholder="Password" type="text" required>
            <input autocomplete="off" class="form-control" name="website" placeholder="Website" type="text" required>
            <input class="btn btn-primary" type="submit" id="encrypt" value="Encrypt">
        </form>
        <button type="button" class="btn btn-outline-danger" style="margin: auto" id="button">Remove</button>
    </div>

I have a habit of overlooking things, so if there's something I'm missing, please let me know a.s.a.p.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you separate the function, it will be easy to debug. I gave an example here, I have a table called account. I made different functions to make the CRUD operations

from flask import Flask, jsonify, request, render_template
import sqlite3
app = Flask(__name__)

con = sqlite3.connect("sql.db", check_same_thread=False)
con.row_factory = sqlite3.Row
cur = con.cursor()
    
@app.route('/account', methods=['GET'])
def get_account():
    args = [] 
    where = ''
    if request.args:
        for i in request.args:
            args.append(i + ' = "' + request.args[i]+'"')
        where = ' WHERE '+' and '.join(args)
    cur.execute('SELECT * FROM account{}'.format(where))
    data = [dict(i) for i in cur.fetchall()]
    return jsonify({'data':data})

@app.route('/account', methods=['POST'])
def post_account():
    acc = request.form['acc']
    cur.execute("INSERT INTO account (account) VALUES ('{}')".format(acc))
    con.commit()
    a = cur.lastrowid
    cur.execute('SELECT * FROM account WHERE id = {}'.format(a))
    data = cur.fetchone()
    return jsonify(data)

@app.route('/account', methods=['PUT'])
def put_account():
    data = request.form
    cur.execute("UPDATE account set account = '{}' WHERE id = {}".format(data['acc'], data['id']))
    con.commit()
    cur.execute('SELECT * FROM account WHERE id = {}'.format(data['id']))
    data = cur.fetchall()
    return jsonify(data)

@app.route('/account', methods=['DELETE'])
def dalete_account():
    data = request.form
    cur.execute("DELETE from account  WHERE id = {}".format(data['id']))
    con.commit()
    return jsonify({'status': 'Deleted Successfully', 'deleted_id': data['id']})

Table Schema

CREATE TABLE IF NOT EXISTS account(
id integer PRIMARY KEY,
account text)

And the AJAX,

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <marquee behavior="" direction="">Press F12 and See the console.</marquee>
ID: <input type="number" id="id" ><br>
Acc: <input type="text" id="acc"><br>
<button onclick="post()">Post: Add Acc and Submit</button>
<button onclick="put()">Put: Add ID and acc and Submit</button>
<button onclick="del()">Delete: Add ID and Submit</button>
<div id="result"></div>
<script>
    function post() {
        dic = {'acc': document.getElementById('acc').value}
        $.ajax({
            type: "POST",
            url: '/account',
            data: dic,
            success: function(data){
                console.log(data)
                $('input').val('')
            }
        })
    }
    function put() {
        dic = {'id': document.getElementById('id').value, 'acc': document.getElementById('acc').value}
        $.ajax({
            type: "PUT",
            url: '/account',
            data: dic,
            success: function(data){
                console.log(data)
                $('input').val('')
            }
        })
    }
    function del() {
        dic = {'id': document.getElementById('id').value}
        $.ajax({
            type: "DELETE",
            url: '/account',
            data: dic,
            success: function(data){
                console.log(data)
                $('input').val('')
            }
        })
    }
</script>

</body>
</html>

You may need to add few things to AJAX, and it is already there in your code,

contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8') Type: Boolean or String

When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent).

dataType (default: Intelligent Guess (xml, json, script, or html)) Type: String

A function to be used to handle the raw response data of XMLHttpRequest. This is a pre-filtering function to sanitize the response. You should return the sanitized data. The function accepts two arguments: The raw data returned from the server and the 'dataType' parameter.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...