[Resolvido] Atualizar Registros Apenas Via Gridview - Actionupdate Com Yii::app()->Request->Ispostrequest

Boa noite,

Estou com o seguinte problema, preciso/quero atualizar os registros apenas via Yii::app()->request->isPostRequest na actionUpdate da gridView, assim como é feito com o delete na actionDelete.

Este recurso é para evitar a edição via url, caso o usuário tente acessar o registro ele é redirecionado para a page 404.

Tentei por na grid assim:

admin.php - CGridView




...

'update'=>array(

    'label'=>'update',

    'url'=>'Yii::app()->createUrl("registro/update", array("id"=>$data->id))',

    'options'=>array(  // this is the 'html' array but we specify the 'ajax' element

        'ajax'=>array(

            'type'=>'POST',

            'url'=>"js:$(this).attr('href')", // ajax post will use 'url' specified above

        ),

    ),

),

...



RegistroController




public function actionUpdate($id)

{

    // Uncomment the following line if AJAX validation is needed

    // $this->performAjaxValidation($model);

    

    if(Yii::app()->request->isPostRequest)

    {

        $model=$this->loadModel($id);

        if(isset($_POST['Registro']))

        {

            $model->attributes=$_POST['Registro'];

            

            if($model->save()){

                Yii::app()->user->setFlash('success',"Operação realizada com sucesso!" );

                $this->refresh();

            }

        }

        

        $this->render('update',array(

            'model'=>$model,

        ));

    }else

        throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

}



mais sem sucesso. Ele redireciona direto para a page 404.

Como posso resulver este problema?

Tnx.

Laverson,

Já tento adicionar o ID no ajax?




'ajax'=>array(

            'type'=>'POST',

            'url'=>"js:$(this).attr('href')", // ajax post will use 'url' specified above

            'data'=>array("id"=>$data->id)

        ),




Eu não me aprofundei bem no $id que está nas novas atualizações do Yii, que está sendo usando no actionUpdate($id) e loadMode($id) e actionDelete($id), no geral ele busca o $_GET[‘id’], não fiz os testes com $_POST[‘id’].

Newerton,

tentei usar o


 

...

'data'=>array("id"=>$data->id)

...



, mais não funcionou.

Pelo que vi aqui ele não funciona sem ter o success, porém quando eu uso o success ele "quebra" a extensão EJuiComboBox (exibindo o dropDown e o inputText separados) que uso na pesquisa num form acima, mais mesmo assim ele não passa pelo if(Yii::app()->request->isPostRequest), da Page 404.

=\

Editado

Se ele utiliza o $_GET[‘id’] no delete, porque então eu não consigo deletar um registro via url, tendo que clicar no botão de remove do CGridView ?

Laverson,

Não sei como fazer no CGridView, mais era bom se cada botão tivesse um <form> envolvendo ele, ai isso resolveria o problema. Só que ae não sei se a class CButtonColumn aceita adicionar tags antes dos botão.

Ou senão você mesmo pode mesmo criar uma coluna e renderizar o <form> com o botão e um <input type="hidden"/> com o ID mocado.

Achei uns links interessantes pra você.

http://www.yiiframework.com/forum/index.php/topic/7453-unable-to-add-form-and-button-in-cgridview-column/

Vlw pelos links Newerton, porém no primeiro eu não consegui fazer o form ser renderizado na página, ou da erro ou nada aparece. :(

Já no segundo consigo chegar até o action no controller de boa, mais ele não carrega a página para atualizar.

Eis como está (utilizei o ajaxLink do segundo link para verificar se chega no action):

admin.php


<?php

    echo CHtml::ajaxLink('ClickMe',Yii::app()->createUrl('registro/update/4'),

    array(

        'type'=>'POST',

        'data'=>'js:{"id" : 4,"YII_CSRF_TOKEN" : "'.Yii::app()->request->csrfToken.'"}',

        // 'success'=>"$('#id-grid').yiiGridView.update('id-grid')"

    ));

?>

controller->actionUpdate




public function actionUpdate($id)

{

	$model=$this->loadModel($id);


	// Uncomment the following line if AJAX validation is needed

	// $this->performAjaxValidation($model);


	if(isset($_POST['id'])){

		if(isset($_POST['Registro']))

		{

			$model->attributes=$_POST['Registro'];

			if($model->save()){

                Yii::app()->user->setFlash('success',"Operação realizada com sucesso!" );

                $this->refresh();

				// $this->redirect(array('view','id'=>$model->id));

            }

		}

    }


	$this->render('update',array(

		'model'=>$model,

	));

}



Verifiquei com o firebug e ocorreu tudo bem, ele chegou na action.

Também dei um throw new CHttpException para verificar se realmente estava passando pelo if(isset($_POST[‘id’])) e ele passou de boa.

Agora fica a pergunta, como usar este ajaxLink dentro da grid e como renderizar a página de update?

Tnx.

Cara, posso estar falando besteira… mas acho que vc adicionando uma regra de acessso na sua controller, seu problema seria resolvido.

Bom, eu tô fazendo um sistema em ajax aqui e esses componentes de AJAX do Yii realmente são chatos de manipular.

Tenta usar link normal e no htmlOptions, adiciona um índice chamado ‘ajax’ passando para ele um array com as configurações do seu ajax.




CHtml::link('<seu_texto>', '#', array(

    'ajax' => array(

	'type' => 'POST',

	'url' => '<sua_url>',

	'cache' => false,

	// Outras Configurações

	'success' => 'function() {

	    // ...

	}',

    ),

));



