refs Plugin
The refs plugin is a built-in Coralite helper that provides runtime DOM element access. It allows template scripts to safely access and manipulate DOM elements by their ref attributes.
Basic Usage #
Here's the complete workflow for using refs:
<template id="form-component">
<form>
<input type="text" ref="username" placeholder="Username"></input>
<input type="password" ref="password" placeholder="Password"></input>
<button type="button" ref="submitBtn">Submit</button>
</form>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
script: (context, helpers) => {
const refs = helpers.refs
const username = refs('username')
const password = refs('password')
const submitBtn = refs('submitBtn')
submitBtn.addEventListener('click', () => {
if (username.value && password.value) {
console.log('Login:', username.value)
// Handle form submission
} else {
alert('Please fill all fields')
}
})
}
})
</script>
Complete Examples #
Interactive Counter #
<template id="counter">
<div class="counter">
<h2>Count: {{ count }}</h2>
<button type="button" ref="increment">+</button>
<button type="button" ref="decrement">-</button>
<button type="button" ref="reset">Reset</button>
</div>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
tokens: {
count: ({ initial }) => parseInt(initial) || 0
},
script: (context, helpers) => {
const refs = helpers.refs
const increment = refs('increment')
const decrement = refs('decrement')
const reset = refs('reset')
let count = context.values.count
const counterDisplay = document.querySelector('h2')
increment.addEventListener('click', () => {
count++
counterDisplay.textContent = `Count: ${count}`
})
decrement.addEventListener('click', () => {
count--
counterDisplay.textContent = `Count: ${count}`
})
reset.addEventListener('click', () => {
count = 0
counterDisplay.textContent = `Count: ${count}`
})
}
})
</script>
Dynamic Form Validation #
<template id="signup-form">
<form>
<div>
<input type="email" ref="email" placeholder="Email"></input>
<span ref="emailError" class="error"></span>
</div>
<div>
<input type="password" ref="password" placeholder="Password"></input>
<span ref="passwordError" class="error"></span>
</div>
<button type="button" ref="submitBtn">Sign Up</button>
</form>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
script: (context, helpers) => {
const refs = helpers.refs
const email = refs('email')
const password = refs('password')
const emailError = refs('emailError')
const passwordError = refs('passwordError')
const submitBtn = refs('submitBtn')
const validateEmail = (email) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
const validatePassword = (password) => {
return password.length >= 8
}
submitBtn.addEventListener('click', () => {
let valid = true
// Validate email
if (!validateEmail(email.value)) {
emailError.textContent = 'Invalid email format'
valid = false
} else {
emailError.textContent = ''
}
// Validate password
if (!validatePassword(password.value)) {
passwordError.textContent = 'Password must be 8+ characters'
valid = false
} else {
passwordError.textContent = ''
}
if (valid) {
console.log('Form submitted:', email.value)
// Submit form
}
})
}
})
</script>
Tabbed Interface #
<template id="tabs">
<div class="tabs">
<div class="tab-buttons">
<button type="button" ref="tab1">Tab 1</button>
<button type="button" ref="tab2">Tab 2</button>
<button type="button" ref="tab3">Tab 3</button>
</div>
<div class="tab-content">
<div ref="content1">Content 1</div>
<div ref="content2" style="display:none">Content 2</div>
<div ref="content3" style="display:none">Content 3</div>
</div>
</div>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
script: (context, helpers) => {
const refs = helpers.refs
const buttons = [refs('tab1'), refs('tab2'), refs('tab3')]
const contents = [refs('content1'), refs('content2'), refs('content3')]
buttons.forEach((btn, index) => {
btn.addEventListener('click', () => {
// Hide all contents
contents.forEach(content => {
content.style.display = 'none'
})
// Show selected content
contents[index].style.display = 'block'
// Update button states
buttons.forEach(b => b.classList.remove('active'))
btn.classList.add('active')
})
})
}
})
</script>
Key Points #
- Runtime Access:
helpers.refs('refName')gets DOM elements - Automatic Caching: Elements cached after first access
- Safe Queries: Returns null if element not found