Currently learning Vue 3 and new in stackoverflow.
I am trying to capture the id of an element, and based on it load an input to edit the value of the descriptionText property. The problem is that it edits the descriptionText property of all the elements, and I’m trying to make it happen only in one
I´m using vue-draggable-next and Sweetalert2 libraries on this project
<template>
<head>
<!-- Boxicons -->
<link
href="https://unpkg.com/[email protected]/css/boxicons.min.css"
rel="stylesheet"
/>
</head>
<div class="container-fluid row mt-2">
<div class="col-md-3 float-start">
<div class="panel-default border" style="background-color: #f7f9fa">
<div class="panel-heading text-center">
<h3 class="panel-title visible-panel-text">Draggable elements</h3>
</div>
<!-- Elements zone -->
<draggable
class="row mt-2"
:list="draggableElements"
:sort="false"
:group="{ name: 'cloneableItems', pull: 'clone', put: false }"
@end="generateJSON"
>
<div
class="col-sm-6 mb-2"
v-for="element in draggableElements"
:key="element.id"
>
<div class="border drag-element">{{ element.visibleName }}</div>
</div>
</draggable>
<!-- Copy JSON panel -->
<div
class="panel-json json-container mt-2 border"
style="background-color: #f7f9fa"
>
<div
class="panel-heading text-center"
@click="state.showJSONPanel = !state.showJSONPanel"
>
<h3
class="panel-title"
style="text-align: center; cursor: pointer; user-select: none"
>
JSON
</h3>
</div>
<div class="panel-body" v-show="state.showJSONPanel">
<textarea
class="json-textarea form-control"
v-model="state.generatedJSON"
style="width: 90%; margin: 0 auto; resize: none"
></textarea>
<button class="btn btn-secondary btn-sm" @click="copyJSON">
Copy JSON
</button>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<!-- Show content -->
<draggable
class="w-100 h-100 border"
:empty-insert-threshold="1000"
:list="state.contentElements"
@update="generateJSON"
:group="{ name: 'putItems', pull: 'clone', put: true }"
>
<div
v-for="element in state.contentElements"
:key="element.id"
class="container"
>
<template v-if="element.type == 'description'">
<label>This is the description element</label>
<div>{{ element.descriptionText }}</div>
</template>
<!-- Edit & delete -->
<div
class="iterable-icons-container"
style="display: flex; justify-content: flex-end"
>
<!-- Edit icon -->
<i class="bx bxs-cog edit-icon" @click="editElement(element.id)"></i>
<!-- Delete icon -->
<i class="bx bxs-trash-alt edit-icon" @click="deleteElement()"></i>
</div>
</div>
</draggable>
</div>
<!-- Changes panel -->
<div class="col-md-3 border">
<div>
<!-- Description -->
<template
v-if="
state.editedId >= 0 &&
state.contentElements[state.editedId].type == 'description'
"
>
<label><strong>Description element</strong></label>
<input type="text" v-model="edit.descriptionNewText" />
<button class="btn btn-light" @click="saveChanges()">Save changes</button>
</template>
</div>
</div>
</div>
</template>
<script setup>
import "bootstrap";
import "bootstrap/dist/css/bootstrap.css";
import { reactive, ref } from "vue";
//Drag and drop library
import { VueDraggableNext as draggable } from "vue-draggable-next";
//Sweetalert
import Swal from "sweetalert2";
import "sweetalert2/dist/sweetalert2.min.css";
//Array with the main elements list
const draggableElements = [
{
id: crypto.randomUUID(),
visibleName: "Description",
descriptionText: "This is a description that you can edit",
type: "description",
mandatory: false,
},
];
//Variable where the data flows
let state = reactive({
//Store a global index to edit
editedId: ref(-1),
contentElements: reactive([]),
showJSONPanel: ref(false),
generatedJSON: ref(""),
});
//eslint-disable-next-line
let edit = reactive({
descriptionNewText: ref(""),
});
function copyJSON() {
const textarea = document.querySelector(".json-textarea");
textarea.select();
document.execCommand("copy");
Swal.fire("Success", "JSON copied", "success");
}
function generateJSON() {
//Actualizar valor del textarea
let textarea = document.querySelector(".json-textarea");
textarea.value = state.generatedJSON;
//Generar el archivo JSON de acuerdo a lo puesto por el usuario
state.generatedJSON = JSON.stringify(state.contentElements, null, 2);
}
//Edit
function editElement(id) {
const elementId = state.contentElements.findIndex((element) => element.id === id);
state.editedId = elementId;
const elementType = state.contentElements[state.editedId].type;
console.log("Type is: ", elementType);
}
//Delete element
//Eliminar elemento del panel de construcción del formulario
function deleteElement(index) {
Swal.fire({
title: "Confirm delete",
text: "Are you sure?",
icon: "warning",
showCancelButton: true,
confirmButtonText: "Yes, delete",
cancelButtonText: "Cancel",
}).then((result) => {
if (result.isConfirmed) {
state.contentElements.splice(index, 1);
state.generatedJSON = JSON.stringify(state.contentElements, null, 2);
}
});
}
//Save changes in the element
function saveChanges(type) {
type = state.contentElements[state.editedId].type
console.log("Type is: ", type)
switch(type){
case 'description':
//Description data
state.contentElements[state.editedId].descriptionText = edit.descriptionNewText;
state.editedId = -1
edit.descriptionNewText = ""
break;
}
}
</script>
<style scoped>
.drag-element {
cursor: pointer;
}
.edit-icon {
font-size: 25px;
}
.edit-icon:hover {
color: blueviolet;
cursor: pointer;
}
</style>
I have been searching the internet for methods to asolve this, or at least approach, but I have not been able to find anything.