É justamente uma regra que eu quero adicionar ao action do controller. Mais para tanto, eu preciso que o update não seja via GET, seja POST ou ajax por exemplo.

A idéia do Newerton se encaixa no que eu quero, se eu conseguir criar um form em uma column da pra fazer o que eu quero de boa.

Agora o que eu queria saber é, como é construída a chamada ao action delete que utiliza o if(Yii::app()->request->isPostRequest). Sabendo como que faz isso da pra fazer com o update e outros actions

O mesmo acontece quando uso o CHtml::link, ele atualiza a grid porém não renderiza a página de update… :huh:

Laverson,

Cria uma função no seu model, mais ou menos assim:




class Registro extends CActiveRecord {

    public $botaoForm;


    [...]


    public function getBotaoForm(){

        $html = CHtml::form($url, 'post');

        $html .= CHtml::hiddenField('id', $this->primaryKey);

        $html .= CHtml::htmlButton('Editar', array('type' => 'submit'));

        $html .= CHtml::endForm();

        return $html;

    }

}

Agora na sua CGridView, você cria a seguinte coluna:


array(

	'name' => 'botaoForm',

	'value' => '$data->getBotaoForm()',

	'type' => 'raw',                    

),

Testei aqui e funciono! ;)

\ỗ/ aeeeww \o/

Funcionou de boa Newerton, muito obrigado pela ajuda cara.

To me acabando de rir aqui (rindo pra não chorar :D ), se liga… se eu fizer isso com este botão eu vou ter que fazer com todos os outros botões desta e de todas as outras grids pro sistema fazer o que eu quero hehehhe me lasquei. :lol:

Fiz assim pra usar imagem no lugar do simples botão:

model




public function getBotaoForm(){

    $src = Yii::app()->request->baseUrl.'/images/icons/icon-pencil.png';

    $url = Yii::app()->createUrl("registro/update/");

    

    $html = CHtml::form($url, 'post');

    $html .= CHtml::hiddenField('id', $this->primaryKey);

    // $html .= CHtml::htmlButton('Editar', array('type' => 'submit'));

    $html .= '<input type="image" src="'.$src.'" alt="Submit">';

    $html .= CHtml::endForm();

    return $html;

}



controller




[...]

public function actionUpdate()

{

    if(isset($_POST['id'])){

        $model=$this->loadModel($_POST['id']);

        [...]

    }

    [...]

}

[...]



grid




[...]

array(

    'name' => 'botaoForm',

    'value' => '$data->getBotaoForm()',

    'type' => 'raw',                    

),

[...]



Att.

Ai sim hehe

Bom se é isso a sua finalidade, vai precisar fazer em todos os model, mais se não me engano tem como você fazer um Helper, e criar 1x essa função e usar somente nas CGridView.

Ai seria usado mais ou menos assim:


'value' => 'Helper::botaoForm($url, $id)',


'value' => 'Helper::botaoForm("registro/update", $data->primaryKey)',

É só uma suposição não testei, mais já vi em algum post no forum, mostrando como faz isso.

Assim você consegue enviar a URL(Para o <form>), e o ID (Para o <input>), assim não precisa ficar repetindo em todos os Model.

Pois é, tinha pensado em fazer isto mesmo.

Acho que ainda da pra simplificar mais passando apenas o get_class($data) como primeiro parâmetro ficando assim:


'value' => 'Helper::botaoForm(get_class($data), $data->primaryKey)',

dai é só fazer mais algumas modificações no método.

:D