or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

checkbox.mdconfiguration.mdcontextmenu.mdcore.mddnd.mdevents.mdindex.mdplugins.mdsearch.md
tile.json

dnd.mddocs/

0

# Drag & Drop Operations

1

2

Advanced drag and drop support with customizable constraints, foreign element support, and visual feedback during operations. The DnD plugin enables intuitive tree manipulation through mouse and touch interactions.

3

4

## Capabilities

5

6

### DnD Configuration

7

8

Configuration options for drag and drop behavior.

9

10

```javascript { .api }

11

/**

12

* Drag and Drop plugin configuration

13

*/

14

interface DnDConfig {

15

/** Enable copy mode (hold Ctrl to copy instead of move) */

16

copy?: boolean;

17

/** Time before opening closed nodes during drag (ms, default: 500) */

18

open_timeout?: number;

19

/** Time before moving node to new position (ms, default: 500) */

20

move_timeout?: number;

21

/** Function or boolean to determine if node is draggable */

22

is_draggable?: boolean|function;

23

/** Check constraints while dragging (default: true) */

24

check_while_dragging?: boolean;

25

/** Allow dragging multiple selected nodes (default: true) */

26

drag_selection?: boolean;

27

/** Enable touch support (boolean or "selected" for selected nodes only) */

28

touch?: boolean|string;

29

/** Larger drop targets for easier dropping (default: false) */

30

large_drop_target?: boolean;

31

/** Larger drag handles for easier dragging (default: false) */

32

large_drag_target?: boolean;

33

/** Use HTML5 drag and drop API (default: true) */

34

use_html5?: boolean;

35

}

36

37

// Usage in tree initialization

38

const config = {

39

"plugins": ["dnd"],

40

"dnd": {

41

"copy": false,

42

"check_while_dragging": true,

43

"drag_selection": true,

44

"touch": true,

45

"large_drop_target": false

46

}

47

};

48

```

49

50

**Usage Examples:**

51

52

```javascript

53

// Initialize tree with drag and drop

54

$("#tree").jstree({

55

"core": {

56

"data": [

57

"Item 1", "Item 2",

58

{"text": "Folder", "children": ["Sub Item 1", "Sub Item 2"]}

59

],

60

"check_callback": true // Enable modifications

61

},

62

"plugins": ["dnd"],

63

"dnd": {

64

"copy": false, // Move by default

65

"check_while_dragging": true,

66

"drag_selection": true

67

}

68

});

69

70

// Get instance for DnD operations

71

const tree = $("#tree").jstree(true);

72

```

73

74

### Draggable Node Control

75

76

Methods and configuration for controlling which nodes can be dragged.

77

78

```javascript { .api }

79

/**

80

* Function to determine if a node is draggable

81

* @param nodes - Array of nodes being dragged

82

* @param event - Original drag event

83

* @returns True if nodes can be dragged

84

*/

85

type IsDraggableFunction = (nodes: Array<object>, event: Event) => boolean;

86

87

/**

88

* Configuration for draggable behavior

89

*/

90

interface DraggableConfig {

91

/** Global draggable setting */

92

is_draggable: boolean|IsDraggableFunction;

93

/** Per-node draggable setting in node data */

94

node_draggable?: boolean;

95

}

96

```

97

98

**Usage Examples:**

99

100

```javascript

101

// Global draggable function

102

$("#tree").jstree({

103

"plugins": ["dnd"],

104

"dnd": {

105

"is_draggable": function(nodes, e) {

106

// Only allow dragging leaf nodes

107

return nodes.every(node => tree.is_leaf(node));

108

}

109

}

110

});

111

112

// Per-node draggable setting

113

$("#tree").jstree({

114

"core": {

115

"data": [

116

{"text": "Draggable Item", "draggable": true},

117

{"text": "Fixed Item", "draggable": false},

118

{"text": "Default Item"} // Uses global setting

119

]

120

},

121

"plugins": ["dnd"]

122

});

123

124

// Dynamic draggable control

125

$("#tree").jstree({

126

"plugins": ["dnd"],

127

"dnd": {

128

"is_draggable": function(nodes, e) {

129

// Allow dragging only if user has permission

130

return nodes.every(node =>

131

node.li_attr && node.li_attr['data-user-can-move'] === 'true'

132

);

133

}

134

}

135

});

136

```

