Skip to main content

Letz

The letz attribute is the cornerstone of Gen-Z.js state management, providing seamless two-way data binding between HTML elements and application state. It initializes variables and automatically synchronizes values between the DOM and your application's state.

Overview​

The letz attribute creates reactive variables that automatically update the UI when their values change. It's perfect for building interactive forms, dynamic content, and real-time applications without writing JavaScript.

Basic Syntax​

<element letz="variableName"></element>

How It Works​

  1. Initialization: Creates a variable in the global state with the element's current value
  2. Two-way Binding: Automatically listens for changes and updates both the state and UI
  3. Type Conversion: Optionally converts values to specific data types
  4. Reactive Updates: Triggers updates to all elements using the same variable

Basic Examples​

Text Input Binding​

<input type="text" letz="username" placeholder="Enter your username" />
<p>Hello, <span getz="username"></span>!</p>

Number Input​

<input type="number" letz="age" value="25" />
<p>You are <span getz="age"></span> years old.</p>

Checkbox Binding​

<input type="checkbox" letz="isSubscribed" checked />
<p>Subscription status: <span getz="isSubscribed"></span></p>

Typed Variables​

You can specify a data type for your state variable by appending it after a colon:

Syntax​

<element letz="variableName:Type"></element>

Supported Types​

String (Default)​

<input type="text" letz="name:String" value="John" />
  • Default behavior if no type is specified
  • Stores value as-is as a string

Number​

<input type="number" letz="age:Number" value="25" />
<input type="range" letz="volume:Number" min="0" max="100" value="50" />
  • Automatically converts input values to numbers
  • Non-numeric values become NaN

Boolean​

<input type="checkbox" letz="isActive:Boolean" checked />
<input type="text" letz="hasPermission:Boolean" value="true" />
  • For checkboxes: uses the checked property
  • For other inputs: "true", "1", or any non-empty string = true
  • Empty string, "false", or "0" = false

Object​

<textarea letz="config:Object">{"theme": "dark", "lang": "en"}</textarea>
<div letz="user:Object" style="display: none;">
{"name": "Alice", "role": "admin"}
</div>
  • Parses valid JSON strings into JavaScript objects
  • Invalid JSON will result in an error

Null​

<input type="hidden" letz="placeholder:Null" />
  • Sets the variable value to null
  • Useful for placeholder variables

Undefined​

<input type="hidden" letz="feature:Undefined" />
  • Sets the variable value to undefined
  • Useful for optional features

Advanced Examples​

Form with Multiple Types​

<form>
<input type="text" letz="fullName:String" placeholder="Full Name" />
<input type="number" letz="age:Number" placeholder="Age" />
<input type="email" letz="email:String" placeholder="Email" />
<input type="checkbox" letz="newsletter:Boolean" /> Subscribe to newsletter

<div>
<p>Name: <span getz="fullName"></span></p>
<p>Age: <span getz="age"></span></p>
<p>Email: <span getz="email"></span></p>
<p>Newsletter: <span getz="newsletter"></span></p>
</div>
</form>

Complex Object Binding​

<textarea letz="userProfile:Object" rows="5">
{
"name": "John Doe",
"settings": {
"theme": "dark",
"notifications": true
}
}
</textarea>

<p>User: <span getz="userProfile.name"></span></p>
<p>Theme: <span getz="userProfile.settings.theme"></span></p>

Dynamic Counter​

<input type="number" letz="count:Number" value="0" />
<button setz="count:count + 1">Increment</button>
<button setz="count:count - 1">Decrement</button>
<p>Count: <span getz="count"></span></p>

Element Type Behaviors​

Input Elements​

<!-- Text inputs -->
<input type="text" letz="textValue" />
<input type="email" letz="email" />
<input type="password" letz="password" />

<!-- Number inputs -->
<input type="number" letz="quantity:Number" />
<input type="range" letz="volume:Number" />

