I want to allow admin user to generate as much fields as he/she wants. I found a solution in another extension and I used it as my starting point. So I have a code like this:
In system.xml:
<showcases translate="label">
 <label>Showcases</label>
 <frontend_type>text</frontend_type>
 <sort_order>10</sort_order>
 <show_in_default>1</show_in_default>
 <show_in_website>1</show_in_website>
 <show_in_store>1</show_in_store>
 <fields>
 <showcase translate="label">
 <label>Showcases</label>
 <frontend_type>select</frontend_type>
 <frontend_model>awesomehome/adminhtml_showcases</frontend_model>
 <backend_model>adminhtml/system_config_backend_serialized</backend_model>
 <sort_order>410</sort_order>
 <show_in_default>1</show_in_default>
 <show_in_website>1</show_in_website>
 <show_in_store>1</show_in_store>
 </showcase>
 </fields>
</showcases>
And in Namespace/Awesomehome/Block/Adminhtml/Showcases.php:
class Namespace_Awesomehome_Block_Adminhtml_Showcases 
 extends Mage_Adminhtml_Block_System_Config_Form_Field
{
 protected $_addRowButtonHtml = array();
 protected $_removeRowButtonHtml = array();
 protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
 {
 $this->setElement($element);
 $html = '<div id="showcase_template" style="display:none">';
 $html .= $this->_getRowTemplateHtml();
 $html .= '</div>';
 $html .= '<ul id="showcase_container">';
 if ($this->_getValue('showcases')) {
 foreach (array_keys($this->_getValue('showcases')) as $row) {
 if ($row) {
 $html .= $this->_getRowTemplateHtml($row);
 }
 }
 }
 $html .= '</ul>';
 $html .= $this->_getAddRowButtonHtml(
 'showcase_container',
 'showcase_template', $this->__('Add new showcase')
 );
 return $html;
 }
 protected function _getRowTemplateHtml($row = 0)
 {
 $html = '<li><fieldset>';
 $html .= $this->_getShowcaseTypeHtml($row);
 $html .= $this->_getRemoveRowButtonHtml();
 $html .= '</fieldset></li>';
 return $html;
 }
 protected function _getShowcaseTypeHtml($row) {
 $html = '<label>' . $this->__('Showcase type:') . '</label>';
 $html .= '<select style="width:100%;" class="input-text" name="' . $this->getElement()->getName() . '[type][]">';
 $html .= '<option value="1" '
 . ($this->_getValue('type/' . $row) == "1" ? 'selected="selected"' : '') .'>'
 . $this->__("Simple") . "</option>";
 $html .= '<option value="2" '
 . ($this->_getValue('type/' . $row) == "2" ? 'selected="selected"' : '') .'>'
 . $this->__("With Image") . "</option>";
 $html .= '</select><br/>';
 return $html;
 }
It works as expected and it's like this:
Now I want to add an Image upload field to my fieldset. How should I do that?
Update:
I know that in system.xml you can write this code to add image fields:
<image translate="label">
 <label>Image</label>
 <frontend_type>image</frontend_type>
 <backend_model>adminhtml/system_config_backend_image</backend_model>
 <upload_dir config="system/filesystem/media" scope_info="1">awesomehome/topcategories</upload_dir>
 <base_url type="media" scope_info="1">awesomehome/topcategories</base_url>
 <sort_order>30</sort_order>
 <show_in_default>1</show_in_default>
 <show_in_website>1</show_in_website>
 <show_in_store>1</show_in_store>
 <comment>Allowed file types: jpeg, gif, png.</comment>
</image>
But I can't use this approach because I want to have multiple fields, not one.
3 Answers 3
Add this in your system.xml
<logo translate="label comment">
<label>Logo</label>
<comment>Allowed file types: jpeg, gif, png.</comment>
<frontend_type>image</frontend_type>
<backend_model>adminhtml/system_config_backend_image</backend_model>
<upload_dir config="system/filesystem/media" scope_info="1">theme</upload_dir>
<base_url type="media" scope_info="1">theme</base_url>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</logo>
The element represents the location where the image will be uploaded to. In the above example, the image will be saved to a sub-folder under the media folder. e.g. /media/theme/. The element is used to rendering the tag. To output the image from the above example, you could use the following code
echo Mage::getBaseUrl('media') . Mage::getStoreConfig('system_config_name/group/logo');
- 
 I can't usesystem.xmlin my case. Please read my question again.Pedram Behroozi– Pedram Behroozi2015年10月23日 08:40:50 +00:00Commented Oct 23, 2015 at 8:40
- 
 But why you can't use itVivek Khandelwal– Vivek Khandelwal2015年10月23日 08:58:33 +00:00Commented Oct 23, 2015 at 8:58
- 
 Because your approach adds one image field to system config. I want to have dynamic number of image fields.Pedram Behroozi– Pedram Behroozi2015年10月25日 08:35:49 +00:00Commented Oct 25, 2015 at 8:35
- 
 okay. I will tell you a different approachVivek Khandelwal– Vivek Khandelwal2015年10月26日 04:21:23 +00:00Commented Oct 26, 2015 at 4:21
I tried something similar and only got it solved partially.
First, in order to add multiple types of fields in your array/serialised config option, I created an extended version of the class Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract that included the types select, multiselect and file (as the original function only allowed you to use the text type), see https://github.com/Genmato/Core/blob/master/app/code/community/Genmato/Core/Block/System/Config/Form/Field/Array/Abstract.php (file is a bit to large to include here).
Next I found out that combining the file type with other (select/text) fields did not work properly. When saving the data only the file details where available and the array got messed-up. So I opted for a solution to have one field for saving the uploads:
<templates translate="label comment">
 <label>Templates</label>
 <frontend_model>genmato_addresslabel/system_config_form_templates</frontend_model>
 <backend_model>genmato_addresslabel/system_config_backend_storefile</backend_model>
 <sort_order>1</sort_order>
 <show_in_default>1</show_in_default>
 <show_in_website>0</show_in_website>
 <show_in_store>0</show_in_store>
 <upload_dir config="system/filesystem/media" scope_info="1">addresslabel</upload_dir>
 <base_url type="media" scope_info="1">addresslabel</base_url>
 <comment>Label templates, to be used as background in the PDF (only PDF files are allowed)</comment>
 </templates>
The corresponding block class:
class Genmato_AddressLabel_Block_System_Config_Form_Templates extends Genmato_Core_Block_System_Config_Form_Field_Array_Abstract
{
 public function __construct()
 {
 $this->addColumn('template', array(
 'label' => Mage::helper('genmato_addresslabel')->__('Template'),
 'style' => 'width:300px',
 'class' => '',
 'type' => 'file',
 ));
 $this->_addAfter = false;
 $this->_addButtonLabel = Mage::helper('genmato_addresslabel')->__('Add new item');
 $this->setTemplate('genmato/core/system/config/form/field/array.phtml');
 parent::__construct();
 }
}
And the backend model class:
class Genmato_AddressLabel_Model_System_Config_Backend_Storefile extends Mage_Adminhtml_Model_System_Config_Backend_File
{
 protected function _afterLoad()
 {
 $value = (string)$this->getValue();
 $this->setValue(empty($value) ? false : unserialize($value));
 }
 protected function _beforeSave()
 {
 $value = $this->getValue();
 // Load current template data
 $data = unserialize(Mage::getStoreConfig($this->getPath()));
 // Check for deleted records
 if (is_array($data)) {
 foreach ($data as $key => $val) {
 if (!isset($value[$key])) {
 unset($data[$key]);
 }
 }
 }
 // check for new uploads.
 foreach ($value as $key => $val) {
 if (!is_array($val)) {
 continue;
 }
 foreach ($val as $filefield => $filevalue) {
 try {
 if ($_FILES['groups']['tmp_name'][$this->getGroupId()]['fields'][$this->getField()]['value'][$key][$filefield]) {
 $file = array();
 $tmpName = $_FILES['groups']['tmp_name'];
 $file['tmp_name'] = $tmpName[$this->getGroupId()]['fields'][$this->getField()]['value'][$key][$filefield];
 $name = $_FILES['groups']['name'];
 $file['name'] = $name[$this->getGroupId()]['fields'][$this->getField()]['value'][$key][$filefield];
 if (isset($file['tmp_name']) || empty($file['tmp_name'])) {
 $uploadDir = $this->_getUploadDir();
 $uploader = new Mage_Core_Model_File_Uploader($file);
 $uploader->setAllowedExtensions($this->_getAllowedExtensions());
 $uploader->setAllowRenameFiles(true);
 $result = $uploader->save($uploadDir);
 $filename = $result['file'];
 if ($filename) {
 if ($this->_addWhetherScopeInfo()) {
 $filename = $this->_prependScopeInfo($filename);
 }
 }
 $data[$key]['template'] = $filename;
 } else {
 }
 }
 } catch (Exception $e) {
 Mage::throwException($e->getMessage());
 return $this;
 }
 }
 }
 $this->setValue(serialize($data));
 return $this;
 }
}
And a second field where I store my configuration:
<config translate="label comment">
 <label>Label configurations</label>
 <frontend_model>genmato_addresslabel/system_config_form_config</frontend_model>
 <backend_model>genmato_pdflib/system_config_backend_storeserial</backend_model>
 <sort_order>2</sort_order>
 <show_in_default>1</show_in_default>
 <show_in_website>0</show_in_website>
 <show_in_store>0</show_in_store>
 <comment>Label configuration, you can create multiple label configurations for different usages</comment>
 </config>
And the block class used:
class Genmato_AddressLabel_Block_System_Config_Form_Config extends Genmato_Core_Block_System_Config_Form_Field_Array_Abstract
{
 public function __construct()
 {
 $this->addColumn('name', array(
 'label' => Mage::helper('genmato_addresslabel')->__('Name'),
 'style' => 'width:100px',
 ));
 $this->addColumn('template', array(
 'label' => Mage::helper('genmato_addresslabel')->__('Use template'),
 'style' => 'width:100px',
 'type' => 'select',
 'options' => Mage::getModel('genmato_addresslabel/system_config_source_templates')->getTemplates(),
 ));
 $this->addColumn('width', array(
 'label' => Mage::helper('genmato_addresslabel')->__('W (mm)'),
 'style' => 'width:40px'
 ));
 $this->addColumn('height', array(
 'label' => Mage::helper('genmato_addresslabel')->__('H (mm)'),
 'style' => 'width:40px'
 ));
 $this->addColumn('rotate', array(
 'label' => Mage::helper('genmato_addresslabel')->__('Rotate 90'),
 'type' => 'select',
 'options' => array("0" => "No", "1" => "Yes"),
 'style' => 'width:50px'
 ));
 $this->addColumn('multiple', array(
 'label' => Mage::helper('genmato_addresslabel')->__('Multiple labels'),
 'type' => 'select',
 'options' => array("0" => "No", "1" => "Yes"),
 'style' => 'width:50px'
 ));
 $this->addColumn('label_width', array(
 'label' => Mage::helper('genmato_addresslabel')->__('W (mm)'),
 'style' => 'width:40px'
 ));
 $this->addColumn('label_height', array(
 'label' => Mage::helper('genmato_addresslabel')->__('H (mm)'),
 'style' => 'width:40px'
 ));
 $this->_addAfter = false;
 $this->_addButtonLabel = Mage::helper('genmato_addresslabel')->__('Add new item');
 $this->setTemplate('genmato/core/system/config/form/field/array.phtml');
 parent::__construct();
 }
}
Here I use a select/dropdown option to select the uploaded file per config row, this also allows me to use the same file on multiple rows.
This might not be the perfect solution for your situation, but might be a starting point to solve your problem. Feel free to use parts of the code used in the Genmato_Core (See https://github.com/Genmato/Core) module for your own solution.
- 
 Thanks. I'll try it today and will let you know. It seems promising.Pedram Behroozi– Pedram Behroozi2015年10月26日 06:01:06 +00:00Commented Oct 26, 2015 at 6:01
- 
 @PedramBehroozi did you try it, and did it work? I would also be interested :)simonthesorcerer– simonthesorcerer2015年11月10日 16:12:45 +00:00Commented Nov 10, 2015 at 16:12
- 
 @simonthesorcerer not yet, but I should deal with it before Saturday. Will update soon.Pedram Behroozi– Pedram Behroozi2015年11月11日 06:28:35 +00:00Commented Nov 11, 2015 at 6:28
May below links helps you to solve your query.
http://www.mydons.com/how-to-display-image-preview-in-admin-form-magento/
Show thumbnail image and delete image in custom module admin form
- 
 Rather than post links post some code just in case the links no longer workrob3000– rob30002015年10月21日 04:13:15 +00:00Commented Oct 21, 2015 at 4:13
Explore related questions
See similar questions with these tags.