137

138

### Drop Target Control

139

140

Configuration for controlling where nodes can be dropped.

141

142

```javascript { .api }

143

/**

144

* Check callback function for validating drop operations

145

* @param operation - Type of operation ("move_node", "copy_node")

146

* @param node - Node being moved/copied

147

* @param parent - Target parent node

148

* @param position - Position within parent

149

* @param more - Additional operation data including DnD info

150

* @returns True if operation is allowed

151

*/

152

type CheckCallback = (

153

operation: string,

154

node: object,

155

parent: object,

156

position: number|string,

157

more: object

158

) => boolean;

159

```

160

161

**Usage Examples:**

162

163

```javascript

164

// Restrict drop targets with check_callback

165

$("#tree").jstree({

166

"core": {

167

"check_callback": function(operation, node, parent, position, more) {

168

// Allow drops only into folders

169

if (operation === "move_node") {

170

return parent.type === "folder";

171

}

172

return true;

173

}

174

},

175

"plugins": ["dnd", "types"],

176

"types": {

177

"folder": {"icon": "fa fa-folder"},

178

"file": {"icon": "fa fa-file"}

179

}

180

});

181

182

// Complex drop validation

183

$("#tree").jstree({

184

"core": {

185

"check_callback": function(op, node, parent, pos, more) {

186

if (op === "move_node") {

187

// Prevent dropping parents into their children

188

if (more.core && more.dnd) {

189

return !tree.is_ancestor(node, parent);

190

}

191

192

// Prevent certain node types from being parents

193

if (parent.type === "file") {

194

return false;

195

}

196

197

// Limit number of children

198

if (tree.get_children_dom(parent).length >= 10) {

199

return false;

200

}

201

}

202

return true;

203

}

204

},

205

"plugins": ["dnd", "types"]

206

});

207

```

208

209

### Copy vs Move Operations

210

211

Configuration and behavior for copy and move operations.

212

213

```javascript { .api }

214

/**

215

* Copy/Move operation configuration

216

*/

217

interface CopyMoveConfig {

218

/** Default operation mode */

219

copy: boolean;

220

/** Modifier keys for copy mode */

221

copy_modifier?: string; // "ctrl", "alt", "shift", "meta"

222

/** Always copy specific node types */

223

always_copy?: Array<string>;

224

/** Never copy specific node types */

225

never_copy?: Array<string>;

226

}

227

```

228

229

**Usage Examples:**

230

231

```javascript

232

// Copy by default, move with Shift key

233

$("#tree").jstree({

234

"plugins": ["dnd"],

235

"dnd": {

236

"copy": true, // Copy by default

237

"copy_modifier": "shift" // Hold Shift to move instead

238

}

239

});

240

241

// Copy specific node types automatically

242

$("#tree").jstree({

243

"plugins": ["dnd", "types"],

244

"dnd": {

245

"copy": false, // Move by default

246

"always_copy": ["template", "reference"] // Always copy these types

247

},

248

"types": {

249

"template": {"icon": "fa fa-copy"},

250

"reference": {"icon": "fa fa-link"},

251

"regular": {"icon": "fa fa-file"}

252

}

253

});

254

255

// Listen for copy/move operations

256

$("#tree").on("move_node.jstree", function(e, data) {

257

if (data.original) {

258

console.log("Node moved from", data.original.parent, "to", data.parent);

259

}

260

});

261

262

$("#tree").on("copy_node.jstree", function(e, data) {

263

console.log("Node copied:", data.node.text);

264

});

265

```

