Своя Кнопка И Действие

всем привет

нужно сделать кнопку "скрыть-показать", которая-бы аяксом это проделывала

речь идет о CButtonColumn в CGridView

сделал в контроллере экшн =


public function actionShowHide($id)

{

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

   $shhd = $model->show == 'yes' ? 'no' : 'yes';

   $this->loadModel($id)->updateByPk($id, array('show'=>$shhd));

   if(!isset($_GET['ajax']))

       $this->redirect(

            isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin')

   );            

}

в представлении, в виджете зафигачил кнопку =


'class'=>'CButtonColumn',

'buttons'=>array(

   'view'=>array(

      'visible'=>'false',

    ),

   'preview'=>array(

      'imageUrl'=>'http://мойсайт.ru/gridview/view.png',

      'url'=>'Yii::app()->createUrl(

          "documents/showhide", array("id"=>$data->id_doc))',

	),                        

),

'template'=>'{update}{delete}{preview}',

и по ходу дела возникла парочка вопросов:

  1. а как правильно указывать путь к стандартным иконкам и нестандартным иконкам?

  2. как-то надо сделать так, чтобы в зависимости от статуса записи и иконка менялась…

вобщем = хэлпи ми дьюдз плиз иф ю ноу энисинг

попытался для imageUrl использовать условие - сначала тернарный оператор, потом анонимную функцию…

не сработало…


'imageUrl' => $model->show == 'yes' ? Yii::app()->baseUrl."/images/show.png" : Yii::app()->baseUrl."/images/hide.png",


'imageUrl'=>function($row,$data) {

	return $data->show == 'yes' ? Yii::app()->baseUrl."/images/show.png" : Yii::app()->baseUrl."/images/hide.png";

},



что-то не то…

imgUrl у вас ведь строка. Я не совсем понимаю ваш полет мысли и что нужно сделать, возможно еще не проснулся.

Если хотите скрыть колонку в CGridview по нажатию на кнопку, то тут вам и аякс то не нужен.

Сделайте кнопки в виде обычных ссылок, так будет проще, либо же даже этого не надо.




'class'=>'CButtonColumn',

'buttons'=>array(

   'view'=>array(

      'visible'=>'false',

    ),

   'preview'=>array(

      'imageUrl'=>'http://мойсайт.ru/gridview/view.png',

      'url'=>'#',

      'htmlOptions'=>array('onclick'=>'show_hide(this)');//если тут есть htmlOptions  

),                        

),

'template'=>'{update}{delete}{preview}',


//js

function show_hide(e)

{

   //сделаем например класс show, в котором будет display:block, и другая картинка, и hide

   if ($(e).hasClass("show")){

      $(e).removeClass("show");

      $(e).addClass("hide");

   }

//либо же css менять background, и скрывать css("display":"block") и hide(), ну и то же самое для обратного

}//это для смены при клике



Собственно если вы хотите менять иконку в зависимости от статуса при выводе? или где то




$(document).ready(function{

$(".grid-view tr").each(function(){

   if ($(this).attr("show")="yes"){

      //показываем

   } else {

      //не показываем  

   }

});

});

//также добавляем это в afterAjaxUpdate, чтобы не ломалось при пагинации

//в gridview в шапке 

'rowHtmlOptionsExpression' => 'array("show"=>$data->show)',



Если не угадал, напишите что еще нужно :unsure:

to ineersa = ага вы угадали = хочется менять иконку в зависимости от статуса

и грешным делом думал = раз строка, то должно отработаться условие, но был глубоко не прав…

спасибо за наводку по использованию js =


'htmlOptions'=>array('onclick'=>'show_hide(this)');

очень не хотелось, но видать придется

p.s. у меня еще такой вопрос: можно ли внутри виджета CGridView получить доступ к $model->show?

Снова таки непонятно, что у вас есть $model?

Если это внешняя переменная то:




function($data,$row) use ($model){

echo $model->show;//вот так в анонимной функции

}



Если же вы имеете ввиду то что передаете в Grid - то $data->show.

мммм…

я был уверен, что CGridView для построения своей таблицы использует модель ActiveRecord

а раз так, то было бы неплохо получить из модели значение поля show и в зависимости от него вывести ту или иную иконку в батонах

НО

использование $data->show приводит к ошибке Undefined variable: data

а function($data,$row) use ($model){…} к ошибке Object of class Closure could not be converted to string

p.s. да и вообще $model->show ничего не отображает

Так вы меня запутали окончательно) Да используется AR для GridView.

Имелось ввиду что если у вас в $data и есть show, то его так вытягиваем, если же вы модель передаете отдельно вне gridview то через use.

