In the process of developing an admin panel using Vuejs and tailwind CSS for managing exercises on a page, I have encountered some challenges.
My current objective is to insert the dynamic form values into a Firebase real-time database. However, I am struggling to extract the values from the form itself. The concept involves allowing users to add additional fields for each 'step' they wish to include in an exercise by clicking on a plus button next to the field.
I attempted to set a reference in the setup script: const step = reference([]);
, but this method did not yield the desired outcome.
I also explored adding it to the props, only to receive an error indicating that 'step' is not defined.
Outlined below is the setup script:
<script setup>
import { database, auth } from "../firebase";
import { ref, setWithPriority, push, set } from "firebase/database";
import { ref as reference } from "vue";
import router from "../router";
let exerciseRef = ref(database, "exercises/");
let selected = reference(null);
const props = defineProps([
"selected",
"name",
"video",
"summary",
"description",
"isActive",
]);
const emits = defineEmits([
"update:name",
"update:video",
"update:description",
"update:summary",
"update:isActive",
]);
function createExercise() {
exerciseRef = ref(database, `exercises/${selected.value - 1}/4`);
set(exerciseRef, {
name: props.name,
video: props.video,
summary: props.summary,
description: props.description,
isActive: props.isActive,
});
let logRef = ref(database, "logs/exercise/");
let pushRef = push(logRef);
setWithPriority(
pushRef,
{
type: "added",
exercise: props.name,
admin: auth.currentUser.displayName,
date: new Date().toLocaleString("en-US"),
},
0 - Date.now()
);
router.push("/admin/exercises");
}
This represents the HTML structure for the dynamic form:
<form>
<div class="form-group">
<label>Steps</label>
<div
v-for="(input, index) in stepNumbers"
:key="`stepInput-${index}`"
class="input wrapper flex items-center"
>
<input
v-model="input.step"
type="text"
class="h-10 rounded-lg outline-none p-2"
placeholder="Enter step"
/>
<!-- Add Svg Icon-->
<svg
@click="addField(input, stepNumbers)"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
class="ml-2 cursor-pointer"
>
<path fill="none" d="M0 0h24v24H0z" />
<path
fill="green"
d="M11 11V7h2v4h4v2h-4v4h-2v-4H7v-2h4zm1 11C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16z"
/>
</svg>
<!-- Remove Svg Icon-->
<svg
v-show="stepNumbers.length > 1"
@click="removeField(index, stepNumbers)"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
class="ml-2 cursor-pointer"
>
<path fill="none" d="M0 0h24v24H0z" />
<path
fill="#EC4899"
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-9.414l2.828-2.829 1.415 1.415L13.414 12l2.829 2.828-1.415 1.415L12 13.414l-2.828 2.829-1.415-1.415L10.586 12 7.757 9.172l1.415-1.415L12 10.586z"
/>
</svg>
</div>
</div>
</form>
Additionally, here is the script responsible for adding more fields to the form:
<script>
export default {
name: "AddRemove",
data() {
return {
stepNumbers: [{ step: "" }],
};
},
methods: {
addField(value, fieldType) {
fieldType.push({ value: "" });
},
removeField(index, fieldType) {
fieldType.splice(index, 1);
},
},
};
</script>
If you can provide any assistance or insights, it would be immensely appreciated.