or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-updates.mdevent-handling.mdindex.mdslider-creation.mdui-enhancements.mdvalue-management.md

event-handling.mddocs/

0

# Event Handling

1

2

Comprehensive event system for responding to slider interactions and value changes with detailed callback information and namespacing support.

3

4

## Capabilities

5

6

### on()

7

8

Binds an event listener to the slider.

9

10

```javascript { .api }

11

/**

12

* Bind an event listener to the slider

13

* @param eventName - Event name, optionally with namespace (e.g., 'update.myNamespace')

14

* @param callback - Function to call when event fires

15

*/

16

slider.noUiSlider.on(eventName: string, callback: EventCallback): void;

17

18

type EventCallback = (

19

values: string[], // Formatted values for all handles

20

handle: number, // Index of the handle that triggered the event

21

unencoded: number[], // Raw numeric values for all handles

22

tap?: boolean, // True if triggered by tap/click

23

positions?: number[], // Handle positions as percentages (0-100)

24

slider?: SliderAPI // Reference to the slider API

25

) => void;

26

```

27

28

**Usage Examples:**

29

30

```javascript

31

// Basic event binding

32

slider.noUiSlider.on('update', function(values, handle) {

33

console.log('Handle', handle, 'updated to:', values[handle]);

34

});

35

36

// Access all callback parameters

37

slider.noUiSlider.on('slide', function(values, handle, unencoded, tap, positions, slider) {

38

console.log('Values:', values); // ["20.00", "80.00"] (formatted)

39

console.log('Handle:', handle); // 1 (active handle index)

40

console.log('Raw values:', unencoded); // [20, 80] (numeric)

41

console.log('Tap event:', tap); // true/false

42

console.log('Positions:', positions); // [20, 80] (percentages)

43

console.log('Slider API:', slider); // Reference to slider

44

});

45

46

// Event with namespace

47

slider.noUiSlider.on('update.validation', function(values) {

48

validateInput(values);

49

});

50

```

51

52

### off()

53

54

Removes event listeners from the slider.

55

56

```javascript { .api }

57

/**

58

* Remove event listeners from the slider

59

* @param eventName - Event name, namespace, or combination to remove

60

*/

61

slider.noUiSlider.off(eventName: string): void;

62

```

63

64

**Usage Examples:**

65

66

```javascript

67

// Remove all listeners for an event

68

slider.noUiSlider.off('update');

69

70

// Remove listeners for specific namespace

71

slider.noUiSlider.off('.validation');

72

73

// Remove specific event with namespace

74

slider.noUiSlider.off('update.validation');

75

76

// Remove all namespaced events

77

slider.noUiSlider.off('.myNamespace');

78

```

79

80

## Event Types

81

82

### start

83

84

Fired when user interaction begins (mousedown, touchstart).

85

86

```javascript { .api }

87

slider.noUiSlider.on('start', callback);

88

```

89

90

**Usage:**

91

92

```javascript

93

slider.noUiSlider.on('start', function(values, handle, unencoded) {

94

console.log('Started dragging handle', handle);

95

document.body.style.cursor = 'grabbing';

96

});

97

```

98

99

### slide

100

101

Fired continuously during user interaction (mousemove, touchmove).

102

103

```javascript { .api }

104

slider.noUiSlider.on('slide', callback);

105

```

106

107

**Usage:**

108

109

```javascript

110

slider.noUiSlider.on('slide', function(values, handle, unencoded) {

111

// Real-time feedback during dragging

112

document.getElementById('current-value').textContent = values[handle];

113

});

114

```

115

116

### update

117

118

Fired when slider values change, from any source.

119

120

```javascript { .api }

121

slider.noUiSlider.on('update', callback);

122

```

123

124

**Usage:**

125

126

```javascript

127

slider.noUiSlider.on('update', function(values, handle, unencoded) {

128

// Update form inputs, display values, etc.

129

document.getElementById('value-' + handle).value = unencoded[handle];

130

});

131

```

132

133

### change

134

135

Fired when user interaction ends and value has changed.

136

137

```javascript { .api }

138

slider.noUiSlider.on('change', callback);

139

```

