Yii的动态形式

时间:2013-04-01 16:36:15

标签: ajax tabs yii

我在为我的应用程序创建内容时遇到问题。我已经拥有的是一个CJuiTabs系统,每个标签中都有一个表单。选项卡的数量和值/名称由我的数据库中另一个表中的一些tinyInt列定义。选项卡的值将作为隐藏字段提交。

现在,如果您转到带有已提交记录的ID的视图,您将能够更新该记录,但您无法使用其他选项卡值创建新记录。 这是我的问题。如何根据您选择的选项卡使应用程序决定创建新记录还是更新现有记录?如果你要更新一条记录,我希望显示记录的值,但是如果你要创建一个新记录,你应该只看到空白字段(好吧,它是一个评级系统,所以我猜它是星星而不是字段)。

我想这可以通过使用AJAX完成,但我不太清楚如何做到这一点。

游戏/视图:

<?php 
$tab_list=Platform::getPlatforms();
$tabarray=array();

// Create Dynamic Tabs
foreach($tab_list as $key=>$value){
    $tabarray["$value"]=array(
        'id'=>$key,
        'content'=>$this->renderPartial('../ranking/_form',
            array('model'=>$ranking, 'key'=>$key),TRUE)
    );
}?>

<?php
$this->widget('zii.widgets.jui.CJuiTabs',array(
    'tabs'=>$tabarray,
    'options'=>array(
        'collapsible'=>true,
    ),
    'id'=>'categorytabs',
)); ?>

型号/平台:

const PC = 1;
    const Mac = 2;
    const XBOX = 3;
    const XBOX360 = 4;
    const PS2 = 5;
    const PS3 = 6;
    const PSP = 7;
    const PSVITA = 8;
    const Wii = 9;
    const WiiU = 10;
    const NintendoDS = 11;
    const NintendoDS3 = 12;
...
    public function getPlatforms()
    {
        $id = Yii::app()->request->getQuery('id');
        $platform = Platform::model()->findByPk($id);
        $platforms = array();
        if ($platform -> pc == 1)
        {
            $platforms[self::PC] = "PC";
        }
        if ($platform -> xbox == 1)
        {
            $platforms[self::XBOX] = 'XBOX';
        }
        if ($platform -> xbox360 == 1)
        {
            $platforms[self::XBOX360] = "XBOX 360";
        }
        if ($platform -> ps2 == 1)
        {
            $platforms[self::PS2] = "PS2";
        }
        if ($platform -> ps3 == 1)
        {
            $platforms[self::PS3] = 'PS3';
        }
        if ($platform -> psp == 1)
        {
            $platforms[self::PSP] = "PSP";
        }
        if ($platform -> psVita == 1)
        {
            $platforms[self::PSVITA] = 'PS VITA';
        }
        if ($platform -> wii == 1)
        {
            $platforms[self::Wii] = "Wii";
        }
        if ($platform -> wiiU == 1)
        {
            $platforms[self::WiiU] = "Wii U";
        }
        if ($platform -> nintendoDS == 1)
        {
            $platforms[self::NintendoDS] = 'Nintendo DS';
        }
        if ($platform -> nintendoDS3 == 1)
        {
            $platforms[self::NintendoDS3] = 'Nintendo DS3';
        }       
        return $platforms;
    }

控制器/ GameController:

public function actionView($id)
    {
        ...
        $ranking=$this->createRanking($model);
        ...
        }

    protected function createRanking($model)
    {
        $user_id=Yii::app()->user->getId(); 
        $game_id=$model->id;
        $rank=ranking::model()->find("create_user_id=$user_id and game_id=$game_id"); 

        if($rank===null){
        $ranking=new Ranking;
        }
        else{
        $ranking=$rank;
        }

        if(isset($_POST['Ranking']))
        {
            $ranking->game_id=$model->id;
            $ranking->attributes=$_POST['Ranking'];

            $valid = $ranking->validate();
            if ($valid)
            {
                $ranking->save(false);
                $this->redirect(array('index'));
            }
        }
        return $ranking;
    }

