# 11. 1 Xây dựng chức năn kéo thả clone (ok)

![](/files/-MSTLQhf9wy_uOdqd5PQ)

C:\xampp\htdocs\test\wp-content\plugins\plugin-name\admin\class-wpf-admin\_ct.php

```
public function enqueue_scripts($hook) {
    $screen = get_current_screen();
    if ($screen->id != 'customize') {
      $plugin_dir = plugin_dir_url(__FILE__);
      wp_register_script($this->plugin_name, $plugin_dir . 'js/wpf-admin_ct.js', array('jquery'), $this->version, false);
      wp_enqueue_script($this->plugin_name);
      wp_enqueue_style($this->plugin_name, $plugin_dir . 'css/wpf-themplate.css', array(), $this->version, 'all');
      wp_enqueue_script($this->plugin_name.'-template', $plugin_dir . 'js/wpf-themplate_ct.js', array('jquery'), $this->version, false);
      wp_enqueue_script('jquery-ui-core');
      // wp_enqueue_script('jquery-ui-sortable');
      wp_enqueue_script('jquery-ui-draggable');
      wp_enqueue_script('jquery-ui-droppable');
    }
  }
```

C:\xampp\htdocs\test\wp-content\plugins\plugin-name\admin\js\wpf-themplate\_ct.js

```
var WPF;
(function ($, window, document, undefined) {
	// Builder Function
	WPF = {
		prefix: 'wpf_ct_',
		template_type: false,
		init: function ($options) {
			$options = $.extend({
        prefix: this.prefix,
        template_type: this.template_type
    	},$options);
    	this.prefix = $options.prefix;
      this.template_type = $options.template_type;
      this.bindEvents();
		},
		bindEvents: function () {
			this.Save();
			this.InitDraggable();
		},
		Save: function () {
			var self = this;
			$('#' + self.prefix + 'submit').click(function (event) {
				event.preventDefault();
				var $form = $(this).closest('form'),
				$inputs = $('.' + self.prefix + 'back_builder').find('input,select,textarea');
				$inputs.prop('disabled', true);
				setTimeout(function () {
					var $data = self.ParseData();
					console.log($data);
				}, 100);
			});
		},
		ParseData: function () {
			var $wrapper = $('#' + WPF.prefix + 'module_content'),
			$data = {},
			$modules = $wrapper.find('.' + WPF.prefix + 'back_active_module_content');
		},
		InitDraggable: function () {
			var $this = this;
			console.log($this.prefix)
			$('.' + $this.prefix + 'back_module_panel .' + $this.prefix + "back_module").draggable({
        helper: "clone"
			});
		}
	}
}(jQuery, window, document));
```

C:\xampp\htdocs\test\wp-content\plugins\plugin-name\includes\class-wpf-form\_ct.php

```
<?php
class WPF_Form_CT {
  protected $plugin_name;
  protected $version;
  protected $themplate_id = false;
  public function __construct($plugin_name, $version, $themplate_id = false) {
    $this->plugin_name  = $plugin_name;
    $this->version      = $version;
    $this->themplate_id = $themplate_id;
  }
  public function form() {
    $sort_cmb  = array_merge(WPF_Utils_CT::get_wc_attributes(), WPF_Utils_CT::get_default_fields());
    $languages = array(
      'en' => array(
        'name'     => '',
        'selected' => true,
      ),
    );
    natcasesort($sort_cmb);
    $layout = $data = array();
    $this->add_fields($data);
    ?>
    	<input type="hidden" value="" name="layout" id="wpf_layout" />
    	<input type="hidden" value="<?php echo $this->themplate_id ?>" id="wpf_themplate_id" name="themplate_id" />
      <div class="wpf_ct_back_builder">
        <div class="wpf_ct_back_module_panel">
          <?php foreach ($sort_cmb as $type => $name): ?>
            <div <?php if (!empty($layout[$type])): ?>style="display:none;"<?php endif; ?> data-type="<?php echo $type ?>" id="wpf_ct_cmb_<?php echo $type ?>" class="wpf_ct_back_module"> 
              <?php $this->module($type, $name, array(), $languages); ?>
            </div>
          <?php endforeach; ?>
        </div>
        <div class="wpf_ct_back_row_content" id="wpf_ct_module_content">  
          <div class="wpf_ct_module_holder">
            <div class="wpf_empty_holder_text"><?php _e('Drop module here', 'wpf') ?></div>
          </div>
        </div>
      </div>
    <?php
  }
  private function module($type, $name, array $module = array(), array $languages = array()) {
    ?>
      <strong class="wpf_ct_module_name"><?php echo $name ?></strong>
      <div class="wpf_ct_back_module_top">
        <div class="wpf_left">
          <span class="wpf_back_active_module_title"><?php echo $name ?></span>
        </div>
        <div class="wpf_right">
          <a href="#" class="wpf_module_btn wpf_toggle_module"></a>
          <a href="#" class="wpf_module_btn wpf_delete_module"></a>
        </div>
      </div>
      <div class="wpf_active_module">
        <?php WPF_Utils_CT::module_multi_text($type, $module, $languages, 'field_title', __('Field Title', 'wpf_ct')); ?>
        <div data-type="<?php echo $type ?>" class="wpf_back_active_module_content">    
          <div class="wpf_back_active_module_row wpf_back_active_module_hide_field">

          </div>
        </div>
      </div>
    <?php
  }
  private function add_fields($data = array()) {
    $layouts = array(
      'vertical' => __('Vertical Layout', 'wpf'),
      'horizontal' => __('Horizontal Layout', 'wpf')
    );
    ?>
      <div class="wpf_lightbox_row">
        <div class="wpf_lightbox_label"><label for="wpf_name"><?php _e('Form Title', 'wpf'); ?></label></div>
        <div class="wpf_lightbox_input">
          <input id="wpf_name" class="wpf_towidth" type="text" value="<?php echo !empty($data['name']) ? $data['name'] : '' ?>" name="name" />
        </div>
      </div>
      <div class="wpf_lightbox_row ">
        <div class="wpf_lightbox_label"><?php _e('Layout', 'wpf'); ?></div>
        <div class="wpf_lightbox_input wpf_grid wpf_changed">
          <?php foreach ($layouts as $id => $ch): ?>
            <input id="wpf_<?php echo $id ?>" type="radio" value="<?php echo $id; ?>" name="type" <?php if ((!$data && $id === 'vertical' ) || ( isset($data['type']) && $data['type'] == $id )): ?>checked="checked"<?php endif; ?>/>
            <label title="<?php echo $ch ?>" for="wpf_<?php echo $id ?>" class="wpf_grid_<?php echo $id; ?>"></label>
          <?php endforeach; ?>
        </div>
      </div>
    <?php
  }
  public function save_themplate(array $post) {
    $result = false;
    if (!empty($post['layout'])) {
      $option = WPF_Options_CT::get_option($this->plugin_name, $this->version);
      if (empty($post['name'])) {
        $post['name'] = uniqid($this->plugin_name . '_');
      }
      $themplate_id = !empty($post['themplate_id']) ? $post['themplate_id'] : $option->unique_name($post['name']);
      $layout = stripslashes_deep($post['layout']);
    }
    echo '<pre>';
      var_export($themplate_id);
    echo '</pre>';
    die('aaaaaaa');
    return $result;
  }
}
?>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://learnphp.gitbook.io/learnphp/wordpress-advand/11.-1-xay-dung-chuc-nan-keo-tha-clone-ok.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