140

141

**Usage:**

142

143

```javascript

144

slider.noUiSlider.on('change', function(values, handle, unencoded) {

145

// Save to database, validate final value, etc.

146

console.log('Final value changed to:', values[handle]);

147

saveToDatabase(unencoded);

148

});

149

```

150

151

### set

152

153

Fired when values are set programmatically via set() or setHandle().

154

155

```javascript { .api }

156

slider.noUiSlider.on('set', callback);

157

```

158

159

**Usage:**

160

161

```javascript

162

slider.noUiSlider.on('set', function(values, handle, unencoded) {

163

console.log('Value programmatically set to:', values[handle]);

164

});

165

166

// This will trigger the 'set' event

167

slider.noUiSlider.set([30, 70]);

168

```

169

170

### end

171

172

Fired when user interaction ends (mouseup, touchend).

173

174

```javascript { .api }

175

slider.noUiSlider.on('end', callback);

176

```

177

178

**Usage:**

179

180

```javascript

181

slider.noUiSlider.on('end', function(values, handle, unencoded) {

182

console.log('Finished interacting with handle', handle);

183

document.body.style.cursor = '';

184

});

185

```

186

187

### hover

188

189

Fired when hovering over the slider (requires 'hover' behaviour).

190

191

```javascript { .api }

192

slider.noUiSlider.on('hover', callback);

193

```

194

195

**Usage:**

196

197

```javascript

198

// Enable hover behaviour

199

noUiSlider.create(element, {

200

start: 50,

201

range: { min: 0, max: 100 },

202

behaviour: 'hover'

203

});

204

205

// Listen for hover events

206

slider.noUiSlider.on('hover', function(value) {

207

// Note: hover callback receives single value, not array

208

console.log('Hovering over value:', value);

209

showTooltip(value);

210

});

211

```

212

213

## Event Namespacing

214

215

Use namespaces to organize and manage event listeners:

216

217

```javascript

218

// Add namespaced listeners

219

slider.noUiSlider.on('update.ui', updateUI);

220

slider.noUiSlider.on('update.validation', validateValues);

221

slider.noUiSlider.on('change.persistence', saveToDatabase);

222

223

// Remove specific namespace

224

slider.noUiSlider.off('.ui'); // Removes only UI-related listeners

225

slider.noUiSlider.off('.validation'); // Removes only validation listeners

226

227

// Remove specific event with namespace

228

slider.noUiSlider.off('update.ui'); // Removes only UI update listener

229

230

// Multiple namespaces

231

slider.noUiSlider.on('update.ui.form', function(values) {

232

// Update form fields

233

});

234

```

235

236

## Practical Usage Patterns

237

238

### Form Integration

239

240

```javascript

241

// Two-way binding with form inputs

242

const priceRange = document.getElementById('price-range');

243

const minInput = document.getElementById('min-price');

244

const maxInput = document.getElementById('max-price');

245

246

noUiSlider.create(priceRange, {

247

start: [100, 500],

248

connect: true,

249

range: { min: 0, max: 1000 }

250

});

251

252

// Update inputs when slider changes

253

priceRange.noUiSlider.on('update', function(values, handle) {

254

if (handle === 0) {

255

minInput.value = Math.round(values[0]);

256

} else {

257

maxInput.value = Math.round(values[1]);

258

}

259

});

260

261

// Update slider when inputs change

262

minInput.addEventListener('change', function() {

263

priceRange.noUiSlider.set([this.value, null]);

264

});

265

266

maxInput.addEventListener('change', function() {

267

priceRange.noUiSlider.set([null, this.value]);

268

});

269

```

270

271

### Real-time Validation

272

273

```javascript

274

slider.noUiSlider.on('update.validation', function(values, handle, unencoded) {

275

const isValid = unencoded.every(value => value >= 10 && value <= 90);

276

277

if (!isValid) {

278

slider.target.classList.add('invalid');

279

showError('Values must be between 10 and 90');

280

} else {

281

slider.target.classList.remove('invalid');

282

hideError();

283

}

284

});

285

```

