I cannot identify the reason for this message in Alpine JS - javascript

I get this error and have no idea how to fix:
alpine.js:115 Alpine Error: "ReferenceError: Invalid left-hand side in assignment"
Expression: "getTasks() = rightSideOfExpression($event, getTasks())"
Element: <input class=​"shadow appearance-none border rounded w-1/​3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:​outline-none focus:​shadow-outline" id=​"valorvenda" type=​"text" placeholder=​"Valor" autofocus x-ref=​"valorvenda" #keydown.enter=​"addTask($refs.valorvenda.id)​">​
u # alpine.js:115
(anonymous) # alpine.js:132
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorvenda" type="text" placeholder="Valor" autofocus="" x-ref="valorvenda" #keydown.enter="addTask($refs.valorvenda.id)">
VM5454749:3 Uncaught (in promise) ReferenceError: Invalid left-hand side in assignment
at eval (eval at d.el (alpine.js:174), <anonymous>:3:21)
at d.el (alpine.js:174)
at d (alpine.js:131)
at alpine.js:151
at be.evaluateCommandExpression (alpine.js:1760)
at z (alpine.js:933)
at HTMLDivElement.l (alpine.js:909)
and a have no idea what i do! Can you help me, please?

You probably meant to compare instead of assign. Change = to ==:
getTasks() == rightSideOfExpression($event, getTasks())

I spend my weekend searching for the problem.
I believe the cause is because I'm using the x-model attribute like this:
<div x-data="tasks()" x-init="getTasks()" x-model="getTasks()">
<div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
<div class="card m-1 p-1 cursor-pointer border border-gray-400 rounded-lg hover:shadow-md hover:border-opacity-0 transform hover:-translate-y-1 transition-all duration-200">
<div class="flex flex-row w-full py-2 px-2 m-1 text-sm text-green-800 bg-green-100">
Definir estratégia de COMPRA:
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorcompra" type="text" placeholder="Valor" autofocus x-ref="valorcompra" #keydown.enter="addTask($refs.valorcompra.id)">
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="percentualcompra" type="text" placeholder="Percentual">
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="quantidadecompra" type="text" placeholder="Quantidade">
</div>
<template x-for="(t, taskIndex) in tasks.filter(t => t.coin === window.moeda && t.boardName === 'compra')" :key="taskIndex">
<div :id="t.uuid">
<div class="bg-white rounded-lg shadow mb-3 p-2 text-sm">
<div x-text="t.name" class="text-gray-800"></div>
<div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
<div x-text="formatDateDisplay(t.date)" class="text-gray-500 text-xs"></div>
<div class="items-start text-right text-red-800" #click="removeTask(t.uuid)"><i class="fa fa-times-circle" aria-hidden="true"></i></div>
</div>
</div>
</div>
</template>
</div>
<div class="card m-1 p-1 cursor-pointer border border-gray-400 rounded-lg hover:shadow-md hover:border-opacity-0 transform hover:-translate-y-1 transition-all duration-200">
<div class="flex flex-row w-full py-2 px-2 m-1 text-sm text-red-800 bg-red-100">
Definir estratégia de VENDA:
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorvenda" type="text" placeholder="Valor" autofocus x-ref="valorvenda" #keydown.enter="addTask($refs.valorvenda.id)">
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="percentualvenda" type="text" placeholder="Percentual">
<input class="shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="quantidadevenda" type="text" placeholder="Quantidade">
</div>
<template x-for="(t, taskIndex) in tasks.filter(t => t.coin === window.moeda && t.boardName === 'venda')" :key="taskIndex">
<div :id="t.uuid">
<div class="bg-white rounded-lg shadow mb-3 p-2 text-sm">
<div x-text="t.name" class="text-gray-800"></div>
<div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
<div x-text="formatDateDisplay(t.date)" class="text-gray-500 text-xs"></div>
<div class="items-start text-right text-red-800" #click="removeTask(t.uuid)"><i class="fa fa-times-circle" aria-hidden="true"></i></div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
assigning a JS function here is the cause of the error. What I need is a way to update the x-data every time the getTasks() fucntion is run and I don't know how to do it.

