Replies: 5 comments 4 replies
-
I probably need more details to understand your situation. If this isn't working, what's the actual behavior vs. what's the expected behavior. Also, it would be helpful to have a way to preview your app so that it can be debugged. |
Beta Was this translation helpful? Give feedback.
-
The goal is a nested modal. so you open a modal menu, which has a button to open another modal menu etc, each level of modal should have a clickable background input blocker which only closes that modal and leaves all others open. |
Beta Was this translation helpful? Give feedback.
-
const { button, div } = van.tags
const dropdowns = vanX.reactive([])
const Dropdowns = () => {
return vanX.list(div({ class: 'absolute noInput fill' }), dropdowns, dropdown => {
prnt('dropdown func ', dropdown)
return div({
class: 'input absolute fill red',
style: '',
onclick: (e) => {
prnt('click')
vanX.replace(dropdowns, dropdowns.filter(d => d.func !== dropdown.func))
},
}, dropdown.func)
})
}
function showDropdown(dropdown, e) {
const target = e.target
const targetPos = target.getBoundingClientRect()
const pos = { x: targetPos.left, y: targetPos.top + targetPos.height }
dropdowns.push({
func: dropdown,
pos
})
}
const File = () => {
return div('File', button({ onclick: (e) => { showDropdown(Help(), e) } }, 'Help'))
}
const Help = () => {
return div('Help')
}
const Home = () => {
const el = div(
{ class: 'bigButtons panel', style: 'width:15rem;' },
button({ onclick: (e) => { showDropdown(File(), e) } }, 'File'),
Dropdowns()
)
return el
}
van.add(document.body, Home()) File and Help do not appear when clicking the button to fire showDropdown |
Beta Was this translation helpful? Give feedback.
-
@sirenkovladd Thank you, () => dropdown.val.func did the trick. Here is the final nested modals component: const dropdowns = vanX.reactive([])
const Dropdowns = () => {
return vanX.list(div({ class: 'absolute noInput fill' }), dropdowns, dropdown => {
return div({
class: 'fill dark absolute dropdownbackdrop input',
onclick: (e) => {
if (e.target.classList.contains('dropdownbackdrop')) {
timers.dropdown = requestAnimationFrame(() => {
console.log('click outside modal')
vanX.replace(dropdowns, dropdowns.slice(0, -1))
})
}
},
}, div({ style: `position:absolute;left:${dropdown.val.pos.x}px;top:${dropdown.val.pos.y}px;` }, () => dropdown.val.func))
})
}
function showDropdown (dropdown, e, position = 'bottom') {
const target = e.target
const targetPos = target.getBoundingClientRect()
let pos = { x: targetPos.left, y: targetPos.top + targetPos.height }
switch (position) {
case 'right':
pos = { x: targetPos.left + targetPos.width + 4, y: targetPos.top - 3 }
break
}
dropdowns.push({
func: vanX.noreactive(dropdown),
pos
})
} |
Beta Was this translation helpful? Give feedback.
-
function showDropdown (dropdown, e, position = 'bottom') {
const target = e.target
const targetPos = target.getBoundingClientRect()
let pos = { x: targetPos.left, y: targetPos.top + targetPos.height }
switch (position) {
case 'right':
pos = { x: targetPos.left + targetPos.width + 4, y: targetPos.top - 3 }
break
}
const modal = { func: vanX.noreactive(dropdown), pos }
dropdowns.push({ func: vanX.noreactive(dropdown), pos })
timers.dropdown2 = setTimeout(() => { clampToWindow2(dropdowns[dropdowns.length - 1].func) }, 200)
} Adding this line function clampToWindow2 (element) {
timers.clamp = requestAnimationFrame(() => {
const rect = element.getBoundingClientRect()
const windowHeight = window.innerHeight
const windowWidth = window.innerWidth
const maxX = windowWidth - rect.width
const maxY = windowHeight - rect.height
const clampedX = Math.min(maxX, Math.max(0, rect.left))
const clampedY = Math.min(maxY, Math.max(0, rect.top))
prnt('clamp 2', clampedX, clampedY)
element.style.left = clampedX + 'px'
element.style.top = clampedY + 'px'
})
} it was working fine in this single dropdown version: const showDropdown = () => {
if (dropdown.val) { dropdown.val = false; state.isOpen = false; return }
state.isOpen = true
dropdown.val = DropdownMenu({ x: inp.start.x, y: inp.start.y })
timers.toggleDropdown = requestAnimationFrame(() => {
clampToWindow2(dropdown.val)
timers.toggleDropdown2 = requestAnimationFrame(() => {
dropdown.val.classList.remove('transparent')
})
})
} How can I get this to work with the dropdowns array version? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm trying to create a nested modal system:
So you can open nested menus within menus and close them one level at a time. This approach isn't working, is there a more vanJS way to do it?
Beta Was this translation helpful? Give feedback.
All reactions