2013-04-01 190 views
0

我在創建應用程序時出現問題。我已經擁有的是每個選項卡中都有一個表單的CJuiTabs系統。選項卡的數量和值/名稱由數據庫中另一個表中的許多tinyInt列定義。該選項卡的值與表單一起作爲隱藏字段提交。Yii中的動態表單

所以,現在如果你轉到一個帶有ID的視圖,你已經提交了一個記錄,你將能夠更新該記錄,但是你不能用其他tab值創建新記錄。 這是我的問題。如何讓應用程序根據您選擇的選項卡創建新記錄或更新現有記錄?如果你正在更新記錄,我希望顯示記錄的值,但是如果你正在創建一個新記錄,你應該只能看到空白字段(當然,它是一個評分系統,所以我猜它是星星不是字段)。

我想它應該通過使用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

我不知道我完全得到這個,讓我試着看看我是否得到這個問題,

你有多種形式,一個用戶可以編輯,他們都是在不同的遊戲平臺上排列一個遊戲的形式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)的Plateforms。然後,你可以做線沿線的東西:

$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」 =>陣列(),但不要使之成爲習慣。)

但是你不看起來你已經走了這條路線,所以如果你想要的話,請檢查一下,如果不是這樣,更改createRanking()以返回一個給定遊戲的平臺對應的排名數組,使用key => value是平臺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 [「排名」]),那麼你可以使用平臺_id從數組的正確型號隔離在爲了將其保存到分貝(或創建一個新的,如果它不存在)

希望幫助,或至少讓你在正確的軌道上。

編輯:添加了一些代碼,不是最好的/乾淨的解決方案,但它應該工作,並很容易理解:

控制器/ 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', 
)); ?> 
+0

謝謝你的回答,它真的幫了我很多。我想我會用最後一種方法,但我不知道如何返回createRanking()的排名數組。 – Deram

+0

所以這將是一個很大的幫助,如果有人能給我一個快速的例子或提示:) – Deram

+0

@德拉姆編輯我的答案與額外的代碼:) –