or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binding.mdcomponents.mdindex.mdobservables.mdperformance.mdtemplates.mdutils.md
tile.json

utils.mddocs/

0

# Utility Functions

1

2

Comprehensive utility library providing array manipulation, DOM utilities, data conversion, and cross-browser compatibility functions. These utilities are available under the `ko.utils` namespace and provide foundational functionality used throughout Knockout.js.

3

4

## Capabilities

5

6

### Array Utilities

7

8

Utility functions for array manipulation and iteration.

9

10

```javascript { .api }

11

/**

12

* Iterate over array elements

13

* @param array - Array to iterate over

14

* @param action - Function called for each element

15

* @param actionOwner - Optional 'this' context for action

16

*/

17

function arrayForEach<T>(

18

array: T[],

19

action: (item: T, index: number) => void,

20

actionOwner?: any

21

): void;

22

23

/**

24

* Find first element matching predicate

25

* @param array - Array to search

26

* @param predicate - Test function

27

* @param predicateOwner - Optional 'this' context for predicate

28

* @returns First matching element or undefined

29

*/

30

function arrayFirst<T>(

31

array: T[],

32

predicate: (item: T, index: number) => boolean,

33

predicateOwner?: any

34

): T | undefined;

35

36

/**

37

* Filter array elements

38

* @param array - Array to filter

39

* @param predicate - Test function

40

* @param predicateOwner - Optional 'this' context for predicate

41

* @returns New array with matching elements

42

*/

43

function arrayFilter<T>(

44

array: T[],

45

predicate: (item: T, index: number) => boolean,

46

predicateOwner?: any

47

): T[];

48

49

/**

50

* Transform array elements

51

* @param array - Array to transform

52

* @param mapping - Transform function

53

* @param mappingOwner - Optional 'this' context for mapping

54

* @returns New array with transformed elements

55

*/

56

function arrayMap<T, U>(

57

array: T[],

58

mapping: (item: T, index: number) => U,

59

mappingOwner?: any

60

): U[];

61

62

/**

63

* Find index of element in array

64

* @param array - Array to search

65

* @param item - Item to find

66

* @returns Index of item or -1 if not found

67

*/

68

function arrayIndexOf<T>(array: T[], item: T): number;

69

70

/**

71

* Add all elements from source array to target array

72

* @param array - Target array to modify

73

* @param valuesToPush - Elements to add

74

* @returns Modified target array

75

*/

76

function arrayPushAll<T>(array: T[], valuesToPush: T[]): T[];

77

78

/**

79

* Remove specific item from array

80

* @param array - Array to modify

81

* @param itemToRemove - Item to remove

82

*/

83

function arrayRemoveItem<T>(array: T[], itemToRemove: T): void;

84

85

/**

86

* Get unique values from array

87

* @param array - Source array

88

* @returns New array with unique values

89

*/

90

function arrayGetDistinctValues<T>(array: T[]): T[];

91

92

/**

93

* Conditionally add or remove item from array

94

* @param array - Array to modify

95

* @param value - Value to add/remove

96

* @param included - Whether to include (true) or exclude (false)

97

* @returns Modified array

98

*/

99

function addOrRemoveItem<T>(array: T[], value: T, included?: boolean): T[];

100

```

101

102

**Usage Examples:**

103

104

```javascript

105

import ko from "knockout";

106

107

const numbers = [1, 2, 3, 4, 5];

108

const people = [

109

{ name: "Alice", age: 25 },

110

{ name: "Bob", age: 30 },

111

{ name: "Charlie", age: 35 }

112

];

113

114

// Array iteration

115

ko.utils.arrayForEach(numbers, (num, index) => {

116

console.log(`${index}: ${num}`);

117

});

118

119

// Finding elements

120

const firstAdult = ko.utils.arrayFirst(people, person => person.age >= 18);

121

console.log(firstAdult); // { name: "Alice", age: 25 }

122

123

// Filtering and mapping

124

const adults = ko.utils.arrayFilter(people, person => person.age >= 18);

125

const names = ko.utils.arrayMap(people, person => person.name);

126

127

// Array manipulation

128

const fruits = ["apple", "banana"];

129

ko.utils.arrayPushAll(fruits, ["orange", "grape"]);

130

console.log(fruits); // ["apple", "banana", "orange", "grape"]

131

```

