I'm creating a custom widget and control in Elementor. What I want to achieve is a button, when clicked, will open the file dialog to let the user choose a file. Once a file is chosen, an ajax script will upload the file and returns the download link. Please see below the pictures of what I want to achieve.
The file is uploading properly and I can set the value of the hidden input field with the file's url. But I can't get the url to show on the frontend.
Here is my current code:
Control (file-upload.php)
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class File_Upload_Control extends \Elementor\Base_Data_Control {
public function get_type() {
return 'fileupload';
}
protected function get_default_settings() {
return [
'label' => 'Download File',
];
}
public function content_template() {
$control_uid = $this->get_control_uid();
?>
<div class="elementor-control-field">
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
<div class="elementor-control-input-wrapper">
<p class="eae-form-notice"></p>
<form action="" method="post" name="eae-file-upload-form">
<?php wp_nonce_field('eae-file-upload'); ?>
<input type="file" name="eae-file">
</form>
</div>
<input id="<?php echo $control_uid; ?>" type="hidden" name="eae-file-link" class="elementor-control-tag-area" title="{{ data.title }}" data-setting="{{ data.name }}" />
</div>
<?php
}
public function enqueue() {
wp_register_script( 'eae-file-upload', plugins_url( 'assets/js/file-upload.js', __DIR__ ) );
$data = array(
'upload_url' => admin_url('async-upload.php'),
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('media-form')
);
wp_localize_script( 'eae-file-upload', 'su_config', $data );
wp_enqueue_script( 'eae-file-upload' );
}
}
Widget (download-button.php)
<?php
class Download_Button_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'Download Button';
}
public function get_title() {
return __( 'Download Button', 'elementor-artbees-extension' );
}
public function get_icon() {
return 'fa fa-download';
}
public function get_categories() {
return [ 'basic' ];
}
protected function _register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => __( 'Content', 'elementor-artbees-extension' ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'button_text',
[
'label' => __( 'Text', 'elementor-artbees-extension' ),
'type' => \Elementor\Controls_Manager::TEXT,
'input_type' => 'text',
'default' => __( 'Click here', 'elementor-artbees-extension' ),
'placeholder' => __( 'Enter button text here', 'elementor-artbees-extension' ),
]
);
$this->add_control(
'download_file',
[
// 'label' => __( 'Download File', 'elementor-artbees-extension' ),
'type' => 'fileupload',
]
);
}
protected function render() {
$settings = $this->get_settings_for_display();
echo '<div class="eae-text">';
echo $settings['button_text'] . '<br>';
echo $settings['download_file'];
echo '</div>';
}
protected function _content_template() {}
}
JS (file-upload.js)
(function($) {
$(document).ready(function() {
var notice = $('.eae-form-notice');
var form = $('form[name=eae-file-upload-form]');
var file = form.find('input[name=eae-file]');
file.live('change', function(e) {
e.preventDefault();
var formData = new FormData();
formData.append('action', 'upload-attachment');
formData.append('async-upload', e.target.files[0]);
formData.append('name', e.target.files[0].name);
formData.append('_wpnonce', su_config.nonce);
$.ajax({
url: su_config.upload_url,
data: formData,
processData: false,
contentType: false,
dataType: 'json',
type: 'POST',
beforeSend: function() {
file.hide();
notice.html('Uploading…');
},
success: function(resp) {
// console.log(resp.data.url);
$('input[name=eae-file-link]').val(resp.data.url);
}
});
});
});
})(jQuery);
var_dump( $settings );
to see the array items; the file URL should be somewhere. And have you tried$settings = $this->get_settings();
?$settings = $this->get_settings();
but didn't work. I changed the input hidden to input text just to see if it works. Then on the input text I tried typing and it's automatically changing the text live on the frontend. But when I use the upload function, the javascript changes the value of the input but it doesn't automatically change on the frontend.