or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ajax.mdconfiguration.mddata-management.mdevents.mdindex.mdinitialization.mdtheming.md

ajax.mddocs/

0

# AJAX Integration

1

2

Remote data loading with customizable request handling, response processing, infinite scrolling, and caching support.

3

4

## Capabilities

5

6

### AJAX Configuration

7

8

Complete configuration interface for remote data loading with extensive customization options.

9

10

```javascript { .api }

11

/**

12

* AJAX configuration options

13

*/

14

interface AjaxOptions {

15

url: string | ((params: AjaxParams) => string);

16

data?: (params: AjaxParams) => object;

17

dataType?: string;

18

delay?: number;

19

cache?: boolean;

20

transport?: (params: TransportParams, success: Function, failure: Function) => void;

21

processResults?: (data: any, params: AjaxParams) => AjaxResponse;

22

23

// All jQuery.ajax options are also supported

24

method?: string;

25

headers?: object;

26

contentType?: string;

27

timeout?: number;

28

}

29

30

/**

31

* AJAX request parameters

32

*/

33

interface AjaxParams {

34

term: string; // Search term entered by user

35

page: number; // Current page number (starts at 1)

36

_type?: string; // Request type: 'query' for standard requests

37

}

38

39

/**

40

* Expected AJAX response format

41

*/

42

interface AjaxResponse {

43

results: DataObject[]; // Array of data objects

44

pagination?: { // Optional pagination info

45

more: boolean; // True if more results available

46

};

47

}

48

49

/**

50

* Transport function parameters

51

*/

52

interface TransportParams {

53

url: string;

54

data: object;

55

success: (data: any) => void;

56

error: (jqXHR: any, textStatus: string, errorThrown: string) => void;

57

}

58

```

59

60

### Basic AJAX Setup

61

62

Simple AJAX configuration for common remote data scenarios.

63

64

```javascript { .api }

65

/**

66

* Basic AJAX configuration

67

*/

68

ajax: {

69

url: string | function, // Request URL or function returning URL

70

dataType: 'json', // Expected response type (default: 'json')

71

delay: 250, // Debounce delay in milliseconds (default: 250)

72

cache: false // Enable request caching (default: false)

73

}

74

```

75

76

**Usage Examples:**

77

78

```javascript

79

// Simple AJAX setup

80

$('#ajax-select').select2({

81

ajax: {

82

url: '/api/users',

83

dataType: 'json'

84

}

85

});

86

87

// Dynamic URL based on context

88

$('#context-select').select2({

89

ajax: {

90

url: function(params) {

91

var contextId = $('#context').val();

92

return '/api/context/' + contextId + '/items';

93

},

94

dataType: 'json',

95

delay: 500

96

}

97

});

98

99

// With custom headers and authentication

100

$('#auth-select').select2({

101

ajax: {

102

url: '/api/secure-data',

103

headers: {

104

'Authorization': 'Bearer ' + authToken,

105

'X-Requested-With': 'XMLHttpRequest'

106

},

107

method: 'POST'

108

}

109

});

110

```

111

112

### Request Data Transformation

113

114

Customize the data sent with AJAX requests to match your API expectations.

115

116

```javascript { .api }

117

/**

118

* Data transformation function

119

*/

120

data?: (params: AjaxParams) => object;

121

```

122

123

**Usage Examples:**

124

125

```javascript

126

// Basic parameter mapping

127

$('#api-select').select2({

128

ajax: {

129

url: '/api/search',

130

data: function(params) {

131

return {

132

q: params.term, // Search term

133

page: params.page, // Page number

134

limit: 10 // Results per page

135

};

136

}

137

}

138

});

139

140

// Complex parameter transformation

141

$('#complex-select').select2({

142

ajax: {

143

url: '/api/complex-search',

144

data: function(params) {

145

var filters = getActiveFilters();

146

var sortOrder = getSortOrder();

147

148

return {

149

query: params.term || '',

150

pagination: {

151

page: params.page || 1,

152

size: 25

153

},

154

filters: filters,

155

sort: sortOrder,

156

timestamp: Date.now()

157

};

158

}

159

}

160

});

161

162

// Conditional parameters

163

$('#conditional-select').select2({

164

ajax: {

165

url: '/api/conditional',

166

data: function(params) {

167

var requestData = {

168

search: params.term

169

};

170

171

// Only include page for pagination requests

172

if (params.page && params.page > 1) {

173

requestData.page = params.page;

174

}

175

176

// Include category filter if selected

177

var category = $('#category-filter').val();

178

if (category) {

179

requestData.category = category;

180

}

181

182

return requestData;

183

}

184

}

185

});

186

```