<!-- Checkboxes -->
<input type="checkbox" letz="agreed:Boolean" />

<!-- Radio buttons -->
<input type="radio" name="size" value="small" letz="selectedSize" />
<input type="radio" name="size" value="large" letz="selectedSize" />

Textarea​

<textarea letz="description" rows="4" cols="50"></textarea>

Select Elements​

<select letz="country">
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="uk">United Kingdom</option>
</select>

Non-Input Elements​

<!-- Hidden data containers -->
<div letz="config:Object" style="display: none;">
{"api": "https://api.example.com"}
</div>
<span letz="version" style="display: none;">1.2.3</span>

Best Practices​

✅ Do​

  • Use descriptive variable names (userName, not u)
  • Specify types when working with numbers or booleans
  • Initialize with sensible default values
  • Group related variables logically

❌ Don't​

  • Use reserved JavaScript keywords as variable names
  • Create circular dependencies between variables
  • Modify letz variables directly via JavaScript (use setz instead)

Common Patterns​

User Profile Form​

<div class="profile-form">
<input type="text" letz="profile.firstName:String" placeholder="First Name" />
<input type="text" letz="profile.lastName:String" placeholder="Last Name" />
<input type="number" letz="profile.age:Number" placeholder="Age" />
<input type="checkbox" letz="profile.isPublic:Boolean" /> Make profile public

<div class="preview">
<h3>Profile Preview</h3>
<p>
Name: <span getz="profile.firstName"></span>
<span getz="profile.lastName"></span>
</p>
<p>Age: <span getz="profile.age"></span></p>
<p>Public: <span getz="profile.isPublic"></span></p>
</div>
</div>

Settings Panel​

<div class="settings">
<label>
<input type="checkbox" letz="settings.darkMode:Boolean" />
Dark Mode
</label>

<label>
Volume:
<input
type="range"
letz="settings.volume:Number"
min="0"
max="100"
value="50"
/>
<span getz="settings.volume"></span>%
</label>

<select letz="settings.language:String">
<option value="en">English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
</select>
</div>

Troubleshooting​

Common Issues​

Variable Not Updating​

<!-- ❌ Wrong: Missing getz to display -->
<input type="text" letz="name" />
<p>Hello, name!</p>

<!-- ✅ Correct: Use getz to display -->
<input type="text" letz="name" />
<p>Hello, <span getz="name"></span>!</p>

Type Conversion Errors​

<!-- ❌ Wrong: Invalid JSON -->
<textarea letz="data:Object">{invalid json}</textarea>

<!-- ✅ Correct: Valid JSON -->
<textarea letz="data:Object">{"valid": "json"}</textarea>

Case Sensitivity​

<!-- ❌ Wrong: Mismatched case -->
<input type="text" letz="userName" />
<span getz="username"></span>

<!-- ✅ Correct: Exact match -->
<input type="text" letz="userName" />
<span getz="userName"></span>

Browser Compatibility​

The letz attribute works in all modern browsers:

  • Chrome/Edge 60+
  • Firefox 55+
  • Safari 12+
  • Mobile browsers (iOS Safari, Chrome Mobile)

Performance Considerations​

  • Variables are stored in a global state object
  • Updates are batched for optimal performance
  • Large objects may impact performance on slower devices
  • Consider using hidez for data-only elements
  • getz - Display variable values
  • hidez - Hide elements containing data
  • clickz - Handle user interactions

Migration from Vanilla JavaScript​

Before (Vanilla JavaScript)​

let username = "";
const input = document.getElementById("usernameInput");
const display = document.getElementById("usernameDisplay");

input.addEventListener("input", (e) => {
username = e.target.value;
display.textContent = username;
});

After (Gen-Z.js)​

<input type="text" letz="username" /> <span getz="username"></span>

The letz attribute eliminates the need for manual event listeners and DOM manipulation, making your code cleaner and more maintainable.