Gravar na base de dados com uso de kartik\grid\GridView e kartik\grid\EditableColumn / AJAX

141 views
Skip to first unread message

Tiago Ferreira

unread,
Jun 7, 2015, 6:08:43 PM6/7/15
to yii-framew...@googlegroups.com
Sou novo na plataforma Yii2, e ainda estou as cabeçadas com o código...

Estou a tentar com esta framework criar uma pagina web onde possa controlar vários tipos de reparações, tarefas e agendas com a finalidade de a usar no meu negocio local.

Para essa finalidade ao procurar varias soluções para a base do website decidi usar:

Esta plataforma contem de base várias funcionalidades que preciso como Controlo de Utilizadores "RBAC", Multilíngua "I18N", etc...
Sendo assim e como vou precisar de fazer um formulário um pouco complexo para a inserção da fichas de reparação decidi testar desde já os módulos ideais para o efeito sendo eles kartik\grid\GridView e kartik\grid\EditableColumn.
Demo: http://demos.krajee.com/grid-demo

Usei esses módulos para refazer a view no backend referente a tradução multilíngua pois precisava de muitos cliques para editar as centenas de campos e seria muito menos burocrático gravar os mesmos usando ajax e com menos cliques claro.

Consegui alterar o visual para o adequado fazer os filtros da forma correcta mas estou com 
dificuldade em gravar as alterações na base de dados os posts ajax vindos da "editable colum"

Aqui vão os ficheiros usados.

model /backend/modules/i18n/models/i18nMessage.php:

<?php

namespace backend\modules\i18n\models;

use Yii;

/**
 * This is the model class for table "{{%i18n_message}}".
 *
 * @property integer $id
 * @property string $language
 * @property string $translation
 * @property string $sourceMessage
 * @property string $category
 *
 * @property I18nSourceMessage $sourceMessageModel
 */
class I18nMessage extends \yii\db\ActiveRecord
{
    public $category;
    public $sourceMessage;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%i18n_message}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'language'], 'required'],
            [['id'], 'exist', 'targetClass'=>I18nSourceMessage::className(), 'targetAttribute'=>'id'],
            [['translation'], 'string'],
            [['language'], 'string', 'max' => 16],
            [['language'], 'unique', 'targetAttribute' => ['id', 'language']]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('backend', 'ID'),
            'language' => Yii::t('backend', 'Language'),
            'translation' => Yii::t('backend', 'Translation'),
            'sourceMessage' => Yii::t('backend', 'Source Message'),
            'category' => Yii::t('backend', 'Category'),
        ];
    }

    public function afterFind()
    {
        $this->sourceMessage = $this->sourceMessageModel ? $this->sourceMessageModel->message : null;
        $this->category = $this->sourceMessageModel ? $this->sourceMessageModel->category : null;
        return parent::afterFind();
    }


    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSourceMessageModel()
    {
        return $this->hasOne(I18nSourceMessage::className(), ['id' => 'id']);
    }
}

View backend/modules/i18n/views/i18n-message/index.php 

<?php

use yii\helpers\Html;
use yii\grid\GridView;

// the grid columns setup (only two column entries are shown here
// you can add more column entries you need for your use case)
$gridColumns = [

  [
      'class'=>'kartik\grid\SerialColumn',
      'contentOptions'=>['class'=>'kartik-sheet-style'],
      'headerOptions'=>['class'=>'kartik-sheet-style'],
      'width'=>'5px',
      'header'=>'',
      'headerOptions'=>['class'=>'kartik-sheet-style']
  ],

    // the Language column configuration
    [
        'class' => 'kartik\grid\DataColumn',
        'contentOptions'=>['class'=>'kartik-sheet-style'],
        'headerOptions'=>['class'=>'kartik-sheet-style'],

        'attribute' => 'language',
        'filter'=> $languages,
        'pageSummary' => true,
    ],
    // the Categoty column configuration
    [
        'class' => 'kartik\grid\DataColumn',
        'contentOptions'=>['class'=>'kartik-sheet-style'],
        'headerOptions'=>['class'=>'kartik-sheet-style'],

        'attribute' => 'category',
        'filter'=> $categories,

    ],

        [
            'class' => 'kartik\grid\DataColumn',
            'contentOptions'=>['class'=>'kartik-sheet-style'],
            'headerOptions'=>['class'=>'kartik-sheet-style'],

            'attribute' => 'sourceMessage',
            'pageSummary' => true,
        ],
    [
        'class' => 'kartik\grid\EditableColumn',
        'contentOptions'=>['class'=>'kartik-sheet-style'],
        'headerOptions'=>['class'=>'kartik-sheet-style'],

        'attribute' => 'translation',
        'pageSummary' => true,
        'readonly'=>function($model, $key, $index, $widget) {
          //  return (!$model->status); // do not allow editing of inactive records
        },
        'editableOptions'=> function ($model, $key, $index, $widget) {
            return [
                'header' => 'translation',
                'size' => 'md'

            ];
        }
    ],

  ['class' => 'yii\grid\ActionColumn', 'template'=>'{update} {delete}'],
    [
        'class'=>'kartik\grid\CheckboxColumn',
        'headerOptions'=>['class'=>'kartik-sheet-style'],
    ],
 ];

