简体   繁体   中英

alpine.js table edit-in-place functionality

I'm trying to make a table column editable inline using Alpine.js. The idea is to have an "edit in place" functionality so when a row is double-clicked allows for the content to be editable. The issue I'm having is when a cell is clicked it activates all rows.

The ideal behavior is only the clicked row should be editable, all others should remain uneditable.

I have a preview of the issue here, https://codepen.io/ezeagwulae/pen/ZEKeYGQ

<div x-data="data()" class="p-4">
    <div class="uppercase font-bold">shopping items</div>
    <template x-for="item in items">
        <div>
            <a @click.prevent @dblclick="toggleEditingState" x-show="!isEditing" x-text="item.item" class="select-none cursor-pointer underline font-lg text-blue-500"></a>
            <input type="text" x-model="text" x-show="isEditing" @click.away="toggleEditingState" @keydown.enter="disableEditing" @keydown.window.escape="disableEditing" class="bg-white focus:outline-none focus:shadow-outline border border-gray-300 rounded-lg py-2 px-4 appearance-none leading-normal w-128" x-ref="input">
        </div>
    </template>
</div>

In your JS file make sure to get the double-clicked input field with e.target.

In your HTML x-model should be set to item.item. Here's a working example.

HTML

<div x-data="data()" class="p-4">
    <div class="uppercase font-bold">shopping items</div>
    <template x-for="item in items">
        <div>
            <a @click.prevent @dblclick="toggleEditingState" x-show="!isEditing" x-text="item.item" class="select-none cursor-pointer underline font-lg text-blue-500"></a>
            <input type="text" x-model="item.item" x-show="isEditing" @click.away="toggleEditingState" @keydown.enter="disableEditing" @keydown.window.escape="disableEditing" class="bg-white focus:outline-none focus:shadow-outline border border-gray-300 rounded-lg py-2 px-4 appearance-none leading-normal w-128" x-ref="input">
        </div>
    </template>
</div>

JS

function data() {
    return {
        text: "Double click to edit",
        isEditing: false,
        toggleEditingState(e) {
            const el = e.target
            this.isEditing = !this.isEditing;

            el.focus()
        },
        disableEditing() {
            this.isEditing = false;
        },
        items: [
            { id: 1, item: "apple" },
            { id: 2, item: "eggs" },
            { id: 3, item: "milk" }
        ]
    };
}

Any suggestions to make only the clicked row editable and not all rows? For instance, if "eggs" the input field should be shown for this row and the other rows should remain as is

For example like this:

 <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet"/> <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.xx/dist/alpine.js"></script> <div x-data="{ items: [ { id: 1, item: 'apple', edit: false }, { id: 2, item: 'eggs', edit: false }, { id: 3, item: 'milk', edit: false }, ] }" class="p-4" > <div class="uppercase font-bold">shopping items</div> <template x-for="(item, index) in items"> <div> <a @click.prevent @dblclick=" item.edit = true; $nextTick(() => $refs[item.id].focus()); " @click.away="item.edit = false" x-show="!item.edit" x-text="item.item" class=" select-none cursor-pointer underline font-lg text-blue-500 " ></a> <input type="text" x-model="item.item" x-show="item.edit" @click.away="item.edit = false" @keydown.enter="item.edit = false" @keydown.window.escape="item.edit = false" class=" bg-white focus:outline-none focus:shadow-outline border border-gray-300 rounded-lg py-2 px-4 appearance-none leading-normal w-128 " :x-ref="item.id" /> </div> </template> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM