To Creating A Multiple Category Chooser in Backend:
In your Widget.xml:
<parameter name="multi_category_chooser" xsi:type="block" visible="true" required="true" sort_order="10">
<label translate="true">Select Categories</label>
<block class="[Vendor]\[Modul]\Block\Adminhtml\Category\Widget\[Chooser]" />
</parameter>
Create File : [Vendor][Modul]\Block\Adminhtml\Category\Widget[Chooser]
<?php
namespace Vendor\Module\Block\Adminhtml\Category\Widget;
class Chooser extends \Magento\Backend\Block\Template {
protected $_elementFactory;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Data\Form\Element\Factory $elementFactory
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Data\Form\Element\Factory $elementFactory, array $data = []
) {
$this->_elementFactory = $elementFactory;
parent::__construct($context, $data);
}
/**
* Prepare chooser element HTML
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element Form Element
* @return \Magento\Framework\Data\Form\Element\AbstractElement
*/
public function prepareElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element) {
$htmlId = $element->getId();
$data = $element->getData();
$data['after_element_js'] = $this->_afterElementJs($element);
$data['after_element_html'] = $this->_afterElementHtml($element);
$data['readonly'] = 'readonly';
$htmlItem = $this->_elementFactory->create('text', ['data' => $data]);
$htmlItem
->setId("{$htmlId}")
->setForm($element->getForm())
->addClass('required-entry')
->addClass('entities');
$return = <<<HTML
<div id="{$htmlId}-container" class="chooser_container">{$htmlItem->getElementHtml()}</div>
HTML;
$element->setData('after_element_html', $return);
return $element;
}
protected function _afterElementHtml($element)
{
$htmlId = $element->getId();
$return = <<<HTML
<a href="javascript:void(0)" onclick="MultiCategoryChooser.displayChooser('{$htmlId}-container')" class="widget-option-chooser" title="{__('Open Chooser')}">
<img src="{$this->getViewFileUrl('images/rule_chooser_trigger.gif')}" alt="{__('Open Chooser')}" />
</a>
<a href="javascript:void(0)" onclick="MultiCategoryChooser.hideChooser('{$htmlId}-container')" title="{__('Apply')}">
<img src="{$this->getViewFileUrl('images/rule_component_apply.gif')}" alt="{__('Apply')}">
</a>
<div class="chooser"></div>
HTML;
return $return;
}
protected function _afterElementJs($element)
{
$chooserUrl = $this->getUrl('adminhtml/widget_instance/categories', []);
$htmlId = $element->getId();
$return = <<<HTML
<script>
require([
'jquery',
'Magento_Ui/js/modal/alert',
"prototype"
], function (jQuery, alert) {
var MultiCategoryChooser = {
displayChooser : function(chooser) {
chooser = $(chooser).down('div.chooser');
entities = chooser.up('div.chooser_container').down('input[type="text"].entities').value;
postParameters = {selected: entities};
url = '{$chooserUrl}';
if (chooser && url) {
if (chooser.innerHTML == '') {
new Ajax.Request(url, {
method : 'post',
parameters : postParameters,
onSuccess : function(transport) {
try {
if (transport.responseText) {
Element.insert(chooser, transport.responseText);
chooser.removeClassName('no-display');
chooser.show();
}
} catch (e) {
alert({
content: 'Error occurs during loading chooser.'
});
}
}
});
} else {
chooser.removeClassName('no-display');
chooser.show();
}
}
},
hideChooser : function(chooser) {
chooser = $(chooser).down('div.chooser');
if (chooser) {
chooser.addClassName('no-display');
chooser.hide();
}
},
checkCategory : function(event) {
node = event.memo.node;
container = event.target.up('div.chooser_container');
value = container.down('input[type="text"].entities').value.strip();
if (node.attributes.checked) {
if (value) ids = value.split(',');
else ids = [];
if (-1 == ids.indexOf(node.id)) {
ids.push(node.id);
container.down('input[type="text"].entities').value = ids.join(',');
}
} else {
ids = value.split(',');
while (-1 != ids.indexOf(node.id)) {
ids.splice(ids.indexOf(node.id), 1);
container.down('input[type="text"].entities').value = ids.join(',');
}
}
}
}
window.MultiCategoryChooser = MultiCategoryChooser;
jQuery(function() {
var container = $('{$htmlId}-container');
if (container) {
container.up(0).down('.control-value').hide();
}
Event.observe(document, 'node:changed', function(event){
MultiCategoryChooser.checkCategory(event);
});
Event.observe(document, 'category:beforeLoad', function(event) {
container = event.target.up('div.chooser_container');
value = container.down('input[type="text"].entities').value.strip();
event.memo.treeLoader.baseParams.selected = value;
});
});
});
</script>
HTML;
return $return;
}
}
This is the Multi Category Chooser.
If you want to upload an image then why don't you use image selection button.?
If you like the editor then use it.But it is not a proper way to upload an image using an editor.You can use the button instead. If you don't know how to do it. Let me explain.
Here is my code.
The below code is written in block file which creates a button.
$fieldset->addField(
'image',
'file',
[
'name' => 'image',
'label' => __('Image'),
'title' => __('Image'),
]
);
Image is the database field name. In your case it's wysiwyg editor.I don't know the exact but once check in your database.
The below code is used to save the image in your table. Now put this code into your Controller.
<?php
namespace Vendor\Module\Controller\Adminhtml\Slider;
use Magento\Framework\App\Filesystem\DirectoryList;
class Save extends \Magento\Backend\App\Action
{
protected $_mediaDirectory;
protected $_fileUploaderFactory;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\Filesystem $filesystem,
\Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory
)
{
$this->_mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
$this->_fileUploaderFactory = $fileUploaderFactory;
parent::__construct($context);
}
public function execute()
{
/*For Image Upload*/
/** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
try{
$target = $this->_mediaDirectory->getAbsolutePath('imagefolder/');
$targetOne = "imagefolder/";
/** @var $uploader \Magento\MediaStorage\Model\File\Uploader */
$uploader = $this->_fileUploaderFactory->create(['fileId' => 'image']);
/** Allowed extension types */
$uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png', 'zip', 'doc']);
/** rename file name if already exists */
$uploader->setAllowRenameFiles(true);
/** upload file in folder "mycustomfolder" */
$result = $uploader->save($target);
/*If file found then display message*/
if ($result['file'])
{
$this->messageManager->addSuccess(__('File has been successfully uploaded'));
}
}
catch (Exception $e)
{
$this->messageManager->addError($e->getMessage());
}
/*For Image Upload Finished*/
$data = $this->getRequest()->getPostValue();
$data['image'] = $targetOne.$result['file'];
if (!$data) {
$this->_redirect('*/*/filenaem');
return;
}
try {
$rowData = $this->_objectManager->create('Vendor\Module\Model\Slider');
$rowData->setData($data);
if (isset($data['id']))
{
$rowData->setEntityId($data['id']);
}
$rowData->save();
$this->messageManager->addSuccess(__('Row data has been successfully saved.'));
}
catch (Exception $e)
{
$this->messageManager->addError(__($e->getMessage()));
}
$this->_redirect('*/*/index');
return $this->resultRedirectFactory->create()->setPath(
'*/*/upload', ['_secure'=>$this->getRequest()->isSecure()]
);
}
/**
* Check Category Map permission.
*
* @return bool
*/
protected function _isAllowed()
{
return $this->_authorization->isAllowed('Vendor_Module::Module_list');
}
}
After that you want to called it in phtml for the result..so bellow code write in phtml file.
Here is code.
$collection = $block->getCollectionFor();
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); //instance of\Magento\Framework\App\ObjectManager
$storeManager = $_objectManager->get('Magento\Store\Model\StoreManagerInterface');
$currentStore = $storeManager->getStore();
//Base URL for saving image into database.
$mediaUrl = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
getCollectionFor() is write in my block.so according to that, you should apply as your block file.
I hope this is helpful to you. If you have any query let me know.
Best Answer
The problem is that you cannot use depends on widget items that are of type chooser :(
In the file
js/mage/adminhtml/form.js
it processes the changes on widgets in the functiontrackChange
. Here is loads the hidden field that is used to store the value of the item as a reference and the using up it works up the dom to find the td that is should show or hide.The problem with the chooser items is that there is no hidden input field that matches the id format that magento is looking for.
You will see the JS error
Uncaught TypeError: Cannot read property 'up' of null
.To get part of the depends working you can look into how the html of the chooser is built in the file
Mage_Widget_Block_Adminhtml_Widget_Chooser
. By simply adding a hidden field with the id$element->getId()
to the returned string of the function_toHtml
the field itself with hide/show but the button for choosing will not as this is part of a different row in the table. Here you would have to update the javascript to deal with the structure. Luckly the$chooserId
that is used to build the button appears to be derived from the element id and so this should be fairly simply to find via javascript.