// the GridView widget (you must use kartik\grid\GridView)
echo \kartik\grid\GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => $gridColumns,
    'containerOptions'=>['style'=>'overflow: auto'], // only set when $responsive = false
    'headerRowOptions'=>['class'=>'kartik-sheet-style'],
    'filterRowOptions'=>['class'=>'kartik-sheet-style'],
    'pjax'=>true, // pjax is set to always true for this demo
    'beforeHeader'=>[
        [
            'columns'=>[
                ['content'=>'Pagina de tradução de website', 'options'=>['colspan'=>7, 'class'=>'text-center warning']],
            ],
            'options'=>['class'=>'skip-export'] // remove this row from export
        ]
    ],
    // set your toolbar
    'toolbar'=> [
        ['content'=>
            Html::button('<i class="glyphicon glyphicon-plus"></i>', ['type'=>'button', 'title'=>Yii::t('kvgrid', 'Add Book'), 'class'=>'btn btn-success', 'onclick'=>'alert("This will launch the book creation form.\n\nDisabled for this demo!");']) . ' '.
            Html::a('<i class="glyphicon glyphicon-repeat"></i>', ['grid-demo'], ['data-pjax'=>0, 'class'=>'btn btn-default', 'title'=>Yii::t('kvgrid', 'Reset Grid')])
        ],
        '{export}',
        '{toggleData}',
    ],
    // set export properties
    'export'=>[
        'fontAwesome'=>true
    ],
    // parameters from the demo form
    'bordered'=>true,
    'striped'=>true,
    'condensed'=>true,
    'responsive'=>true,
    'hover'=>true,
    'showPageSummary'=>false,
    'persistResize'=>false,
    'exportConfig'=>true,
    ]);
?>


E finalmente o controler que tem como função gravar os dados mas não grava...

Controller backend/modules/i18n/controllers/I18nMessageController.php

<?php

namespace backend\modules\i18n\controllers;

use backend\modules\i18n\models\I18nSourceMessage;
use Yii;
use backend\modules\i18n\models\I18nMessage;
use backend\modules\i18n\models\search\I18nMessageSearch;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\helpers\Json;
/**
 * I18nMessageController implements the CRUD actions for I18nMessage model.
 */
class I18nMessageController extends Controller
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
        ];
    }

    /**
     * Lists all I18nMessage models.
     * @return mixed
     */
    public function actionIndex1()
    {
        $searchModel = new I18nMessageSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
        Url::remember(Yii::$app->request->getUrl(), 'i18n-messages-filter');

        $languages = ArrayHelper::map(
            I18nMessage::find()->select('language')->distinct()->all(),
            'language',
            'language'
        );
        $categories = ArrayHelper::map(
            I18nSourceMessage::find()->select('category')->distinct()->all(),
            'category',
            'category'
        );

        return $this->render('index1', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'languages' => $languages,
            'categories' => $categories
        ]);
    }





    public function actionIndex()
    {
        $searchModel = new I18nMessageSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
        Url::remember(Yii::$app->request->getUrl(), 'i18n-messages-filter');

        $languages = ArrayHelper::map(
            I18nMessage::find()->select('language')->distinct()->all(),
            'language',
            'language'
        );
        $categories = ArrayHelper::map(
            I18nSourceMessage::find()->select('category')->distinct()->all(),
            'category',
            'category'
        );




        if(Yii::$app->request->post('hasEditable'))
      {
           $model =new I18nMessage();
          $bookId = Yii::$app->request->post('editableKey');
          $model = I18nMessage::findOne($bookId);


          $post = [];
          $posted = current($_POST['translation']);
          $post['translation'] = $posted;

       // Load model like any single model validation
      if ($model->load($post))
      {
          // When doing $result = $model->save(); I get a return value of false
          if($model->save())
          {
          if (isset($posted['translation']))
          {
            $output =  $model->translation;
          }
          $out = Json::encode(['output'=>$output, 'message'=>'']);
          }
      }
      // Return AJAX JSON encoded response and exit
      echo $out;
      die;
      }



















        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'languages' => $languages,
            'categories' => $categories
        ]);

    }

    /**
     * Creates a new I18nMessage model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new I18nMessage();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['index']);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Updates an existing I18nMessage model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @param string $language
     * @return mixed
     */




    public function actionUpdate($id, $language)
    {
        $model = $this->findModel($id, $language);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(Url::previous('i18n-messages-filter') ?: ['index']);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Deletes an existing I18nMessage model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @param string $language
     * @return mixed
     */
    public function actionDelete($id, $language)
    {
        $this->findModel($id, $language)->delete();

        return $this->redirect(['index']);
    }

    /**
     * Finds the I18nMessage model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @param string $language
     * @return I18nMessage the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id, $language)
    {
        if (($model = I18nMessage::findOne(['id' => $id, 'language' => $language])) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}



Penso que o erro deve andar dentro do conteúdo assinalado a Azul Italico.

Agradeço a vossa cooperação.
Desde já muito Obrigado.
:)

Alisson Chrystian Campelo

unread,
Jun 7, 2015, 9:39:49 PM6/7/15
to yii-framew...@googlegroups.com
Eu não entendi muito o que VC quer fazer... Pois o Yii dá suporte a i18n, não precisaria deste pacote a parte...

BlackBox

unread,
Jun 8, 2015, 1:00:13 AM6/8/15
to yii-framew...@googlegroups.com
Quero alterar a view para que seja mais rápido fazer as traduções dos websites.
É por isso que uso os tais módulos.
Assim posso editar os campos na hora e gravar sem actualizar a pagina.

Envio em anexo uma imagem que exemplifica o caso.
Yii2-GridView.jpg
Reply all
Reply to author
Forward
0 new messages