Related

Vue 3 Breadcrumb did not work with <Script setup>

I need your help for my Breadcrumb component.
It did work last time but after I add the Pinia it did not work anymore.
I don't know if this is related to Pinia or not.
This is the screenshot of the project
my_vue_project_screenshot
If you additional detail more than below, please let me know
Thank you all in advance
Also, I'm not sure my Vue project structure is correct or not.
Main layout
|
|- BreadCrumb
|- RouterView
I put BreadCrumb component inside every View pages. Like this (for example)
<script setup>
import breadcrumb from '../../components/breadcrumb.vue';
const pages=[{ name: 'ช่าง', href: '/staff', current: true }]
const technicians = [
{ id: 0, name: 'Mr A', score: 25, role: 'กลึง' },
{ id: 1, name: 'Mr B', score: 35, role: 'เจาะ' },
]
</script>
<template>
<breadcrumb :pages="pages"/>
<div class="space-y-6 pt-8 sm:space-y-5 sm:pt-10">
<div class="sm:flex sm:items-center">
<div class="sm:flex-auto">
<h1 class="text-xl font-semibold text-gray-900">รายชื่อช่าง</h1>
<p class="mt-2 text-sm text-gray-700">Admin</p>
</div>
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
<router-link to="/staff/add">
<button type="button" class="inline-flex items-center justify-center rounded-md border border-transparent
bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2
focus:ring-indigo-500 focus:ring-offset-2 sm:w-auto">เพิ่มช่าง</button>
</router-link>
</div>
</div>
<div class="mt-8 flex flex-col">
<div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
<table class="min-w-full divide-y divide-gray-300">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">ชื่อ</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">แผนก</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">คะแนน</th>
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
<span class="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<tr v-for="technician in technicians" :key="technician.id">
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">{{ technician.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ technician.role }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ technician.score }}</td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
<router-link :to="{ name: 'editstaff', params: { id: technician.id }}"
class="text-indigo-600 hover:text-indigo-900"
>Edit<span class="sr-only">, {{ technician.name }}</span>
</router-link>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</template>
This is my BreadCrumb.vue
<script setup>
import { ChevronRightIcon, HomeIcon } from '#heroicons/vue/20/solid'
</script>
<template>
<nav class="flex" aria-label="Breadcrumb">
<ol role="list" class="flex items-center space-x-4">
<li>
<div>
<a href="/" class="text-gray-400 hover:text-gray-500">
<HomeIcon class="h-5 w-5 flex-shrink-0" aria-hidden="true" />
<span class="sr-only">Home</span>
</a>
</div>
</li>
<li v-for="page in pages" :key="page.name">
<div class="flex items-center">
<ChevronRightIcon class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<a :href="page.href" class="ml-4 text-sm font-medium text-gray-500 hover:text-gray-700"
:aria-current="page.current ? 'page' : undefined">{{ page.name }}</a>
</div>
</li>
</ol>
</nav>
</template>
Lastly, this is my main Layout (Not sure if this is related too or not
<script setup>
import { ref } from 'vue'
import { Dialog, DialogPanel, TransitionChild, TransitionRoot } from '#headlessui/vue'
import {
HomeIcon,
Bars3Icon,
FolderIcon,
UsersIcon,
XMarkIcon
} from '#heroicons/vue/24/outline'
const authenticated = false;
const navigation = [
{ name: 'home', to: '/', icon: HomeIcon },
{ name: 'enj', to: '/staff', icon: UsersIcon },
{ name: 'proj', to: '/project', icon: FolderIcon },
{ name: 'selectproj', to: '/selectproject', icon: FolderIcon },
{ name: 'validateproj', to: '/validateproject', icon: FolderIcon },
]
const sidebarOpen = ref(false)
</script>
<template>
<div>
<TransitionRoot as="template" :show="sidebarOpen">
<Dialog as="div" class="relative z-40 md:hidden" #close="sidebarOpen = false">
<TransitionChild as="template" enter="transition-opacity ease-linear duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="transition-opacity ease-linear duration-300" leave-from="opacity-100" leave-to="opacity-0">
<div class="fixed inset-0 bg-gray-600 bg-opacity-75" />
</TransitionChild>
<div class="fixed inset-0 z-40 flex">
<TransitionChild as="template" enter="transition ease-in-out duration-300 transform" enter-from="-translate-x-full" enter-to="translate-x-0" leave="transition ease-in-out duration-300 transform" leave-from="translate-x-0" leave-to="-translate-x-full">
<DialogPanel class="relative flex w-full max-w-xs flex-1 flex-col bg-gray-800">
<TransitionChild as="template" enter="ease-in-out duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="ease-in-out duration-300" leave-from="opacity-100" leave-to="opacity-0">
<div class="absolute top-0 right-0 -mr-12 pt-2">
<button type="button" class="ml-1 flex h-10 w-10 items-center justify-center rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" #click="sidebarOpen = false">
<span class="sr-only">Close sidebar</span>
<XMarkIcon class="h-6 w-6 text-white" aria-hidden="true" />
</button>
</div>
</TransitionChild>
<div class="h-0 flex-1 overflow-y-auto pt-5 pb-4">
<div class="flex flex-shrink-0 items-center px-4">
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company" />
</div>
<nav class="mt-5 space-y-1 px-2">
<router-link v-for="item in navigation" :key="item.name" :to="item.to" class="['text-gray-300 hover:bg-gray-700 hover:text-white', 'group flex items-center px-2 py-2 text-base font-medium rounded-md']">
<component :is="item.icon" :class="[isActive ? 'text-gray-300' : 'text-gray-400 group-hover:text-gray-300', 'mr-4 flex-shrink-0 h-6 w-6']" aria-hidden="true" />
{{ item.name }}
</router-link>
</nav>
</div>
<div class="flex flex-shrink-0 bg-gray-700 p-4">
<a href="#" class="group block flex-shrink-0">
<div class="flex items-center">
<div>
<img class="inline-block h-10 w-10 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />
</div>
<div class="ml-3">
<p class="text-base font-medium text-white">Tom Cook</p>
<p class="text-sm font-medium text-gray-400 group-hover:text-gray-300">View profile</p>
</div>
</div>
</a>
</div>
</DialogPanel>
</TransitionChild>
<div class="w-14 flex-shrink-0">
<!-- Force sidebar to shrink to fit close icon -->
</div>
</div>
</Dialog>
</TransitionRoot>
<!-- Static sidebar for desktop -->
<div class="hidden md:fixed md:inset-y-0 md:flex md:w-64 md:flex-col">
<!-- Sidebar component, swap this element with another sidebar if you like -->
<div class="flex min-h-0 flex-1 flex-col bg-gray-800">
<div class="flex flex-1 flex-col overflow-y-auto pt-5 pb-4">
<div class="flex flex-shrink-0 items-center px-4">
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company" />
</div>
<nav class="mt-5 flex-1 space-y-1 px-2">
<RouterLink v-for="item in navigation" :key="item.name" :to="item.to" :class="[item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'group flex items-center px-2 py-2 text-sm font-medium rounded-md']">
<component :is="item.icon" :class="[item.current ? 'text-gray-300' : 'text-gray-400 group-hover:text-gray-300', 'mr-3 flex-shrink-0 h-6 w-6']" aria-hidden="true" />
{{ item.name }}
</RouterLink>
</nav>
</div>
<div class="flex flex-shrink-0 bg-gray-700 p-4">
<div class="group block w-full flex-shrink-0">
<div v-if="authenticated" class="flex items-center">
<div class="ml-3">
<p class="text-base font-medium text-white pl-2">:Username</p>
<RouterLink to="/">
<p class="text-xs font-medium text-gray-300 group-hover:text-gray-200">Logout</p>
</RouterLink>
</div>
</div>
<div v-else class="flex items-center">
<div class="ml-3">
<RouterLink to="/signin">
<p class="text-base font-medium text-gray-300 group-hover:text-gray-200">เข้าสู่ระบบ</p>
</RouterLink>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flex flex-1 flex-col md:pl-64">
<div class="sticky top-0 z-10 bg-gray-100 pl-1 pt-1 sm:pl-3 sm:pt-3 md:hidden">
<button type="button" class="-ml-0.5 -mt-0.5 inline-flex h-12 w-12 items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" #click="sidebarOpen = true">
<span class="sr-only">Open sidebar</span>
<Bars3Icon class="h-6 w-6" aria-hidden="true" />
</button>
</div>
<main class="flex-1">
<div class="py-6">
<div class="mx-auto max-w-7xl px-4 sm:px-6 md:px-8">
<!-- Replace with your content -->
<slot>
<RouterView/>
</slot>
<!-- /End replace -->
</div>
</div>
</main>
</div>
</div>
</template>

VueJS 3 changing background on clicking a container

Below is my code, I want to change background and text color on clicking the container that has a tailwind class of h-36. Can any one help me and come up with a solution to that issue.
<template>
<div>
<SideBar />
<NavBar />
<div class="mt-20 ml-24 mr-2 mb-2 bg-white h-screen flex">
<div class="flex w-1/3 flex-col divide-y overflow-auto">
<div class="h-20 text-black bg-white flex shadow-sm text-lg uppercase font-black w-full items-center px-4">
<span>Configurations</span>
</div>
<div class="overflow-y-scroll">
<div class="h-36 w-full bg-yellow-650 px-4 flex items-center cursor-pointer">
<DesktopComputerIcon class="text-white h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-white">
<h3 class="text-white text-base font-bold">Front Office</h3>
<p class="text-xs">
Manage front office settings and appointments
</p>
</div>
</div>
<div class="h-36 w-full bg-white px-4 flex items-center cursor-pointer">
<UserGroupIcon class="text-black h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-black">
<h2 class="text-black text-base font-bold">Patients</h2>
<p class="text-xs">
Manage patients infomation and settings
</p>
</div>
</div>
<div class="h-36 w-full bg-white px-4 flex items-center cursor-pointer">
<PhotographIcon class="text-black h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-black">
<h2 class="text-black text-base font-bold">Imaging</h2>
<p class="text-xs">
Settings and management for imaging
</p>
</div>
</div>
<div class="h-36 w-full bg-white px-4 flex items-center cursor-pointer" #click="showConfig('custom')">
<AdjustmentsIcon class="text-black h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-black">
<h2 class="text-black text-base font-bold">Custom Settings</h2>
<p class="text-xs">
Manage time slots, departments, and others
</p>
</div>
</div>
<div class="h-36 w-full bg-white px-4 flex items-center cursor-pointer" #click="showConfig('billing')">
<CashIcon class="text-black h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-black">
<h2 class="text-black text-base font-bold">Billing</h2>
<p class="text-xs">
Manage billing controls, currency, amounts, treatments
</p>
</div>
</div>
<div class="h-36 w-full bg-white px-4 flex items-center cursor-pointer">
<LibraryIcon class="text-black h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-black">
<h2 class="text-black text-base font-bold">Insurance</h2>
<p class="text-xs">
Manage insurance claims and payments
</p>
</div>
</div>
<div class="h-36 w-full bg-white px-4 flex items-center cursor-pointer" #click="showConfig('users')">
<UserIcon class="text-black h-12 w-12 flex-none"/>
<div class="flex flex-col w-3/4 ml-3 text-black">
<h2 class="text-black text-base font-bold">Users</h2>
<p class="text-xs">
Create new users, manage uses, edit and delete
</p>
</div>
</div>
</div>
</div>
<div class="flex w-2/3 p-10">
<div class="w-full overflow-auto">
<Billing v-if='billing'/>
<CustomsConfig v-if='custom'/>
<Users v-if='users'/>
</div>
</div>
</div>
</div>
</template>
<script>
import {
UserGroupIcon,
PhotographIcon,
AdjustmentsIcon,
CashIcon,
LibraryIcon,
UserIcon,
DesktopComputerIcon,
} from '#heroicons/vue/outline';
import { ref } from 'vue';
import SideBar from '#/components/shared/SideBar.vue';
import NavBar from '#/components/shared/NavBar.vue';
import Billing from '#/components/configurations/settings/ui/billing.vue';
import CustomsConfig from '#/components/configurations/settings/ui/customConfig.vue';
import Users from '#/components/configurations/settings/ui/allUsers.vue';
export default {
components: {
SideBar,
NavBar,
UserGroupIcon,
PhotographIcon,
AdjustmentsIcon,
CashIcon,
LibraryIcon,
UserIcon,
DesktopComputerIcon,
CustomsConfig,
Users,
Billing,
},
setup() {
const custom = ref(false);
const users = ref(false);
const billing = ref(false);
const showConfig = (config) => {
if (config === 'custom') {
custom.value = true;
users.value = false;
billing.value = false;
}
if (config === 'users') {
custom.value = false;
users.value = true;
billing.value = false;
}
if (config === 'billing') {
custom.value = false;
users.value = false;
billing.value = true;
}
};
return {
custom,
users,
billing,
showConfig,
};
},
};
</script>
Because I want when the user clicks that div it changes the background and text color and render a component on the right hand side.
You can simply bind class property in the container so it takes the desired value
<div :class="desiredClass" class="h-36 w-full.....
and in your showConfig function you can update the value of desiredClass accordingly
this.desiredClass = "h-26"
you may want also to declare desiredClass as a reactive state .

How to make a styled circle component using tailwindcss?

I am working on image upload component in my react app and I design the image uploader component.
Here is the code and the result respectively.
<div className="px-8 py-6 mt-2 text-left bg-white shadow-lg">
<form action="">
<div class="flex items-center justify-center bg-grey-lighter">
<label class=" flex flex-col items-center px-4 py-6 bg-white text-blue rounded-lg shadow-lg tracking-wide uppercase border border-blue cursor-pointer hover:bg-blue hover:text-white">
<AddAPhotoIcon />
<span class="mt-2 text-base leading-normal">Upload Photo</span>
<input type="file" class="hidden" />
</label>
</div>
</form>
</div>
But I want change it exactly as the following component.
Make sure you have the same width and height for the element you want circular, in combination with rounded-full.
I adapted your example and used h-40 and w-40 to control height and width. With rounded-full, the result is a circular component.
<div class="flex items-center justify-center">
<form action="">
<label class="text-blue border-blue hover:bg-blue flex h-40 w-40 cursor-pointer flex-col items-center justify-center rounded-full border bg-white uppercase tracking-wide shadow-lg hover:text-white">
<AddAPhotoIcon />
<span class="mt-2 text-base leading-normal">Upload Photo</span>
<input type="file" class="hidden" />
</label>
</form>
</div>
Is this you want ??
<script src="https://cdn.tailwindcss.com"></script>
<div class="p-10 w-72 border-4 border-gray-200 rounded-full">
<div class="bg-gray-300 p-20 w-52 rounded-full text-center">
Upload <br/>Photo
</div>
</div>

Vue why click event not working in v-if or v-show

i am trying to fire click event from div but if v-if false on component rendering click event not working
here my code:
export default {
name: "ProSelect",
data() { return {
isActive: false,
}},
methods: {
select(event) {
console.log('ID :' + event.currentTarget.id);
}
}
}
<div
v-if="isActive"
class="absolute shadow bg-white top-100 z-40 w-full lef-0 rounded max-h-select overflow-y-auto">
<div class="flex flex-col w-full">
<div
id="foo"
#click="select($event)"
class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-teal-100 hover:bg-gray-100 hover:border-indigo-500">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-teal-100">
<div class="w-full items-center flex">
<div class="mx-2 -mt-1">
Jack jhon
</div>
</div>
</div>
</div>
<div
id="foo2"
v-on:click="select($event)"
class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-teal-100 hover:bg-gray-100 hover:border-indigo-500">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-teal-100">
<div class="w-full items-center flex">
<div class="mx-2 -mt-1">
Jack jhon 2
</div>
</div>
</div>
</div>
</div>
</div>
if i change isActive variable to true on rendering click is working
i found the answer but i wonder why this is not working.If i use #mousedown.prevent instead of #click its working
I am not sure if I get it correctly but as per the code you posted. Your parent div will be removed from the DOM as v-if is false. You can assign isActive as true while mounting.
Working Demo :
new Vue({
el: '#app',
data() {
return {
isActive: false,
}
},
methods: {
select(event) {
console.log('ID :' + event.currentTarget.id);
}
},
mounted() {
this.isActive = true;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div
v-if="isActive"
class="absolute shadow bg-white top-100 z-40 w-full lef-0 rounded max-h-select overflow-y-auto">
<div class="flex flex-col w-full">
<div
id="foo"
#click="select($event)"
class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-teal-100 hover:bg-gray-100 hover:border-indigo-500">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-teal-100">
<div class="w-full items-center flex">
<div class="mx-2 -mt-1">
Jack jhon
</div>
</div>
</div>
</div>
<div
id="foo2"
v-on:click="select($event)"
class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-teal-100 hover:bg-gray-100 hover:border-indigo-500">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-teal-100">
<div class="w-full items-center flex">
<div class="mx-2 -mt-1">
Jack jhon 2
</div>
</div>
</div>
</div>
</div>
</div>
</div>
this is whole template code
<template>
<div>
<div class="flex flex-col items-center">
<div class="w-full flex flex-col items-center">
<div class="w-full">
<div class="flex flex-col items-center relative">
<div class="w-full">
<div class="flex">
<div class="flex flex-auto flex-wrap"></div>
<input
class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:rounded-none focus:rounded-t-lg focus:border-b-0 focus:bg-white focus:border-indigo-500 border-transparent focus:border-transparent focus:ring-0"
type="text"
v-model="selected"
:name="name"
#focusin="isActive = !isActive"
#focusout="isActive = !isActive"
placeholder="Search by position">
</div>
</div>
<div
v-if="isActive"
class="absolute shadow bg-white top-100 z-40 w-full lef-0 rounded max-h-select overflow-y-auto">
<div class="flex flex-col w-full">
<div
id="foo"
#click="select($event)"
class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-teal-100 hover:bg-gray-100 hover:border-indigo-500">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-teal-100">
<div class="w-full items-center flex">
<div class="mx-2 -mt-1">
Jack jhon
</div>
</div>
</div>
</div>
<div
id="foo2"
v-on:click="select($event)"
class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-teal-100 hover:bg-gray-100 hover:border-indigo-500">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-teal-100">
<div class="w-full items-center flex">
<div class="mx-2 -mt-1">
Jack jhon 2
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>

how to duplicate a form using alpine.js

Given a form with a couple of input form fields, for example:
(the style is based on tailwindcss if it plays a role)
<div>
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">Profile</h3>
<p class="mt-1 text-sm text-gray-600">
This information will be displayed publicly so be careful what you share.
</p>
</div>
</div>
<div class="mt-5 md:mt-0 md:col-span-2">
<form action="#" method="POST">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="px-4 py-5 bg-white space-y-6 sm:p-6">
<!-- todo: duplicate the input form fields -->
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<label for="first_name" class="block text-sm font-medium text-gray-700">First name</label>
<input type="text" name="first_name" id="first_name" autocomplete="given-name" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
</div>
<div class="col-span-6 sm:col-span-3">
<label for="last_name" class="block text-sm font-medium text-gray-700">Last name</label>
<input type="text" name="last_name" id="last_name" autocomplete="family-name" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
</div>
</div>
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<button type="button" #click="duplicate(idx)" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
+
</button>
</div>
</div>
</form>
</div>
</div>
</div>
How to add dynamically / duplicate the two form fields (first name, last name) when the end user clicks on the + button (duplicate(idx) function), using alpine.js ?

Categories