Куда вы ее пытаетесь впихнуть и что сделать, можно ли поподробнее зачем вам $model, $model->show и где оно используется.

ооооо! это я умею - как и любой новичок! :lol:

вот мой грид =


$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'documents-grid',

	'dataProvider'=>$model->search(),

	//'filter'=>$model, // comment this if you want hide search fields

	'columns'=>array(

            

                array(

                    'name' => 'id_doc',

                    'filter'=>false,

                    'htmlOptions' => array(

                        'width'=>'30',

                        'style' => 'text-align: center;',

                        ),

                ),            

            

		array(

                    'name' => 'name',

                    'filter'=>false,                    

                ),            

            

                array(

                    'name' => 'dt_show',

                    'filter'=>false,

                    'value' => 'Yii::app()->dateFormatter->format(\'dd.MM.yyyy\', $data->dt_show);',

                    'htmlOptions' => array(

                        'width'=>'75',

                        'style' => 'text-align: center;',

                        ),                     

                ),            

		

		array(

                    'name' => 'show',

                    'filter'=>false, 

                    'htmlOptions' => array(

                        'width'=>'40',

                        'style' => 'text-align: center;',

                        ),                    

                ), 

		

		array(

			'class'=>'CButtonColumn',

                        'buttons'=>array(

                            'view'=>array(

                                'visible'=>'false',

                                ),

                            'update'=>array(

                                'options'=>array('style'=>'margin-right: 4px;'),

                                ),                            

                            'showhide'=>array(

                                'label'=>'скрыть/показать',

                                'imageUrl'=>Yii::app()->baseUrl."/images/showhide.png",

                                'url'=>'Yii::app()->createUrl("documents/showhide", array("id"=>$data->id_doc))',

                                'options'=>array('style'=>'margin-right: 4px;'),

                            ),                        

                        ),

                        'template'=>'{showhide}{update}{delete}',

		),

	),

));

а вот так бы мне хотелось:


'imageUrl' => $model->show == 'yes' 

     ? Yii::app()->baseUrl."/images/show.png" 

     : Yii::app()->baseUrl."/images/hide.png",

чтобы использовать в if…else… для выбора нужной картинки в imgUrl

думаю пора остановиться на таком выделении записей у который значение поля show равно no =


'type'=>'html',

'value'=>'$data->show == "yes" 

     ? $data->show 

     : "<strong style=\'color: red;\'>$data->show</strong>"',

выделю их жирно и красным

В вашем случае проще переписать стандартные кнопки на ссылки, это дело 5 минут:




array(

   "header"=>"Actions",

   "type"=>"raw",

   "value"=>function ($data,$row){

      if ($data->show=="yes") $img_url="";

      else $img_url="";

      echo CHtml::link(CHtml::image($img_url,""),$this->createUrl());

      //вывод ваших остальных кнопок

   }

),



Условия отрабатывают если висит eval(). imgUrl - просто строка. Подробнее что обрабатывается можете глянуть в исходниках.

спасибо = выглядит заманчиво…

вот только не понятно - причем здесь кнопки, если вы оперируете в ключе value

Вместо кнопок у нас обычная колонка в виде ссылок с картинками, работает точно также, да и по сути является тем же только написанным вручную. Так проще оперировать всем (ну это лично мне), да и + иногда приходится делать не 3 кнопки(да и не кнопки вовсе). То что это панель действий не значит что она обязана быть CButtonColumn.

Иногда проще написать свое, дело в том что CButtonColumn не поддерживает того что вы хотите. Можете сделать свой класс, и переписать заполнение imgUrl. Можете сделать с помощью js, но придется следить за ajaxUpdate и это довольно накладно при большом количестве отображаемых записей. И 3 вариант - сделать так как я, возможно придется поправить css, но в общем все тоже самое.

суперррр!

а вот ваш код, который выше, его надо располагать где = в columns?

название столбца возьмется из ключа headers?

Это точно такая же колонка как и все :rolleyes:




'columns'=>array(

...............

array(

   "header"=>"Actions",

   "type"=>"raw",

   "value"=>function ($data,$row){

      if ($data->show=="yes") $img_url="";

      else $img_url="";

      echo CHtml::link(CHtml::image($img_url,""),$this->createUrl());

      //вывод ваших остальных кнопок

   }

),

)



header используем, так как нет у нас такого атрибута в модели, и name у нас не подтянется.

класс! завтра буду пробовать!

p.s. плюсиков понаставил ;D ;D

Парни день добрый! Раз пошла такая пьянка, подскажите плизз как можно вствить в каждую строку грида чекбокс, что бы можно было удалять строки пометив их галочкой, и нажмая кнопку внизу удалить выделленые, как в пхпмайадмине. Понемаю что это дело как то вставляеется вот сюда.