132

133

### Object Utilities

134

135

Utility functions for object manipulation and property iteration.

136

137

```javascript { .api }

138

/**

139

* Extend target object with properties from source object

140

* @param target - Object to extend

141

* @param source - Source object

142

* @returns Extended target object

143

*/

144

function extend<T, U>(target: T, source: U): T & U;

145

146

/**

147

* Iterate over object properties

148

* @param obj - Object to iterate over

149

* @param action - Function called for each property

150

*/

151

function objectForEach(obj: object, action: (key: string, value: any) => void): void;

152

function objectForEach<T>(obj: { [key: string]: T }, action: (key: string, value: T) => void): void;

153

154

/**

155

* Transform object properties

156

* @param obj - Object to transform

157

* @param mapping - Transform function

158

* @param mappingOwner - Optional 'this' context for mapping

159

* @returns New object with transformed values

160

*/

161

function objectMap<T, U>(

162

obj: { [key: string]: T },

163

mapping: (value: T, key: string) => U,

164

mappingOwner?: any

165

): { [key: string]: U };

166

```

167

168

**Usage Examples:**

169

170

```javascript

171

import ko from "knockout";

172

173

// Object extension

174

const target = { name: "John" };

175

const source = { age: 30, city: "New York" };

176

const extended = ko.utils.extend(target, source);

177

// extended: { name: "John", age: 30, city: "New York" }

178

179

// Object iteration

180

const person = { name: "Alice", age: 25, city: "Boston" };

181

ko.utils.objectForEach(person, (key, value) => {

182

console.log(`${key}: ${value}`);

183

});

184

185

// Object mapping

186

const scores = { math: 85, english: 92, science: 78 };

187

const grades = ko.utils.objectMap(scores, score => {

188

return score >= 90 ? "A" : score >= 80 ? "B" : "C";

189

});

190

// grades: { math: "B", english: "A", science: "C" }

191

```

192

193

### Observable Utilities

194

195

Utility functions for working with observable values.

196

197

```javascript { .api }

198

/**

199

* Unwrap observable value (same as ko.unwrap)

200

* @param value - Observable or regular value

201

* @returns Unwrapped value

202

*/

203

function unwrapObservable<T>(value: T | Observable<T>): T;

204

205

/**

206

* Peek at observable value without creating dependency

207

* @param value - Observable or regular value

208

* @returns Peeked value

209

*/

210

function peekObservable<T>(value: T | Observable<T>): T;

211

```

212

213

**Usage Examples:**

214

215

```javascript

216

import ko from "knockout";

217

218

const observableValue = ko.observable("hello");

219

const regularValue = "world";

220

221

// Unwrap values

222

const unwrapped1 = ko.utils.unwrapObservable(observableValue); // "hello"

223

const unwrapped2 = ko.utils.unwrapObservable(regularValue); // "world"

224

225

// Peek without creating dependency

226

const peeked = ko.utils.peekObservable(observableValue); // "hello"

227

```

228

229

### DOM Utilities

230

231

Utility functions for DOM manipulation and HTML processing.

232

233

```javascript { .api }

234

/**

235

* Parse HTML string into DOM nodes

236

* @param html - HTML string to parse

237

* @param documentContext - Optional document context

238

* @returns Array of DOM nodes

239

*/

240

function parseHtmlFragment(html: string, documentContext?: Document): Node[];

241

242

/**

243

* Set HTML content of element

244

* @param node - Target DOM node

245

* @param html - HTML content to set

246

*/

247

function setHtml(node: Node, html: string): void;

248

249

/**

250

* Trigger DOM event on element

251

* @param element - Target element

252

* @param eventType - Event type (e.g., "click", "change")

253

*/

254

function triggerEvent(element: Element, eventType: string): void;

255

256

/**

257

* Register event handler on element

258

* @param element - Target element

259

* @param eventType - Event type

260

* @param handler - Event handler function

261

*/

262

function registerEventHandler(element: Element, eventType: string, handler: EventListener): void;

263

264

/**

265

* Toggle CSS class on DOM node

266

* @param node - Target element

267

* @param className - CSS class name

268

* @param shouldHaveClass - Whether element should have the class

269

*/

270

function toggleDomNodeCssClass(node: Element, className: string, shouldHaveClass?: boolean): void;

271

272

/**

273

* Set text content of node

274

* @param element - Target node

275

* @param textContent - Text content to set

276

*/

277

function setTextContent(element: Node, textContent: string): void;

278

```