266

267

### Touch and Mobile Support

268

269

Configuration for touch devices and mobile interactions.

270

271

```javascript { .api }

272

/**

273

* Touch support configuration

274

*/

275

interface TouchConfig {

276

/** Enable touch support */

277

touch: boolean|"selected";

278

/** Touch drag threshold (pixels) */

279

touch_threshold?: number;

280

/** Long press duration for drag start (ms) */

281

long_press_timeout?: number;

282

/** Enable touch feedback */

283

touch_feedback?: boolean;

284

}

285

```

286

287

**Usage Examples:**

288

289

```javascript

290

// Full touch support

291

$("#tree").jstree({

292

"plugins": ["dnd"],

293

"dnd": {

294

"touch": true,

295

"large_drop_target": true, // Easier targeting on mobile

296

"large_drag_target": true

297

}

298

});

299

300

// Touch support for selected nodes only

301

$("#tree").jstree({

302

"plugins": ["dnd"],

303

"dnd": {

304

"touch": "selected", // Only selected nodes are draggable on touch

305

"drag_selection": true

306

}

307

});

308

```

309

310

### Foreign Element Support

311

312

Support for dragging elements from outside the tree.

313

314

```javascript { .api }

315

/**

316

* Foreign element configuration

317

*/

318

interface ForeignElementConfig {

319

/** Allow dropping foreign elements */

320

accept_foreign?: boolean;

321

/** Selector for acceptable foreign elements */

322

foreign_selector?: string;

323

/** Function to process foreign element data */

324

foreign_processor?: function;

325

}

326

```

327

328

**Usage Examples:**

329

330

```javascript

331

// Accept foreign elements

332

$("#tree").jstree({

333

"plugins": ["dnd"],

334

"dnd": {

335

"accept_foreign": true,

336

"foreign_selector": ".draggable-item",

337

"foreign_processor": function(element, target, position) {

338

// Convert foreign element to tree node

339

return {

340

"text": element.text(),

341

"data": element.data(),

342

"type": element.attr("data-type") || "default"

343

};

344

}

345

}

346

});

347

348

// Make external elements draggable to tree

349

$(".draggable-item").draggable({

350

"helper": "clone",

351

"revert": "invalid"

352

});

353

354

// Handle foreign drops

355

$("#tree").on("create_node.jstree", function(e, data) {

356

if (data.node.original && data.node.original.foreign) {

357

console.log("Foreign element dropped:", data.node.text);

358

}

359

});

360

```

361

362

### Visual Feedback

363

364

Configuration for drag and drop visual indicators.

365

366

```javascript { .api }

367

/**

368

* Visual feedback configuration

369

*/

370

interface VisualFeedbackConfig {

371

/** Show drop zones during drag */

372

show_drop_zones?: boolean;

373

/** Highlight valid drop targets */

374

highlight_targets?: boolean;

375

/** Custom drag helper element */

376

drag_helper?: function;

377

/** Drop marker styling */

378

drop_marker?: object;

379

}

380

```

381

382

**Usage Examples:**

383

384

```javascript

385

// Enhanced visual feedback

386

$("#tree").jstree({

387

"plugins": ["dnd"],

388

"dnd": {

389

"large_drop_target": true,

390

"show_drop_zones": true,

391

"highlight_targets": true

392

}

393

});

394

395

// Custom drag helper

396

$("#tree").jstree({

397

"plugins": ["dnd"],

398

"dnd": {

399

"drag_helper": function(nodes) {

400

const helper = $('<div class="custom-drag-helper">');

401

helper.text(nodes.length + " item(s) selected");

402

return helper;

403

}

404

}

405

});

406

```

407

408

### DnD Events

409

410

Events triggered during drag and drop operations.

411

412