187

188

### Response Processing

189

190

Transform API responses to match Select2's expected data format.

191

192

```javascript { .api }

193

/**

194

* Response processing function

195

*/

196

processResults?: (data: any, params: AjaxParams) => AjaxResponse;

197

```

198

199

**Usage Examples:**

200

201

```javascript

202

// Basic response transformation

203

$('#transform-select').select2({

204

ajax: {

205

url: '/api/users',

206

processResults: function(data, params) {

207

return {

208

results: data.users.map(function(user) {

209

return {

210

id: user.id,

211

text: user.name + ' (' + user.email + ')'

212

};

213

})

214

};

215

}

216

}

217

});

218

219

// Complex response with pagination

220

$('#paginated-select').select2({

221

ajax: {

222

url: '/api/paginated-data',

223

data: function(params) {

224

return {

225

q: params.term,

226

page: params.page || 1,

227

per_page: 20

228

};

229

},

230

processResults: function(data, params) {

231

params.page = params.page || 1;

232

233

return {

234

results: data.items.map(function(item) {

235

return {

236

id: item.uuid,

237

text: item.display_name,

238

disabled: !item.active

239

};

240

}),

241

pagination: {

242

more: (params.page * 20) < data.total_count

243

}

244

};

245

}

246

}

247

});

248

249

// Grouped results

250

$('#grouped-ajax').select2({

251

ajax: {

252

url: '/api/grouped-data',

253

processResults: function(data, params) {

254

return {

255

results: data.categories.map(function(category) {

256

return {

257

text: category.name,

258

children: category.items.map(function(item) {

259

return {

260

id: item.id,

261

text: item.title

262

};

263

})

264

};

265

})

266

};

267

}

268

}

269

});

270

```

271

272

### Custom Transport

273

274

Override the default AJAX transport for complete control over HTTP requests.

275

276

```javascript { .api }

277

/**

278

* Custom transport function

279

*/

280

transport?: (params: TransportParams, success: Function, failure: Function) => void;

281

```

282

283

**Usage Examples:**

284

285

```javascript

286

// Fetch API transport

287

$('#fetch-select').select2({

288

ajax: {

289

transport: function(params, success, failure) {

290

var requestOptions = {

291

method: 'GET',

292

headers: {

293

'Content-Type': 'application/json'

294

}

295

};

296

297

// Add query parameters to URL

298

var url = new URL(params.url);

299

Object.keys(params.data).forEach(function(key) {

300

url.searchParams.append(key, params.data[key]);

301

});

302

303

fetch(url.toString(), requestOptions)

304

.then(function(response) {

305

if (!response.ok) {

306

throw new Error('Network response was not ok');

307

}

308

return response.json();

309

})

310

.then(success)

311

.catch(failure);

312

},

313

processResults: function(data) {

314

return { results: data };

315

}

316

}

317

});

318

319

// Custom HTTP client transport

320

$('#custom-transport').select2({

321

ajax: {

322

transport: function(params, success, failure) {

323

// Use custom HTTP client (e.g., axios)

324

customHttpClient.get(params.url, {

325

params: params.data,

326

timeout: 5000,

327

headers: {

328

'X-API-Key': getApiKey()

329

}

330

})

331

.then(function(response) {

332

success(response.data);

333

})

334

.catch(function(error) {

335

failure(null, 'error', error.message);

336

});

337

}

338

}

339

});

340

```

341

342

### Infinite Scrolling

343

344

Enable automatic loading of additional results when scrolling to the bottom.

345

346

```javascript { .api }

347

/**

348

* Infinite scrolling is automatically enabled when pagination.more is true

349

*/

350

// Pagination response format

351

interface PaginationResponse {

352

results: DataObject[];

353

pagination: {

354

more: boolean; // Indicates more results available

355

};

356

}

357

```

358

359

**Usage Examples:**

360

361