279

280

**Usage Examples:**

281

282

```javascript

283

import ko from "knockout";

284

285

// Parse HTML

286

const htmlString = "<div><p>Hello</p><p>World</p></div>";

287

const nodes = ko.utils.parseHtmlFragment(htmlString);

288

289

// Set HTML content

290

const container = document.getElementById("container");

291

ko.utils.setHtml(container, "<strong>Bold text</strong>");

292

293

// Event handling

294

const button = document.getElementById("myButton");

295

ko.utils.registerEventHandler(button, "click", (event) => {

296

console.log("Button clicked!");

297

});

298

299

// Trigger events

300

ko.utils.triggerEvent(button, "click");

301

302

// CSS class manipulation

303

const element = document.getElementById("myElement");

304

ko.utils.toggleDomNodeCssClass(element, "active", true); // Add class

305

ko.utils.toggleDomNodeCssClass(element, "active", false); // Remove class

306

ko.utils.toggleDomNodeCssClass(element, "active"); // Toggle class

307

```

308

309

### Data Utilities

310

311

Utility functions for JSON parsing, stringification, and form data handling.

312

313

```javascript { .api }

314

/**

315

* Parse JSON string safely

316

* @param jsonString - JSON string to parse

317

* @returns Parsed object or null if invalid

318

*/

319

function parseJson(jsonString: string): any;

320

function parseJson<T>(jsonString: string): T;

321

322

/**

323

* Convert object to JSON string

324

* @param data - Data to stringify

325

* @param replacer - Optional replacer function

326

* @param space - Optional spacing

327

* @returns JSON string

328

*/

329

function stringifyJson(data: any, replacer?: Function, space?: string | number): string;

330

331

/**

332

* Post JSON data to URL

333

* @param urlOrForm - URL string or form element

334

* @param data - Data to post

335

* @param options - Optional posting options

336

*/

337

function postJson(urlOrForm: string | HTMLFormElement, data: any, options?: PostJsonOptions): void;

338

339

/**

340

* Get form field elements by name or pattern

341

* @param form - Form element

342

* @param fieldName - Field name or RegExp pattern

343

* @returns Array of matching form elements

344

*/

345

function getFormFields(form: HTMLFormElement, fieldName: string | RegExp): HTMLElement[];

346

```

347

348

```typescript { .api }

349

interface PostJsonOptions {

350

params?: object;

351

includeFields?: string[];

352

submitter?: (form: HTMLFormElement) => void;

353

}

354

```

355

356

**Usage Examples:**

357

358

```javascript

359

import ko from "knockout";

360

361

// JSON operations

362

const jsonString = '{"name": "John", "age": 30}';

363

const parsed = ko.utils.parseJson(jsonString);

364

console.log(parsed); // { name: "John", age: 30 }

365

366

const data = { message: "Hello World", timestamp: Date.now() };

367

const jsonStr = ko.utils.stringifyJson(data);

368

369

// Post JSON data

370

ko.utils.postJson("/api/users", {

371

name: "Alice",

372

email: "alice@example.com"

373

});

374

375

// Form field handling

376

const form = document.getElementById("myForm");

377

const nameFields = ko.utils.getFormFields(form, "name");

378

const allFields = ko.utils.getFormFields(form, /.*input.*/);

379

```

380

381

### Numeric Utilities

382

383

Utility functions for generating numeric ranges.

384

385

```javascript { .api }

386

/**

387

* Generate range of numbers

388

* @param min - Minimum value (can be observable)

389

* @param max - Maximum value (can be observable)

390

* @returns Array of numbers from min to max

391

*/

392

function range(min: number | Observable<number>, max: number | Observable<number>): number[];

393

```

394

395

**Usage Examples:**

396

397

```javascript

398

import ko from "knockout";

399

400

// Static range

401

const numbers = ko.utils.range(1, 5);

402

console.log(numbers); // [1, 2, 3, 4, 5]

403

404

// Observable range

405

const min = ko.observable(10);

406

const max = ko.observable(15);

407

const dynamicRange = ko.utils.range(min, max);

408

console.log(dynamicRange); // [10, 11, 12, 13, 14, 15]

409

```

410

411

### Array Comparison

412

413

Advanced array comparison utilities for detecting changes.

414

415

```javascript { .api }

416

/**

417

* Compare two arrays and return change information

418

* @param oldArray - Original array

419

* @param newArray - New array to compare

420

* @param options - Optional comparison options

421

* @returns Array of change objects

422

*/

423

function compareArrays<T>(

424

oldArray: T[],

425

newArray: T[],

426

options?: CompareArraysOptions

427

): ArrayChange<T>[];

428

```

429

430

```typescript { .api }

431

interface ArrayChange<T> {

432

status: "added" | "deleted" | "retained";

433

value: T;

434

index: number;

435

moved?: number;

436

}

437

438

interface CompareArraysOptions {

439

dontLimitMoves?: boolean;

440

sparse?: boolean;

441

}

442

```

443

444

**Usage Examples:**

445

446

```javascript

447

import ko from "knockout";

448

449

const oldArray = ["a", "b", "c"];

450

const newArray = ["a", "c", "d"];

451

const changes = ko.utils.compareArrays(oldArray, newArray);

452

453

console.log(changes);

454

// [

455

// { status: "retained", value: "a", index: 0 },

456

// { status: "deleted", value: "b", index: 1 },

457

// { status: "retained", value: "c", index: 2 },

458

// { status: "added", value: "d", index: 3 }

459

// ]

460

```

461

462

### DOM Data Storage

463

464

Utility functions for storing and retrieving data associated with DOM nodes.

465

466

```javascript { .api }

467

const domData: {

468

/**

469

* Get data stored on DOM node

470

* @param node - DOM node

471

* @param key - Data key

472

* @returns Stored data or undefined

473

*/

474

get<T>(node: Node, key: string): T | undefined;

475

476

/**

477

* Set data on DOM node

478

* @param node - DOM node

479

* @param key - Data key

480

* @param value - Data value

481

*/

482

set<T>(node: Node, key: string, value: T): void;

483

484

/**

485

* Clear all data from DOM node

486

* @param node - DOM node

487

* @returns True if data was cleared

488

*/

489

clear(node: Node): boolean;

490

};

491

```

492

493

### DOM Node Disposal

494

495

Utility functions for DOM node cleanup and disposal callbacks.

496

497

```javascript { .api }

498

const domNodeDisposal: {

499

/**

500

* Add disposal callback for DOM node

501

* @param node - DOM node

502

* @param callback - Callback to execute when node is disposed

503

*/

504

addDisposeCallback(node: Node, callback: (node: Node) => void): void;

505

506

/**

507

* Remove disposal callback from DOM node

508

* @param node - DOM node

509

* @param callback - Callback to remove

510

*/

511

removeDisposeCallback(node: Node, callback: (node: Node) => void): void;

512

513

/**

514

* Clean external data associated with node

515

* @param node - DOM node

516

*/

517

cleanExternalData(node: Node): void;

518

};

519

```

520

521

### Cross-browser Compatibility

522

523

Built-in fields and utilities for cross-browser form handling.

524

525

```javascript { .api }

526

/**

527

* Array of field names/patterns included in JSON posts

528

*/

529

const fieldsIncludedWithJsonPost: (string | RegExp)[];

530

```

531

532

**Usage Examples:**

533

534

```javascript

535

import ko from "knockout";

536

537

// DOM data storage

538

const element = document.getElementById("myElement");

539

ko.utils.domData.set(element, "userData", { id: 123, name: "Test" });

540

const userData = ko.utils.domData.get(element, "userData");

541

542

// Disposal callbacks

543

ko.utils.domNodeDisposal.addDisposeCallback(element, (node) => {

544

console.log("Element disposed:", node);

545

});

546

547

// Check included fields for form posts

548

console.log(ko.utils.fieldsIncludedWithJsonPost);

549

// ["authenticity_token", /^__RequestVerificationToken(_.*)?$/]

550

```

551

552

