Vue implements in situ editing of table cells

Posted by sv4rog on Thu, 10 Feb 2022 07:48:40 +0100

Vue implements in situ editing of table cells

Here are the notes of Vue beginners. Please avoid the old bird. If you are a warm-hearted elder, we earnestly look forward to your valuable comments.

at first

There is a small demand. I hope to read excel files through the browser and modify data on the web page. I checked some JS plug-ins edited by grid. There are so many, which led to the attack of my choice difficulty. In order to edit some simple data, it seems a little uneconomical to introduce plug-ins specifically. I decided to write it myself. After carefully reading Vue's introduction for an hour, he began to code bricks. The success is as follows:

function

Vue is really easy to use. A few lines of code have preliminarily realized the following functions:

  • You can click any cell to modify its value in situ.
  • After modifying the cell, press enter to confirm.
  • The table shows the bidirectional binding of data and JS array. Modify one and the other will change like a ghost quantum.
    For example, in the input enter event, you cannot know the row number and column number of the currently active cell. You can only get the td object through the event bubble path. Change the value of the td object, and the JS array will be updated automatically.

The source code is here_ html + css + JS mixed single file

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Vue Table in situ editing</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js"></script>
    <style>
        .ctab td {
            height: 30px;
            font-size: 14px;
            text-align: center;
            border-left: 1px solid #555;
            border-top: 1px solid #555;
            border-spacing: 0;
            overflow: hidden;
        }

        table {
            background-color: #ffd;
            border-right: 1px solid #555;
            border-bottom: 1px solid #555;
            table-layout: fixed;
        }

        input {
            background-color: #fff;
            text-align: center;
            font-size: 14px;
            border: 0;
            outline: none;
        }
    </style>
</head>

<body>
    <div id="app">
        <table class="ctab" width="400" cellspacing="0" @keyup.enter="endata($event)">
            <tr v-for="(item, r) in tab">
                <!-- use self Event modifier to prevent clicking inside a cell input Element, a function call event occurs -->
                <td v-for="(v, c) in item" :key="cdkey" @click.self="getvar(r, c, v, $event)">{{v}}</td>
            </tr>
        </table>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                tab: [['Serial number', 1, 2, 3], ['full name', 'Zhang San', 'Li Si', 'Wang Wu'], ['Gender', '', '', ''], ['Age', 22, 30, 18]],
                // cdkey has two uses: 1. Re render cell data through cdkey variable value; 2 Vue cannot monitor the change of array elements, but it can monitor cdkey
                cdkey: 1
            },
            methods: {
                getvar: function (r, c, v, e) {
                    const d = e.target;
                    const [w, h] = [d.offsetWidth - 4, d.offsetHeight - 4];
                    $(d).css('border', '2px solid #111').html('<input type="text">');
                    $('input').css({ 'width': w, 'height': h }).val(v).select()
                        .blur(e => {
                            this.tab[r][c] = e.target.value;
                            this.cdkey += 1;
                        });
                },
                endata: function (e) {
                    console.log(e);
                    // Determine whether the bubbling event from input
                    if (e.target.nodeName == 'INPUT') {
                        e.path[1].innerText = e.target.value;
                        this.cdkey += 1;
                    }
                }
            }
        });
    </script>
</body>

</html>

problem

The core code is the lines of getvar function. Although the code is simple, the problem still exists.

  • When a cell is modified and the second cell is clicked, the second cell will not be edited. The program runs the blur event of the previous cell. After inquiry, it should be caused by the conflict between blur event and click. My level cannot be solved.
  • When you click to modify a cell, adding an input element to the cell in situ will cause a slight shift of several pixels under the whole table. Deduct a small amount of width and height of input, but the problem remains. It should be the problem of CSS layout. My level can't solve it.

Look forward to the great God coming to rescue.

Topics: Javascript Front-end Vue.js html