```javascript { .api }

413

// DnD-specific events

414

"dnd_start.vakata": DnDStartEvent;

415

"dnd_move.vakata": DnDMoveEvent;

416

"dnd_stop.vakata": DnDStopEvent;

417

418

interface DnDStartEvent {

419

element: jQuery;

420

target: jQuery;

421

helper: jQuery;

422

}

423

424

interface DnDMoveEvent {

425

element: jQuery;

426

target: jQuery;

427

helper: jQuery;

428

event: Event;

429

}

430

431

interface DnDStopEvent {

432

element: jQuery;

433

target: jQuery;

434

helper: jQuery;

435

event: Event;

436

}

437

```

438

439

**Usage Examples:**

440

441

```javascript

442

// Listen for DnD events

443

$(document).on("dnd_start.vakata", function(e, data) {

444

console.log("Drag started");

445

$("body").addClass("dragging");

446

});

447

448

$(document).on("dnd_move.vakata", function(e, data) {

449

// Update custom drop indicators

450

updateDropZones(data.target);

451

});

452

453

$(document).on("dnd_stop.vakata", function(e, data) {

454

console.log("Drag stopped");

455

$("body").removeClass("dragging");

456

});

457

458

// Tree-specific DnD events

459

$("#tree").on("move_node.jstree", function(e, data) {

460

console.log("Node moved:", {

461

node: data.node.text,

462

old_parent: data.old_parent,

463

new_parent: data.parent,

464

old_position: data.old_position,

465

new_position: data.position

466

});

467

});

468

```

469

470

### Advanced DnD Customization

471

472

Advanced configuration options for complex drag and drop scenarios.

473

474

```javascript { .api }

475

/**

476

* Advanced DnD configuration

477

*/

478

interface AdvancedDnDConfig {

479

/** Custom drag start validation */

480

drag_start?: function;

481

/** Custom drop validation */

482

drop_finish?: function;

483

/** Multi-tree support */

484

multi_tree?: boolean;

485

/** Cross-frame dragging */

486

cross_frame?: boolean;

487

/** Drag constraints */

488

constraints?: object;

489

}

490

```

491

492

**Usage Examples:**

493

494

```javascript

495

// Multi-tree drag and drop

496

$("#tree1, #tree2").jstree({

497

"plugins": ["dnd"],

498

"dnd": {

499

"multi_tree": true,

500

"check_while_dragging": true

501

}

502

});

503

504

// Custom drag constraints

505

$("#tree").jstree({

506

"plugins": ["dnd"],

507

"dnd": {

508

"constraints": {

509

"max_depth": 5,

510

"allowed_parents": ["folder", "category"],

511

"forbidden_children": ["readonly"]

512

},

513

"drag_start": function(nodes, event) {

514

// Custom validation before drag starts

515

return nodes.every(node => !node.li_attr.readonly);

516

}

517

}

518

});

519

520

// Cross-frame dragging setup

521

$("#tree").jstree({

522

"plugins": ["dnd"],

523

"dnd": {

524

"cross_frame": true,

525

"use_html5": true

526

}

527

});

528

```

529

530

## Types

531

532

```javascript { .api }

533

// DnD-specific node extensions

534

interface DraggableNode extends TreeNode {

535

draggable?: boolean;

536

droppable?: boolean;

537

dnd_data?: {

538

origin?: string;

539

foreign?: boolean;

540

[key: string]: any;

541

};

542

}

543

544

// DnD plugin settings

545

interface DnDSettings {

546

copy: boolean;

547

open_timeout: number;

548

move_timeout: number;

549

is_draggable: boolean|function;

550

check_while_dragging: boolean;

551

drag_selection: boolean;

552

touch: boolean|string;

553

large_drop_target: boolean;

554

large_drag_target: boolean;

555

use_html5: boolean;

556

}

557

558

// Drag operation data

559

interface DragData {

560

nodes: Array<object>;

561

event: Event;

562

helper: jQuery;

563

origin: string;

564

is_copy: boolean;

565

is_foreign: boolean;

566

}

567

```