I have a Vue3 app that has a form in it. The app also uses the vue router. In the form, I have a textarea. I've added a #submit.prevent to the form, but then I hit enter in the textarea the page redirects to its parent component. When I click the button it behaves correctly. Only when I hit the enter key in the textarea the redirect occurs.
A minimal example looks like this:
<template>
<div class="">
<form #submit.prevent="validate()" class="flex flex-col">
<textarea
class="mt-0 block w-full px-0.5 bg-white text-black border-0 border-b-2 border-primary focus:ring-0 focus:border-other"
rows="2"
>
</textarea>
<button type="submit">Test</button>
</form>
</div>
</template>
<script>
export default {
setup() {
const validate = () => {
console.log(`check if validated`);
};
return {
validate,
};
},
};
</script>
Related
I Have this form with the transition
this is the problem:
https://youtu.be/cgtBNKRgJwQ
I want the magnifying glass to stay fixed, and the form to move
my code:
import Search from './Icons/SearchIcon';
export default function SearchForm() {
return (
<div className="flex">
<input
id="input"
className="transition-[width] duration-[1500ms] text-sm focus:pl-3 focus:outline-none focus:p-1 w-0 focus:w-full border-y border-l bg-white border-slate-200"
/>
<label className="border-y border-r p-1 border-slate-200" htmlFor="input">
<Search />
</label>
</div>
);
}
Looks like your animation does what you want.
Your component is almost ready, it's just missing ONE class to do what you want:
Add justify-end on your main div, it should do the trick.
There's an issue when using v-model to div tags. Apparently, div tags doesn't allow v-model and I've decided to create my comment section as a component. I needed to assign this div text area as is because of UI/UX reasons. textarea, input, etc tags, as to my knowledge, these tags are not compatible with contenteditable="true"; I need to expand the height of the input field as a user types in their comments. Below is the vue component that I imported in my parent view.
<!-- CommentSection.vue -->
<template>
<div id="chatId" contenteditable="true" placeholder="Leave a message" class="overflow-hidden block mx-4 text-left p-2.5 w-full text-sm text-gray-900 bg-white rounded-2xl border border-gray-300 focus:ring-blue-500 focus:border-blue-500"/>
</template>
<style>
#chatId[contenteditable="true"]:empty:not(:focus):before {
content: attr(placeholder)
}
</style>
On my view file, I imported it and used v-model into it, just like this.
<!--MainPage.vue-->
<template>
...
...
<CommentSection v-model="comment"/>
<button #click="submitPost()"> Submit </button>
...
...
...
</template>
<script>
import CommentSection from '#/components/CommentSection.vue'
export default{
name: 'MainPage',
data(){
return{
comment: '',
}
},
components: { CommentSection },
methods:{
submitPost(){
console.log(this.comment);
},
},
}
</script>
However, when I check my console, it gives me the value "null" or just nothing. Is there's a way to fix this? Or is it the way I implemented it that causes the problem.
EDIT: Here's the running code in codesandbox.
I solved your problem and the code is as follows. I hope I have helped
By adding # to the div tag, we can see the changes in the content of the tag in the change method. And in that method, use emit$ to share its value with other components
<!-- CommentSection.vue -->
<template>
<div id="chatId" #input="chanage" contenteditable="true" placeholder="Leave a message" class="overflow-hidden block mx-4 text-left p-2.5 w-full text-sm text-gray-900 bg-white rounded-2xl border border-gray-300 focus:ring-blue-500 focus:border-blue-500"/>
</template>
<script>
export default {
methods: {
chanage (e) {
this.$emit('value-div', e.target.textContent)
}
}
}
</script>
<style>
#chatId[contenteditable="true"]:empty:not(:focus):before {
content: attr(placeholder)
}
</style>
And here we have the props created by $emit, whose value we initialize in the comment variable. Actually, it has a function similar to v-model.
<!--MainPage.vue-->
<template>
...
...
<CommentSection #value-div="(value)=>comment = value"/>
<button #click="submitPost()"> Submit </button>
...
...
...
</template>
<script>
import CommentSection from '#/components/CommentSection.vue'
export default{
name: 'MainPage',
data(){
return{
comment: '',
}
},
components: { CommentSection },
methods:{
submitPost(){
console.log(this.comment);
},
},
}
</script>
I need to redirect users using onkeypress in nextjs.
I have a search input where users can type and then press enter key to go to the other page.
What I've tried:
const handler = (e) => {
const ENTER = 13;
if (e.keyCode === ENTER) // do a history.push("/news");
console.log("enter");
};
<input
onKeyPress={(e) => handler(e)}
type="text"
name="search"
placeholder="Search by keywords"
className="p-4 md:p-6 w-full py-2 md:py-4 border-2 text-lg md:text-2xl xl:text-3xl border-gray-400 outline-none filosofia_italic bg-white placeholder-gray-400"
/>
i would appreciate your help.
This is covered by the documentation:
Imperatively
next/link should be able to cover most of your routing needs, but you
can also do client-side navigations without it, take a look at the
documentation for next/router.
The following example shows how to do basic page navigations with
useRouter:
import { useRouter } from 'next/router'
export default function ReadMore() {
const router = useRouter()
return (
<button onClick={() => router.push('/about')}>
Click here to read more
</button>
)
}
You can use the useRouter hook from next - https://nextjs.org/docs/api-reference/next/router
Try changing you handler to
import {useRouter} from "next/router";
const Component = () => {
const router = useRouter();
const handler = (e) => {
...
router.push("/news");
}
return (
<input
onKeyPress={handler}
type="text"
name="search"
placeholder="Search by keywords"
className="p-4 md:p-6 w-full py-2 md:py-4 border-2 text-lg
md:text-2xl xl:text-3xl border-gray-400 outline-none
filosofia_italic bg-white placeholder-gray-400"
/>
)
}
I've been trying to change the 'ModalOn' state which is created inside of the medCardSong.js file, and I've been trying to change that state from inside of the 'SongModal.js' file, which is a child component inside of medCardSong.js.
I've inputted the changeState function 'SetModalOn' as a prop to the SongModal.js component, and i've tried changing the state through that.
Here's medCardSong.js:
import React, { useEffect } from 'react';
import { useState} from 'react';
import SongModal from '../modals/SongModal';
function MediumCardSong(props) {
const [ModalOn, SetModalOn] = useState(false);
function killme() {
SetModalOn(false);
console.log(7)
}
console.log(ModalOn)
return (
<div className={" flex flex-col m-2 overflow-hidden duration-300 w-52 " + (ModalOn
? 'transition-none' : 'hover:scale-105 transition-all')} onClick={() =>
{SetModalOn(true);}}>
<img className='object-cover rounded-3xl'
src="https://i0.wp.com/coolhunting.com/wp-content/uploads/2022/07/steve-lacy-
bad-habit.jpg?fit=586%2C586&ssl=1" alt="" />
<div className='pb-2'>
<div className='flex'>
<div className='px-2 pt-2 text-2xl font-bold text-gray-400'>#1</div>
<div className='pl-3 text-xl pt-2 text-white'>Mercury</div>
</div>
<div className='text-left pl-5 text-gray-500'>Steve Lacy</div>
</div>
{ModalOn && <SongModal CloseModal={killme} />}
</div>
);
}
export default MediumCardSong;
and here's SongModal.js:
import React from 'react'
function SongModal(props) {
// setTimeout(() => {props.CloseModal(false)}, 1000)
return (
<div className="bg-neutral-800 bg-opacity-60 fixed inset-0 z-50 backdrop-blur-sm">
<div className="flex h-screen justify-center items-center">
<div className="justify-center bg-neutral-700 py-12 px-24 border-4 border-
pearmint rounded-xl text-xl text-white" >
<button className='text-3xl text-white pr-24 pb-24'
onClick={() => {props.CloseModal()}} >X</button>
sad
</div>
</div>
</div>
)
};
export default SongModal;
The imported CloseModal function works as intended when it's applied outside of the jsx. For example, the "SetTimeOut" piece of code would work properly if it's uncommmented. However this doesn't happen when I call "CloseModal" inside of an Onclick event-handler, such as the call I did for the 'x' Button.
I've also used console.log to see if the button has been registering the clicks I make and it has been. So I'm confused as to why the props.CloseModal function does not work as intended inside the OnClick event listener. Please give advice if you can.
try to call it inside of a hook
function SongModal(props) {
const close = () => {
props.CloseModal()
}
return (
<div>
<button onClick={close}>Close Btn</button>
</div>
)
};
also check the following acritical
link
I had created some cards from an array of objects, now I want to show popup data for each card differently.
here is my code of printing
{data.carData.map( single=>(<li>{ <div onClick={handleClick}><Card single={single}/></div>} </li>))}
for this, I want the card name onClick event, but when I pass anything in the handleClick react throw an error of too many re-renders.
if I do the same onClick event inside the card component and log it prints all the cards names one by one
here is what is inside the card:
function Card({single}) {
const [flowName, setflowName] = useState();
const handleClick=(e)=>{
setflowName(e);
return
}
console.log("loging name:",flowName);
return (
<div className="main mb-2 z-0" onClick={handleClick(e=>single?.flowName)} >
<div className=" inner_main_container pt-4 px-8 bg-white shadow-lg rounded-lg ">
<div className="flex justify-between">
<div className="flex flex-row align-center">
</div>
{single?.badge.map(badge=>(
<div className={"badge"} key={badge}>
<span className={badge==="Growth"?" badgeClrG":(badge==="Content"?"content":"badgeClrO")} key={badge}>{badge}</span>
</div>
) )}
</div>
<div className="flex justify-center">
<img src={single?.image} alt={single?.flowName} />
</div>
<div >
<div className={"mt-2 flex justify-center"}>
<h1>{single?.flowName}</h1>
</div>
</div>
</div>
</div>
) } export default Card
I suspect you're doing this when you're trying to pass a value:
single=>(<li>{ <div onClick={handleClick(value)}><Card single={single}/></div>} </li>))}
Every time this is rendered, the function is invoked straight away, which causes another render and so on...
The solution is to wrap your handleClick call in another function:
single=>(<li>{ <div onClick={()=>handleClick(value)}><Card single={single}/></div>} </li>))}