```javascript

362

// Infinite scroll with page-based pagination

363

$('#infinite-select').select2({

364

ajax: {

365

url: '/api/infinite-data',

366

data: function(params) {

367

return {

368

q: params.term,

369

page: params.page || 1,

370

page_size: 50

371

};

372

},

373

processResults: function(data, params) {

374

params.page = params.page || 1;

375

376

return {

377

results: data.results,

378

pagination: {

379

more: data.has_next_page

380

}

381

};

382

}

383

}

384

});

385

386

// Offset-based infinite scroll

387

$('#offset-select').select2({

388

ajax: {

389

url: '/api/offset-data',

390

data: function(params) {

391

var pageSize = 25;

392

var offset = ((params.page || 1) - 1) * pageSize;

393

394

return {

395

search: params.term,

396

offset: offset,

397

limit: pageSize

398

};

399

},

400

processResults: function(data, params) {

401

params.page = params.page || 1;

402

var pageSize = 25;

403

404

return {

405

results: data.items,

406

pagination: {

407

more: data.total > (params.page * pageSize)

408

}

409

};

410

}

411

}

412

});

413

```

414

415

### Caching and Performance

416

417

Optimize AJAX requests through caching and request management.

418

419

```javascript { .api }

420

/**

421

* Caching configuration

422

*/

423

cache?: boolean; // Enable built-in caching (default: false)

424

delay?: number; // Request debounce delay in ms (default: 250)

425

```

426

427

**Usage Examples:**

428

429

```javascript

430

// Enable caching for static data

431

$('#cached-select').select2({

432

ajax: {

433

url: '/api/static-reference-data',

434

cache: true, // Cache results

435

delay: 100 // Shorter delay for cached data

436

}

437

});

438

439

// Custom caching implementation

440

var customCache = {};

441

442

$('#custom-cache-select').select2({

443

ajax: {

444

transport: function(params, success, failure) {

445

var cacheKey = params.url + '?q=' + (params.data.q || '');

446

447

// Check cache first

448

if (customCache[cacheKey]) {

449

setTimeout(function() {

450

success(customCache[cacheKey]);

451

}, 50);

452

return;

453

}

454

455

// Make request and cache result

456

$.ajax({

457

url: params.url,

458

data: params.data,

459

dataType: 'json'

460

})

461

.done(function(data) {

462

customCache[cacheKey] = data;

463

success(data);

464

})

465

.fail(failure);

466

}

467

}

468

});

469

```

470

471

### Error Handling

472

473

Handle AJAX errors gracefully with user feedback and retry mechanisms.

474

475

```javascript

476

// Basic error handling

477

$('#error-handling-select').select2({

478

ajax: {

479

url: '/api/unreliable-endpoint',

480

transport: function(params, success, failure) {

481

$.ajax({

482

url: params.url,

483

data: params.data,

484

dataType: 'json',

485

timeout: 10000

486

})

487

.done(success)

488

.fail(function(jqXHR, textStatus, errorThrown) {

489

console.error('AJAX Error:', textStatus, errorThrown);

490

491

// Provide user feedback

492

failure(jqXHR, textStatus, 'Failed to load data. Please try again.');

493

});

494

},

495

processResults: function(data, params) {

496

// Handle malformed responses

497

if (!data || !Array.isArray(data.results)) {

498

console.warn('Invalid response format:', data);

499

return { results: [] };

500

}

501

502

return { results: data.results };

503

}

504

}

505

});

506

507

// Retry mechanism

508

function createRetryTransport(maxRetries = 3) {

509

return function(params, success, failure) {

510

var retryCount = 0;

511

512

function attemptRequest() {

513

$.ajax({

514

url: params.url,

515

data: params.data,

516

dataType: 'json',

517

timeout: 5000

518

})

519

.done(success)

520

.fail(function(jqXHR, textStatus, errorThrown) {

521

retryCount++;

522

523

if (retryCount < maxRetries && textStatus !== 'parsererror') {

524

console.log('Retrying request, attempt', retryCount + 1);

525

setTimeout(attemptRequest, 1000 * retryCount);

526

} else {

527

failure(jqXHR, textStatus, errorThrown);

528

}

529

});

530

}

531

532

attemptRequest();

533

};

534

}

535

536

$('#retry-select').select2({

537

ajax: {

538

transport: createRetryTransport(3)

539

}

540

});

541

```