Appearance
x🔛click Directive ​
The x:on:click directive is used to bind click event handlers to HTML elements.
Basic Usage ​
Syntax ​
html
<!-- Without parameters -->
<button x:on:click="methodName">Click</button>
<!-- With parameters -->
<button x:on:click="methodName(arg1, arg2)">Click</button>
<!-- Event object -->
<button x:on:click="handleClick($event)">Click</button>
<!-- Element reference -->
<button x:on:click="handleClick($target)">Click</button>Special Parameters ​
$event - Event Object ​
typescript
@Widget({
selector: '.event-widget',
template: '<button x:on:click="handleClick($event)">Click</button>'
})
export class EventWidget {
handleClick(event: MouseEvent): void {
console.log('Click position:', event.clientX, event.clientY);
event.preventDefault();
event.stopPropagation();
}
}$target - Event Target ​
typescript
@Widget({
selector: '.target-widget',
template: '<button x:on:click="handleClick($target)">Click</button>'
})
export class TargetWidget {
handleClick(target: HTMLElement): void {
console.log('Clicked element:', target.tagName);
target.classList.add('clicked');
}
}$element - Bound Element ​
typescript
@Widget({
selector: '.element-widget',
template: '<button x:on:click="handleClick($element)">Click</button>'
})
export class ElementWidget {
handleClick(element: HTMLElement): void {
console.log('Bound element:', element);
}
}Examples ​
Passing Parameters ​
typescript
@Widget({
selector: '.params-widget',
template: `
<div>
<button x:on:click="addItem('Apple')">Add Apple</button>
<button x:on:click="addItem('Pear')">Add Pear</button>
<button x:on:click="setCount(10)">Set to 10</button>
<ul>
<template x:for="item in items">
<li x:text="item">-</li>
</template>
</ul>
</div>
`
})
export class ParamsWidget {
@xproperty()
items: string[] = [];
@xproperty()
count: number = 0;
addItem(item: string): void {
this.items.push(item);
}
setCount(value: number): void {
this.count = value;
}
}Parameter with Property ​
typescript
@Widget({
selector: '.dynamic-params-widget',
template: `
<div>
<input type="text" x:model="newItem">
<button x:on:click="addItem(newItem)">Add</button>
<button x:on:click="updateMessage(userName)">Update</button>
</div>
`
})
export class DynamicParamsWidget {
@xproperty()
newItem: string = '';
@xproperty()
userName: string = 'User';
@xproperty()
items: string[] = [];
addItem(item: string): void {
if (item.trim()) {
this.items.push(item);
this.newItem = '';
}
}
updateMessage(name: string): void {
console.log('Hello,', name);
}
}Event Details ​
typescript
@Widget({
selector: '.event-details-widget',
template: `
<div>
<button x:on:click="showDetails($event)">Show Details</button>
<p x:text="eventInfo">-</p>
</div>
`
})
export class EventDetailsWidget {
@xproperty()
eventInfo: string = '';
showDetails(event: MouseEvent): void {
this.eventInfo = `
X: ${event.clientX},
Y: ${event.clientY},
Button: ${event.button},
Ctrl: ${event.ctrlKey ? 'Yes' : 'No'}
`;
}
}Usage Inside Loop ​
typescript
@Widget({
selector: '.list-widget',
template: `
<div>
<template x:for="(item, index) in items">
<div>
<span x:text="item.name">-</span>
<button x:on:click="editItem(index)">Edit</button>
<button x:on:click="deleteItem(index)">Delete</button>
</div>
</template>
</div>
`
})
export class ListWidget {
@xproperty()
items: Array<{name: string}> = [
{ name: 'Item 1' },
{ name: 'Item 2' }
];
editItem(index: number): void {
console.log('Editing:', this.items[index]);
}
deleteItem(index: number): void {
this.items.splice(index, 1);
}
}Toggle Example ​
typescript
@Widget({
selector: '.toggle-widget',
template: `
<div>
<button x:on:click="toggle">
<span x:text="isActive ? 'Close' : 'Open'">-</span>
</button>
<div x:if="isActive">
<p>Content is visible</p>
</div>
</div>
`
})
export class ToggleWidget {
@xproperty()
isActive: boolean = false;
toggle(): void {
this.isActive = !this.isActive;
}
}Form Operations ​
typescript
@Widget({
selector: '.form-widget',
template: `
<form>
<input type="text" x:model="username">
<input type="password" x:model="password">
<button type="button" x:on:click="handleSubmit($event)">
Submit
</button>
<button type="button" x:on:click="handleReset">
Reset
</button>
</form>
`
})
export class FormWidget {
@xproperty()
username: string = '';
@xproperty()
password: string = '';
handleSubmit(event: Event): void {
event.preventDefault();
console.log('Submitting form:', {
username: this.username,
password: this.password
});
}
handleReset(): void {
this.username = '';
this.password = '';
}
}Multiple Parameters ​
typescript
@Widget({
selector: '.multi-params-widget',
template: `
<button x:on:click="createUser('Ahmet', 25, true)">
Create User
</button>
<button x:on:click="logData($event, userName, userAge)">
Log
</button>
`
})
export class MultiParamsWidget {
@xproperty()
userName: string = 'Test';
@xproperty()
userAge: number = 30;
createUser(name: string, age: number, isActive: boolean): void {
console.log('Created:', { name, age, isActive });
}
logData(event: Event, name: string, age: number): void {
console.log('Event:', event);
console.log('Data:', { name, age });
}
}Visual Feedback ​
Click events are automatically marked with CSS classes:
typescript
@Widget({
selector: '.feedback-widget',
template: '<button x:on:click="handleClick">Click</button>',
styles: [`
button.xcon-clickable {
cursor: pointer;
}
button.xcon-clicked {
transform: scale(0.95);
transition: transform 0.15s;
}
`]
})
export class FeedbackWidget {
handleClick(): void {
console.log('Clicked!');
}
}Automatic classes:
xcon-clickable: Added during element setupxcon-clicked: Added for 150ms during click
Nested Method Calls ​
typescript
class UserService {
save(data: any): void {
console.log('Saving:', data);
}
}
@Widget({
selector: '.service-widget',
template: '<button x:on:click="userService.save(userData)">Save</button>'
})
export class ServiceWidget {
@xproperty()
userService = new UserService();
@xproperty()
userData = { name: 'Test' };
}Best Practices ​
✅ Correct ​
typescript
// Simple and clear method names
handleClick(): void { }
onSubmit(): void { }
deleteItem(id: number): void { }
// Use event when needed
handleClick(event: MouseEvent): void {
event.preventDefault();
}❌ Wrong ​
html
<!-- Complex logic in template -->
<button x:on:click="items.filter(i => i.active).length > 0 ? save() : cancel()">
Click
</button>
<!-- Use method instead -->typescript
// Correct solution
handleClick(): void {
const hasActive = this.items.some(i => i.active);
if (hasActive) {
this.save();
} else {
this.cancel();
}
}Summary ​
- Simple syntax:
x:on:click="methodName" - Parameter support: Values and expressions can be passed
- Special parameters:
$event,$target,$element - Visual feedback: Automatic CSS classes
- Loop compatible: Can be used inside x:for
- Type-safe: Full support with TypeScript
- Event control: preventDefault, stopPropagation can be used