286

287

### Debounced API Calls

288

289

```javascript

290

let debounceTimer;

291

292

slider.noUiSlider.on('slide', function(values) {

293

// Clear previous timer

294

clearTimeout(debounceTimer);

295

296

// Set new timer for API call

297

debounceTimer = setTimeout(function() {

298

updateSearchResults(values);

299

}, 300);

300

});

301

302

// Immediate update on final change

303

slider.noUiSlider.on('change', function(values) {

304

clearTimeout(debounceTimer);

305

updateSearchResults(values);

306

});

307

```

308

309

### Multi-slider Coordination

310

311

```javascript

312

// Coordinate multiple related sliders

313

const slider1 = document.getElementById('slider1');

314

const slider2 = document.getElementById('slider2');

315

316

// When slider1 changes, update slider2's range

317

slider1.noUiSlider.on('update.coordination', function(values) {

318

const maxValue = parseFloat(values[0]);

319

320

slider2.noUiSlider.updateOptions({

321

range: {

322

min: 0,

323

max: maxValue

324

}

325

});

326

});

327

```

328

329

### Custom Event Dispatching

330

331

```javascript

332

// Dispatch custom DOM events

333

slider.noUiSlider.on('change', function(values, handle, unencoded) {

334

const event = new CustomEvent('slider-changed', {

335

detail: {

336

values: values,

337

unencoded: unencoded,

338

handle: handle,

339

slider: this

340

}

341

});

342

343

document.dispatchEvent(event);

344

});

345

346

// Listen for custom events elsewhere

347

document.addEventListener('slider-changed', function(event) {

348

console.log('Slider changed:', event.detail);

349

});

350

```

351

352

## Event Callback Parameters

353

354

### values: string[]

355

Formatted values for all handles using the format.to() function.

356

357

```javascript

358

// With custom formatter

359

format: {

360

to: value => '$' + Math.round(value)

361

}

362

363

// values array contains: ["$25", "$75"]

364

```

365

366

### handle: number

367

Zero-based index of the handle that triggered the event.

368

369

```javascript

370

slider.noUiSlider.on('update', function(values, handle) {

371

if (handle === 0) {

372

console.log('First handle changed');

373

} else if (handle === 1) {

374

console.log('Second handle changed');

375

}

376

});

377

```

378

379

### unencoded: number[]

380

Raw numeric values for all handles, not processed by formatters.

381

382

```javascript

383

// Always contains actual numeric values

384

// unencoded: [25, 75] (regardless of formatting)

385

```

386

387

### tap: boolean (optional)

388

True if the event was triggered by a tap/click action.

389

390

```javascript

391

slider.noUiSlider.on('change', function(values, handle, unencoded, tap) {

392

if (tap) {

393

console.log('Value changed by clicking');

394

} else {

395

console.log('Value changed by dragging');

396

}

397

});

398

```

399

400

### positions: number[] (optional)

401

Handle positions as percentages (0-100).

402

403

```javascript

404

slider.noUiSlider.on('update', function(values, handle, unencoded, tap, positions) {

405

console.log('Handle positions:', positions); // [25, 75] (percentages)

406

});

407

```

408

409

### slider: SliderAPI (optional)

410

Reference to the slider API object.

411

412

```javascript

413

slider.noUiSlider.on('update', function(values, handle, unencoded, tap, positions, sliderAPI) {

414

// Access other slider methods

415

const allValues = sliderAPI.get();

416

const options = sliderAPI.options;

417

});

418

```

419

420

## Error Handling

421

422

Event handling is generally robust, but be aware of:

423

424

```javascript

425

// Events fire even for invalid operations

426

slider.noUiSlider.on('update', function(values) {

427

try {

428

updateUI(values);

429

} catch (error) {

430

console.error('Error updating UI:', error);

431

}

432

});

433

434

// Prevent infinite loops in cross-updates

435

let updating = false;

436

slider.noUiSlider.on('update', function(values) {

437

if (updating) return;

438

updating = true;

439

440

// Update related elements

441

updateRelatedSlider(values);

442

443

updating = false;

444

});

445

```