<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'news-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'id_news',

		'name',

		'introduction',

		'login',

		'id_user',

		'date_news',

        

        

		/*

		'number_news',

		*/

		array(

			'class'=>'CButtonColumn',

            

            

		),

	),

)); ?>



Как раз имею обалденный материал по этой теме, щас в ней разбираюсь. http://www.elisdn.ru/blog/37/custom-cgridview-columns-in-yii

Сделал вот так, типа того что ссылка на удаление одной строки, а при срабатывание пишет что то типа неверное действие.




<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'news-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'id_news',

		'name',

		'introduction',

		'login',

		'id_user',

		'date_news',

  		/*

		'number_news',

		*/

        array(

            'value' => 'CHtml::link(CHtml::encode("del"), Yii::app()->controller->createUrl("delete", array("id" => $data->id_news)))',

            'type' => 'html',

        ),

        

		array(

			'class'=>'CButtonColumn',

                  

		),


                

	),

)); ?>



Для этого существует selectableRows. Что нам нужно сделать:

  1. Добавим чекбоксы в наш грид:



'columns'=>array(

        array(

            'class' => 'CCheckBoxColumn',

            'selectableRows' => '2',

            'id'=>'autoId',

        ),



  1. Сделаем кнопку для передачи данных об удалении:



<?php echo CHtml::ajaxSubmitButton('Order', url, array(

        'type'=>'POST',

        'data'=>'js:{theIds : $.fn.yiiGridView.getChecked("grid_lists_id","autoId").toString()}',

        'success' =>

        'js:function (data) {

                   //тут делайте то что нужно после удаления, перезагрузка страницы, update грида и т.п.

           }',

    ), array(

        'id' => 'lists_submit_' . rand(1, 255),

    ));?>



  1. Собственно сделать action в контроллере который будет отвечать за удаление, путь к нему и есть url из кнопки.

Благодарю вас за помощью. Как раз немного ранее сделал вот так, еле еле методом тыка




 array(

    'header'=>'delete',

    'value'=>'CHtml::checkBox("id_news", $checked=false, array("value"=>"$data->id_news"))',

    //'class'=>'CButtonColumn',

    'type' => 'raw',

    ),



но потом увидел, что оказывается в АПИ есть класс ‘class’ => ‘CCheckBoxColumn’, и думаю надо переделать, и вы как раз дали готовое, да ещё и показали как получить айдишники постов с помощью JS-грида, за что вам благодарен.

В общем я хотел сделать банально без аякса, то есть форма и после перезагрузки удаление перебором массива в экшене. Но вы дали идею сделать аяксом, что мне тоже не могло не понравиться, хотя с сложнее в тех плане.

В общем пошел дорабатывать это дело, с начала чисто тествов, так как только намечал в планах в этом разобраться, но видать время пришло, в общем плизз, подскажите где ошибся.





// к стати русский язык кнопки почему то не поддерживают

<?php echo CHtml::ajaxSubmitButton("delete",CHtml::normalizeUrl(array('/news/manydelete')), 

        array(

        'type'=>'POST',

        'data'=>'js:{theIds : $.fn.yiiGridView.getChecked("grid_lists_id","autoId").toString()}', //


    ), 

    array(

        'id' => 'lists_submit_' . rand(1, 255),

    ));

   ?>





   	public function actionManyDelete() // тестовый вариант контроллера пока такой, потому как запрос почему то //вообще не выполняется.

	{

		

	  print_r($_POST['ajax']);

                             

	} 




Раньше Уишными приблудами аякса не пользовался это 1-й раз.

Можно подробнее что именно не работает?

Гадать на кофейной гуще мы умеем, но это дело не очень хорошее :rolleyes:

  1. Указали ли selectableRows именно 2.

  2. Все ли верно с классами?

  3. Выполняется ли аякс и что отсылается(можно посмотреть в firebug или developer tools хрома в вкладке network, там смотрим хэдеры которые отправляются аяксом и что нам возвращается).

  4. Делаем var_dump(print_r) всего $_POST, в данном случае у нас ид записей будут находится в $_POST[‘theIds’].

AjaxSubmitButton (давно дело было :) ) тут лишняя, можно просто ajaxButton или ajaxLink. В контроллере:




if (Yii::app()->request->isAjaxRequest&&$_POST['theIds']){

    $ids=explode(',', $_POST['theIds']);

    //вот и наш массив ид 

    .....

}



Если нужны ответы быстрее, или подробнее - можете обращаться в скайп, я не кусаюсь ::)

Логин такой же как и на форуме.