douhu2890 2012-06-06 21:56
浏览 19
已采纳

Zend Framework form_TableForm需要有多个表

Ok, I'm new to the Zend Framework so excuse me if this is kinda ignorant.

Right now I have a form build built into a table and the table looks like

<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>

Who ever built it initially left something for the people I am working for to desire. These same people want to now have basically have a layout that looks like..

<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>
<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>

the table is currently rolled out via a foreach statement as the fields are dynamic and are role based. Essentially the code spits out a full array of that forms elements, and the foreach builds it out. I understand that much about it. But my main question is, is there a way to break out of the table so to speak and then roll out another?

overall I'd like to in essence inject </tr></table><br><table> in some how so I can have 2 distinct tables.

updated with loop I have to exclude some variables and some stuff like it as its part of a propietray work in progress so Im not allowed to post any code from it on the web so that said heres a minimal version, stripped of anything that may make it noticeable

$form = new form_TableForm(self::CHANGEPREFS);
        $form->setAction($this->_helper->url('saveprefs'));
    foreach ($defaults as $name => $value)
            {
               if ($name == 'xxx1' && (!xxx::eval('xxx','view') || $zzz)) continue;
               if ($name == 'xxx2' && !xxx::eval('xxx','view')) continue;
               if ($name == 'xxx3' && !xxx::eval('xxx','alerts')) continue;
               if ($name == 'xxx4' && !xxx::eval('xxx','alerts')) continue;

               $element = new Zend_Form_Element_Checkbox($name);
               $element->setLabel($this->_helper->Literal->xxx($name));
               if ($value) $element->setValue($value);
               $element->setOptions(array(
                   'required' => false,
                   'fullrow' => true
                   ));
               $form->addElement($element);
               //if($name == 'xxx5'){$form .= "</table><table>";}
               //bad attempt at injection above
            }
        $form->addDisplayGroup(array('savebutton'), 'buttonsgroup', array('fullrow' => true));
        return $form;
  • 写回答

1条回答 默认 最新

  • duanjiao6711 2012-06-06 23:40
    关注

    It's been a long time since I've used Zend_Form_Decorators but I think the solution will be with those.

    A brief overview of Zend_Form and decorators might help.

    Zend_Form is sort of the master container of Zend_Form_Element items. These classes have default "decorators" that, when you print the entire Zend_Form object, the class will loop through all the objects and spit out the HTML formatting that's set in it's class.

    You can set the decorator HTML when you create your Zend_Form_Element object. In your foreach loop, you're creating the elements so you can do a conditional to modify the specific element that should close/open a new table. But it can be tricky to get to work right due to how Zend_Form generates it's HTML. I recall needing to create a custom decorator because it just wasn't possible to do something fairly easy with the standard decorators.

    In your case above, you can't just append some HTML code to the $form object because the $form object is a complex class.

    Anyway, enough talk. Try something like this:

    // create the form element
    $element = new Zend_Form_Element_Checkbox($name);
    ... // same code as above
    
    // do something different for 'special' items
    if($name == 'xxx5'){
    
        $element->setDecorators(array(
            array('ViewHelper'),
            // you might need to do this instead of the above
            // array('ViewHelper', array('helper' => 'formCheckbox')),
            array('HtmlTag', array(
                'tag' => 'table', 
                'placement'=>'APPEND', 
                'closeOnly' => true)),
            array(
                'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
                'options' => array(
                    'tag' => 'table', 
                    'placement'=>'APPEND', 
                    'openOnly' => true)
            ),
        ));
    }
    
    // now add the element to the form object
    $form->addElement($element);
    

    Let me try to break this down for you.

    $element->setDecorators( array($d1, $d2, [...]) );
    

    This sets the decorators for this element. Each decorator ($d1, $d2, etc) is built upon from the previous decorator. Think of it as $d1 is going to spit out an HTML string and then $d2 will append/prepend it's HTML string to $d1.

    array('ViewHelper'),
    

    This is the default decorator to even get to the element to show. If you don't have this, there will be nothing to show. Each element has a standard decorator. I believe this might include it, but you might need to force the default with:

    array('ViewHelper', array('helper' => 'formCheckbox')),
    

    Play around with both. At this point the HTML generated should be:

    <input type="checkbox" />
    

    or perhaps it will include table row/cell tags. This part I'm a bit rusty on.

    <tr><td><input type="checkbox" /></td></tr>
    

    If it doesn't, we can get them added by defining them. But lets move on...

    array('HtmlTag', array(
            'tag' => 'table', 
            'placement'=>'APPEND', 
            'closeOnly' => true)),
    

    "HtmlTag" is a standard decorator that ships with Zend_Framework. It basically allows you to add whatever HTML tag you want. The options I set tell it to use the "table" tag, append it to the previous decorator HTML string, and only use the close tag (</table>).

    At this point lets assume we just have the input tag for brevity. We now have:

    <input type="checkbox" /></table>
    

    Now we want to also add an opening table decorator:

    array(
            'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
            'options' => array(
                'tag' => 'table', 
                'placement'=>'APPEND', 
                'openOnly' => true)
        ),
    

    This part might be slightly confusing. Zend_Form doesn't allow you to use the same decorator more than once on a given element. The reason is how the code generates. Basically the decorator name is used like a namespace. If you add two of the same decorators, the later one overrides the former one.

    To get around this, you can give it an alias name, that's what this bit of code is doing:

    'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
    

    "My_Alias_HtmlTag" can be anything you want, but following the same rules don't use an Alias name twice. You'll need a new Alias name every time.

    The rest of the code should be self evident. I want to append an opening table tag to my current HTML string. The final result should be:

    <input type="checkbox" /></table><table>
    

    So, when you print out the $form object, when it hits the "specially decorated" elements, it should produce the HTML code above.

    Of course, this will take some playing around with. Like I mentioned, I'm a bit rusty with the whole Zend_Form and it's decorators.

    There's also a concern that the custom Zend_Form class might be doing unexpected things that might not make this work right.

    But give it a try.

    I think this blog post by Matthew Weier O'Phinney helped a lot: http://devzone.zend.com/1240/decorators-with-zend_form/

    I hope that helps!

    Cheers!

    update

    I had a typo. " 'tag' => 'true' " should have been " 'tag' => 'table'". I updated my previous code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线