### DOM Node Management

553

554

Advanced DOM manipulation functions for managing node lifecycle and cleanup.

555

556

```javascript { .api }

557

/**

558

* Clean up a DOM node and dispose of associated data

559

* @param node - DOM node to clean

560

* @returns The cleaned node (same instance)

561

*/

562

function cleanNode(node: Node): typeof node;

563

564

/**

565

* Remove a DOM node from its parent and clean it up

566

* @param node - DOM node to remove

567

*/

568

function removeNode(node: Node): void;

569

```

570

571

**Usage Examples:**

572

573

```javascript

574

import ko from "knockout";

575

576

// Clean up node before reuse

577

const element = document.getElementById("reusable");

578

ko.cleanNode(element);

579

580

// Remove and clean up node

581

const obsoleteElement = document.getElementById("obsolete");

582

ko.removeNode(obsoleteElement);

583

```

584

585

### Array-DOM Mapping

586

587

Advanced utilities for efficiently mapping arrays to DOM nodes with change tracking and lifecycle hooks.

588

589

```javascript { .api }

590

/**

591

* Map array to DOM nodes with efficient change tracking

592

* @param domNode - Container node for generated nodes

593

* @param array - Source array to map

594

* @param mapping - Function to create nodes for each array item

595

* @param options - Optional mapping behavior configuration

596

* @param callbackAfterAddingNodes - Optional callback after nodes are added

597

*/

598

function setDomNodeChildrenFromArrayMapping<T>(

599

domNode: Node,

600

array: T[],

601

mapping: MappingFunction<T>,

602

options?: MappingOptions<T>,

603

callbackAfterAddingNodes?: MappingAfterAddFunction<T>

604

): void;

605

```

606

607

```typescript { .api }

608

/**

609

* Function that creates DOM nodes for array items

610

*/

611

type MappingFunction<T> = (valueToMap: T, index: number, nodes: Node[]) => Node[];

612

613

/**

614

* Callback executed after nodes are added to DOM

615

*/

616

type MappingAfterAddFunction<T> = (arrayEntry: T, nodes: Node[], index: Observable<number>) => Node[];

617

618

/**

619

* Callback executed during array change lifecycle events

620

*/

621

type MappingHookFunction<T> = (nodes: Node[], index: number, arrayEntry: T) => void;

622

623

/**

624

* Configuration options for array-DOM mapping behavior

625

*/

626

interface MappingOptions<T> {

627

/** Don't limit DOM moves during array reordering */

628

dontLimitMoves?: boolean;

629

/** Called before moving nodes for reordered items */

630

beforeMove?: MappingHookFunction<T>;

631

/** Called before removing nodes for deleted items */

632

beforeRemove?: MappingHookFunction<T>;

633

/** Called after adding nodes for new items */

634

afterAdd?: MappingHookFunction<T>;

635

/** Called after moving nodes for reordered items */

636

afterMove?: MappingHookFunction<T>;

637

/** Called after removing nodes for deleted items */

638

afterRemove?: MappingHookFunction<T>;

639

}

640

```

641

642

**Usage Examples:**

643

644

```javascript

645

import ko from "knockout";

646

647

const container = document.getElementById("list-container");

648

const items = ko.observableArray([

649

{ id: 1, name: "Item 1" },

650

{ id: 2, name: "Item 2" }

651

]);

652

653

// Map array to DOM with lifecycle hooks

654

ko.utils.setDomNodeChildrenFromArrayMapping(

655

container,

656

items(),

657

(item, index, nodes) => {

658

const div = document.createElement("div");

659

div.textContent = item.name;

660

div.setAttribute("data-id", item.id);

661

return [div];

662

},

663

{

664

beforeRemove: (nodes, index, item) => {

665

console.log("Removing item:", item.name);

666

},

667

afterAdd: (nodes, index, item) => {

668

console.log("Added item:", item.name);

669

// Animate new nodes

670

nodes.forEach(node => {

671

node.style.opacity = "0";

672

setTimeout(() => node.style.opacity = "1", 10);

673

});

674

}

675

}

676

);

677

678

// Update array - DOM will be efficiently updated

679

items.push({ id: 3, name: "Item 3" });

680

items.remove(items()[0]);

681

```