tomasr tomasr - 23 days ago 7
PHP Question

Difficult decorators for file input

I need this markup for file input:

<label class="col-sm-12">File upload</label>
<div class="col-sm-12">
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput">
<i class="glyphicon glyphicon-file fileinput-exists"></i>
<span class="fileinput-filename"></span>
</div>
<span class="input-group-addon btn btn-default btn-file">
<span class="fileinput-new">Select file</span>
<span class="fileinput-exists">Change</span>
<input type="file" name="...">
</span>
<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a
</div>
<ul class="errors">
<li>Some error</li>
</ul>
</div>


I tried it like that:

<label class="col-sm-12">Attachment</label>
<div class="col-sm-12">
<?php echo $this->form->attachment; ?>
</div>


With very difficult decorator:

$this->fileDecorator = array(
array(
array('divOpen' => 'HtmlTag'), array('tag' => 'div', 'class' => 'form-control', 'data-trigger' => 'fileinput', 'openOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('i' => 'HtmlTag'), array('tag' => 'i', 'class' => 'glyphicon glyphicon-file fileinput-exists', 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('span' => 'HtmlTag'), array('tag' => 'span', 'class' => 'fileinput-filename', 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('divClose' => 'HtmlTag'), array('tag' => 'div', 'closeOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('spanOpen' => 'HtmlTag'), array('tag' => 'span', 'class' => 'input-group-addon btn btn-default btn-file', 'openOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
'Callback',
array('callback' =>
function($content, $element, $options) {
return "<span class=\"{$options['class']}\">{$options['text']}</span><span class=\"{$options['class2']}\">{$options['text2']}</span>";
},
'class' => 'fileinput-new',
'text' => $this->translator->_('_selectFile'),
'class2' => 'fileinput-exists',
'text2' => $this->translator->_('_change')
)
),
'File',
array(
array('spanClose' => 'HtmlTag'), array('tag' => 'span', 'closeOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
'Callback',
array('callback' =>
function($content, $element, $options) {
return "<a href=\"#\" class=\"{$options['class']}\" data-dismiss=\"{$options['data-dismiss']}\">{$options['text']}</a>";
},
'class' => 'input-group-addon btn btn-default fileinput-exists',
'text' => $this->translator->_('_remove'),
'data-dismiss' => 'fileinput'
)
),
array(
array('div' => 'HtmlTag'), array('tag' => 'div', 'class' => 'fileinput fileinput-new input-group', 'data-provides' => 'fileinput')
),
'Errors'
);


But problem is, that Callback can be only once in decorator (not like HtmlTag). And tag with content is not possible add without callback. It can be solved with more callbacks or differently?

Edit:
I have idea. Is possible to add File decoratror to Callback decorator?

Answer

It is simple like that:

<div class="form-group<?php echo count($this->form->attachment->getErrors()) ? ' has-error has-feedback' : null; ?>">
  <label class="col-sm-12"><?php echo $this->form->attachment->renderLabel(); ?></label>
    <div class="col-sm-12">
      <div class="fileinput fileinput-new input-group" data-provides="fileinput">
        <div class="form-control" data-trigger="fileinput">
          <i class="glyphicon glyphicon-file fileinput-exists"></i>
          <span class="fileinput-filename"></span>
        </div>
        <span class="input-group-addon btn btn-default btn-file">
          <span class="fileinput-new">Select file</span>
          <span class="fileinput-exists">Change</span>
          <?php echo $this->form->attachment->renderFile(); ?>
        </span>
        <a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
      </div>
      <?php echo $this->formErrors($this->form->attachment->getMessages()); ?>
    </div>
  </div>