基于1对n关系的动态添加的表单字段 - 什么框架替代? [英] Dynamic added form fields based on 1-to-n relation - What framework alternatives?

查看:164
本文介绍了基于1对n关系的动态添加的表单字段 - 什么框架替代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们必须开发一个多模型表单,使用ajax调用来动态添加或删除子模型字段集。



例如,让我们假设这个团队方案::

 团队:
团队名称:
团队国家:

会员:
会员名称:
会员A年龄:
[添加其他会员]

[注册团队和会员]

我们目前使用 Yii 。至于我们可以告诉 Yii不支持这种开箱即用(也没有任何扩展这样做)。请不要告诉我有,如果你没有做到。就我们可以说,目前不可能没有大量的扩展工作。



因此,我们可以尝试整合< a href =http://framework.zend.com/manual/2.0/en/modules/zend.form.collections.html#adding-new-elements-dynamically =nofollow> Zend表单集合



我的问题很简单:。



从这里的所有开发人员和程序员,使用php框架,你使用什么框架,以完成上述情况?

解决方案

这里是最后的解决方案,form id是#quoteForm 。在这里,您可以合并两种活动表单的设置:

  //添加汽车按钮
$ addCar)。on('click',function(){
$ .get('<?php echo Yii :: app() - > createAbsoluteUrl('quote / addCar');?& +'?index ='+(carCount + 1),function(data){
var settings = $(#quoteForm)。data('settings');
$(#quoteForm ).data('settings',null);
$(#carlist)。append(data);
var settings_new = $(#quoteForm)。
carCount ++;

$ .each(settings_new.attributes,function(k,v){
settings.attributes.push(v);
});
//设置新设置
$(#quoteForm)。data('settings',settings);
});
pre>

我实际上使用从CActiveForm扩展的ActiveForm类,并且有这种方法将JS添加到客户端脚本,而不运行窗口小部件(从CActiveForm-> run() :

  public function registerJs()
{
$ options = $ this-> clientOptions;
if(isset($ this-> clientOptions ['validationUrl'])&& is_array($ this-> clientOptions ['validationUrl']))
$ options ['validationUrl'] = CHtml :: normalizeUrl($ this-> clientOptions ['validationUrl']);

$ options ['attributes'] = array_values($ this-> attributes);

if($ this-> summaryID!== null)
$ options ['summaryID'] = $ this-> summaryID;

if($ this-> focus!== null)
$ options ['focus'] = $ this->

if(!empty(CHtml :: $ errorCss))
$ options ['errorCss'] = CHtml :: $ errorCss;

$ options = CJavaScript :: encode($ options);
$ cs = Yii :: app() - > clientScript;
$ cs-> registerCoreScript('yiiactiveform');
$ id = $ this-> id;
$ cs-> registerScript(__ CLASS __。'#'。$ id,jQuery('#$ id')。yiiactiveform($ options););
}

这里是控制器部分。您创建一个表单,但只显示字段,而不是使用它作为一个小部件:

  $ form = new ActiveForm 
$ form-> enableAjaxValidation = false;
$ form-> enableClientValidation = true;
$ form-> id ='quoteForm';


$ car = new \QuotesHistory();
$ this-> renderPartial('car_row',compact('car','carMakes','index','form'),false,true);

这里是局部视图的一小部分($ index实际上是carCount,获取请求),这个部分有很多字段,他们都验证和提交正确:

 < div class = field-box> 
<?php
echo $ form-> hiddenField($ car,[$ index] id);
echo $ form-> label($ car,[$ index] automake_id,array('class'=>'form-label'));

echo $ form-> dropDownRow($ car,[$ index] automake_id,CHtml :: listData($ carMakes,'id','name'),array 'data-target'=> CHtml :: activeId($ car,[$ index] automodel_id),
'empty'=>'Select Make',


echo $ form->错误($ car,[$ index] automake_id,array(
'class'=>'alert-msg',
' style'=>'margin:0;'
));
?>
< / div>

在最后一个部分,你需要添加这个在视图的结尾,

 <?php 
if(Yii :: app() - > request-> isAjaxRequest)//我们不需要这个在正常渲染
$ form-> registerJs();
?>

最后一步:为了使所有这一切正常工作,你不应该在ajax响应。您可以在jQuery中执行此操作 - http://www.eirikhoem.net/blog/2011/08/29/yii-framework-preventing-duplicate-jscss-includes-for-ajax-requests/



我已经测试过这个代码,它的工作原理。如果我删除元素,我没有提交表单的问题。


We have to develop a multi-model form that should use ajax calls to dynamically add or remove, sub-model fieldsets.

For example, let's imagine this team form scenario:

Team:
Team Name: 
Team Country:

Members:
Member A name: 
Member A age: 
      [add another member]

[REGISTER TEAM AND MEMBERS]

We are using Yii at the moment. As as far as we can tell Yii doesn't support this out of the box (nor there is any extension that does this). Please don't tell me that there is, if you have not done it. As far as we can tell, that's not possible at the moment without A LOT of extending work.

So, we may try to integrate Zend Form Collections but it seems a pain.

So, Zend do have this.

My question is quite simple:

From all developers and programmers here present, that use php frameworks, what framework do you use, in order to accomplish the scenario described above? Other than Zend, that, we know, do have this already.

解决方案

Here is the final solution, form id is #quoteForm. Here you "merge" the settings of the two active forms:

//Add car button
        $("#addCar").on('click', function(){
            $.get('<?php echo Yii::app()->createAbsoluteUrl('quote/addCar'); ?>' + '?index=' + (carCount+1), function(data) {
                var settings = $("#quoteForm").data('settings');
                $("#quoteForm").data('settings', null);
                $("#carlist").append(data);
                var settings_new = $("#quoteForm").data('settings');
                carCount++;

                $.each(settings_new.attributes, function(k, v) {
                    settings.attributes.push(v);
                });
               //set the new settings
               $("#quoteForm").data('settings', settings);
        });

I actually use ActiveForm class which extends from CActiveForm and has this method which adds JS to the client script without running the widget(extracted form CActiveForm->run()):

public function registerJs()
{
    $options=$this->clientOptions;
    if(isset($this->clientOptions['validationUrl']) && is_array($this->clientOptions['validationUrl']))
        $options['validationUrl']=CHtml::normalizeUrl($this->clientOptions['validationUrl']);

    $options['attributes']=array_values($this->attributes);

    if($this->summaryID!==null)
        $options['summaryID']=$this->summaryID;

    if($this->focus!==null)
        $options['focus']=$this->focus;

    if(!empty(CHtml::$errorCss))
        $options['errorCss']=CHtml::$errorCss;

    $options=CJavaScript::encode($options);
    $cs=Yii::app()->clientScript;
    $cs->registerCoreScript('yiiactiveform');
    $id=$this->id;
    $cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");
}

And here is the controller part. You create a form but only render fields, not using it as a widget:

 $form = new ActiveForm();
 $form->enableAjaxValidation = false;
 $form->enableClientValidation = true;
 $form->id = 'quoteForm';


 $car = new \QuotesHistory();
 $this->renderPartial('car_row', compact('car', 'carMakes', 'index', 'form'), false, true);

Here is a small part of the partial view($index is actually the carCount that is passed in the get request), also this partial has a lot more fields and they all validate and submit correctly:

<div class="field-box">
            <?php
                echo $form->hiddenField($car, "[$index]id");
                echo $form->label($car, "[$index]automake_id", array('class'=>'form-label'));

                echo $form->dropDownRow($car, "[$index]automake_id", CHtml::listData($carMakes, 'id', 'name'), array(
                    'data-target' => CHtml::activeId($car, "[$index]automodel_id"),
                    'empty'=>'Select Make',
                ));

                echo $form->error($car, "[$index]automake_id", array(
                    'class'=>'alert-msg',
                    'style'=>'margin: 0;'
                ));
        ?>
    </div>

And on the last partial you need to add this in the end of the view so that the JS is registered.:

<?php
if(Yii::app()->request->isAjaxRequest)  //we dont need this in normal render  
    $form->registerJs();
?>

One final step: In order all this to works you should not double include any JS libs in the ajax response. You can do this in jQuery - http://www.eirikhoem.net/blog/2011/08/29/yii-framework-preventing-duplicate-jscss-includes-for-ajax-requests/

I've tested this code now and it works. If I remove elements I have no problem submitting the form.

这篇关于基于1对n关系的动态添加的表单字段 - 什么框架替代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