public function moveDrop(Model $model, $id = null, $newParentId = null, $oldParentId = null, $dropData = null) {
		if (empty($id)) {
			return false;
		}

		$changeRoot = false;
		$dataSource = $model->getDataSource();
		$dataSource->begin();
		if ($newParentId != $oldParentId) {
			$changeRoot = true;
			if (!$this->_changeParent($model, $id, $newParentId)) {
				$dataSource->rollback();

				return false;
			}
		}

		$newDataList = [];
		if (!empty($dropData) && is_array($dropData)) {
			$newDataList = Hash::extract($dropData, '0.{n}.id');
		}
		$oldDataList = $this->_getSubTree($model, $newParentId);
		if ($newDataList == $oldDataList) {
			if (!$changeRoot) {
				return true;
			}

			$dataSource->rollback();

			return false;
		}

		$indexNew = array_search($id, $newDataList);
		$indexOld = array_search($id, $oldDataList);
		if (($indexNew === false) || ($indexOld === false)) {
			return false;
		}

		$delta = $indexNew - $indexOld;
		$method = 'moveDown';
		if ($delta < 0) {
			$delta *= -1;
			$method = 'moveUp';
		}

		$optionsEvent = compact('id', 'newParentId', 'method', 'delta');
		$event = new CakeEvent('Model.beforeUpdateTree', $model, [$optionsEvent]);
		$model->getEventManager()->dispatch($event);
		if ($event->isStopped()) {
			$dataSource->rollback();

			return false;
		}

		$result = $model->$method($id, $delta);
		if ($result) {
			$dataSource->commit();
			$event = new CakeEvent('Model.afterUpdateTree', $model);
			$model->getEventManager()->dispatch($event);
		} else {
			$dataSource->rollback();
		}

		return $result;
	}
public function moveDrop(Model $model, $id = null, $newParentId = null, $oldParentId = null, $dropData = null) {
		if (empty($id)) {
			return false;
		}

		$changeRoot = false;
		$dataSource = $model->getDataSource();
		$dataSource->begin();
		if ($newParentId != $oldParentId) {
			$changeRoot = true;
			if (!$this->_changeParent($model, $id, $newParentId)) {
				$dataSource->rollback();

				return false;
			}
		}

		$newDataList = [];
		if (!empty($dropData) && is_array($dropData)) {
			$newDataList = Hash::extract($dropData, '0.{n}.id');
		}
		$oldDataList = $this->_getSubTree($model, $newParentId);
		if ($newDataList == $oldDataList) {
			if (!$changeRoot) {
				return true;
			}

			$dataSource->rollback();

			return false;
		}

		$indexNew = array_search($id, $newDataList);
		$indexOld = array_search($id, $oldDataList);
		if (($indexNew === false) || ($indexOld === false)) {
			return false;
		}

		$delta = $indexNew - $indexOld;
		$method = 'moveDown';
		if ($delta < 0) {
			$delta *= -1;
			$method = 'moveUp';
		}

		$optionsEvent = compact('id', 'newParentId', 'method', 'delta');
		$event = new CakeEvent('Model.beforeUpdateTree', $model, [$optionsEvent]);
		$model->getEventManager()->dispatch($event);
		if ($event->isStopped()) {
			$dataSource->rollback();

			return false;
		}

		$result = $model->$method($id, $delta);
		if ($result) {
			$dataSource->commit();
			$event = new CakeEvent('Model.afterUpdateTree', $model);
			$model->getEventManager()->dispatch($event);
		} else {
			$dataSource->rollback();
		}

		return $result;
	}
public function moveDrop ( Model $ model , $ id = null , $ newParentId = null , $ oldParentId = null , $ dropData = null ) { if ( empty ( $ id ) ) { return false ; } $ changeRoot = false ; $ dataSource = $ model -> getDataSource ( ) ; $ dataSource -> begin ( ) ; if ( $ newParentId != $ oldParentId ) { $ changeRoot = true ; if ( ! $ this -> _changeParent ( $ model , $ id , $ newParentId ) ) { $ dataSource -> rollback ( ) ; return false ; } } $ newDataList = [ ] ; if ( ! empty ( $ dropData ) && is_array ( $ dropData ) ) { $ newDataList = Hash :: extract ( $ dropData , '0.{n}.id' ) ; } $ oldDataList = $ this -> _getSubTree ( $ model , $ newParentId ) ; if ( $ newDataList == $ oldDataList ) { if ( ! $ changeRoot ) { return true ; } $ dataSource -> rollback ( ) ; return false ; } $ indexNew = array_search ( $ id , $ newDataList ) ; $ indexOld = array_search ( $ id , $ oldDataList ) ; if ( ( $ indexNew === false ) || ( $ indexOld === false ) ) { return false ; } $ delta = $ indexNew - $ indexOld ; $ method = 'moveDown' ; if ( $ delta < 0 ) { $ delta *= - 1 ; $ method = 'moveUp' ; } $ optionsEvent = compact ( 'id' , 'newParentId' , 'method' , 'delta' ) ; $ event = new CakeEvent ( 'Model.beforeUpdateTree' , $ model , [ $ optionsEvent ] ) ; $ model -> getEventManager ( ) -> dispatch ( $ event ) ; if ( $ event -> isStopped ( ) ) { $ dataSource -> rollback ( ) ; return false ; } $ result = $ model -> $ method ( $ id , $ delta ) ; if ( $ result ) { $ dataSource -> commit ( ) ; $ event = new CakeEvent ( 'Model.afterUpdateTree' , $ model ) ; $ model -> getEventManager ( ) -> dispatch ( $ event ) ; } else { $ dataSource -> rollback ( ) ; } return $ result ; }
Move item to new position of tree use drag and drop.

@param Model $model Model using this behavior.
@param int|string $id The ID of the item to moving to new position.
@param int|string|null $newParentId New parent ID of item.
@param int|string|null $oldParentId Old parent ID of item.
@param array $dropData Array of ID subtree for item.
@return bool
@triggers Model.beforeUpdateTree $model array($options)
@triggers Model.afterUpdateTree $model
@see https://github.com/johnny/jquery-sortable
Move item to new position of tree use drag and drop .