排名/ _form:

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'ranking-form',
    'enableAjaxValidation'=>false,
)); ?>

    <p class="note">Fields with <span class="required">*</span> are required.</p>

    <?php echo $form->errorSummary($model); ?>

    <?php echo $form->hiddenField($model, 'platform_id', array('value' => $key)); ?>

    <div class="row">
        <?php echo $form->labelEx($model,'overall'); ?>
        <?php $this->widget('CStarRating',array(
            'model'=>$model,
            'attribute' => 'overall',
        )); ?>
        <?php echo $form->error($model,'overall'); ?>
    </div>
    <br/>

    <div class="row">
        <?php echo $form->labelEx($model,'graphics'); ?>
        <?php $this->widget('CStarRating',array(
            'model'=>$model,
            'attribute' => 'graphics',
        )); ?>
        <?php echo $form->error($model,'graphics'); ?>
    </div>
    <br/>

    <div class="row">
        <?php echo $form->labelEx($model,'sound'); ?>
        <?php $this->widget('CStarRating',array(
            'model'=>$model,
            'attribute' => 'sound',
        )); ?>
        <?php echo $form->error($model,'sound'); ?>
    </div>
    <br/>

    <div class="row">
        <?php echo $form->labelEx($model,'gameplay'); ?>
        <?php $this->widget('CStarRating',array(
            'model'=>$model,
            'attribute' => 'gameplay',
        )); ?>
        <?php echo $form->error($model,'gameplay'); ?>
    </div>
    <br/>

    <div class="row">
        <?php echo $form->labelEx($model,'lastingApp'); ?>
        <?php $this->widget('CStarRating',array(
            'model'=>$model,
            'attribute' => 'lastingApp',
        )); ?>
        <?php echo $form->error($model,'gameplay'); ?>
    </div>
    <br/>

    <div class="row buttons">
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
    </div>

<?php $this->endWidget(); ?>

1 个答案:

答案 0 :(得分:1)

我不确定我是否完全得到了这个,让我试着看看我是否遇到了问题,

你有一个用户可以编辑的多种形式,它们都是在不同的游戏平台(XBOX,PS2 / 3等)上排名一种游戏的形式。

如果是这种情况,请在您的游戏控制器中:

$rank=ranking::model()->find("create_user_id=$user_id and game_id=$game_id");
无论游戏平台如何,

将始终返回相同的数据库条目(前提是有条目) 你需要使用

的内容
$rank=ranking::model()->find("create_user_id=$user_id and game_id=$game_id and platform_id=$platform_id");

这涵盖了保存部分,但在显示中也存在问题。你有:

foreach($tab_list as $key=>$value){
    $tabarray["$value"]=array(
        'id'=>$key,
        'content'=>$this->renderPartial('../ranking/_form',
            array('model'=>$ranking, 'key'=>$key),TRUE)
    );

本质上,您为每个标签使用相同的$排名模型,因此相同(已存在)字段输入或星级评分。

这是一个有点棘手的地方。理想情况下,您可以使用Yii's relations将模型设置为具有多个游戏(MANY_MANY)的平台,这些游戏具有多个评级,具体取决于平台/游戏组合。然后你可以做一些事情:

    $platforms = Plateform::model()->findAll(array(
            'with'=>array(                                                  
                'rankings'=>array(
                       'condition'=>'game_id=$game_id AND platform_id=t.id')) //t refers to platform in Yii < 1.1.13. For Yii >= 1.1.13 check version update logs

));
    foreach($platforms as $platform){
        $tabarray[$platform->title]=array( //called it title arbitrarily, could be anything
            'id'=>$platform->id,
            'content'=>$this->renderPartial('../ranking/_form',
                array('model'=>$platform->rankings[0], 'key'=>$platform->id),TRUE)
        );

(我正在饶恕你们使用'params'=&gt; array(),但确实养成习惯。)

但是你似乎没有走过那条路,所以如果你想要检查它,如果不是如何更改createRanking()以返回与使用键的给定游戏的平台相对应的排名数组=&GT;键是平台ID的值。然后你可以这样做:

  foreach($tab_list as $key=>$value){
        $tabarray["$value"]=array(
            'id'=>$key,
            'content'=>$this->renderPartial('../ranking/_form',
                array('model'=>$rankings[$key], 'key'=>$key),TRUE)
        );

如果你继续这样做,就保存而言,如果是isset($ _ GET ['Ranking'])那么你将使用platform_id从数组中隔离正确的模型,以便将其保存到db(或创建)一个新的,如果它不存在)

希望有所帮助,或至少让你走上正轨。

编辑:添加了一些代码,而不是最好/最干净的解决方案,但它应该有效且易于理解:

控制器/ GameController:

 public function actionView($id)
{
    ...
    $this->createRanking($model);
    $rankings = $this->getRankingList();
    ...
}

//add this function
protected function getRankingList($gid,$uid)
    {
        $tab_list=Platform::getPlatforms();
        $rankings = array();
        foreach($tab_list as $key=>$value)
        {
            $rank=Ranking::model()->find("create_user_id=$user_id and game_id=$game_id and platform_id=$key"); 
            if(empty($rank))
                 $rank = new Ranking;
            $rankings[$key]= $rank;
        }
        return $rankings;
    }

游戏/视图:

<?php 
$tab_list=Platform::getPlatforms();
$tabarray=array();

// Create Dynamic Tabs
foreach($tab_list as $key=>$value){
    $tabarray["$value"]=array(
        'id'=>$key,
        'content'=>$this->renderPartial('../ranking/_form',
            array('model'=>$rankings[$key], 'key'=>$key),TRUE)
    );
}?>

<?php
$this->widget('zii.widgets.jui.CJuiTabs',array(
    'tabs'=>$tabarray,
    'options'=>array(
        'collapsible'=>true,
    ),
    'id'=>'categorytabs',
)); ?>