CGridView ajax редактирование

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Аватара пользователя
ARACOOL
Сообщения: 68
Зарегистрирован: 2011.05.21, 15:19
Контактная информация:

CGridView ajax редактирование

Сообщение ARACOOL »

Я не смог найти в интернете решение проблемы. У меня есть таблица построенная с помощью CGridView. И там много записей.
Если возможность при клике на запись в строке делать из нее input и после редактирования убрав курсор с поля отправить ajax запрос с измененными данными.
Как можно так сделать?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: CGridView ajax редактирование

Сообщение samdark »

Где-то тут было расширение на тему: http://www.yiiframework.com/extensions/
Аватара пользователя
ARACOOL
Сообщения: 68
Зарегистрирован: 2011.05.21, 15:19
Контактная информация:

Re: CGridView ajax редактирование

Сообщение ARACOOL »

Хотя бы немного подскажите как и где искать. Там много очень расширений
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

Я сделал без расширений:
В view

Код: Выделить всё

$this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'modelGrid',
    'dataProvider' => $provider,
    'afterAjaxUpdate'=>'function(id, data) { setInlineEdit(); }',
    'columns' => array(
        array('name'=>'name', 'type'=>'raw', 'value'=>'Tools::inlineEdit($data, "name")'),
        array('name'=>'description', 'type'=>'raw', 'value'=>'Tools::inlineEdit($data, "description", "textarea")'),
        // и так далее
ниже в view

Код: Выделить всё

<?php $cs = Yii::app()->getClientScript();
$cs->registerScriptFile(Yii::app()->baseUrl.'/js/jquery.jeditable.mini.js');
?>
<?php $cs->registerScript('inline', "
function setInlineEdit() {
  $('.inlineEdit').each(function(){
    var params = {field: $(this).attr('field')};
    var type = $(this).attr('type');
    var s = '', c = '';
    if(type=='textarea' ) {
       s = 'OK';
       c = 'Cancel';
    }
    $(this).editable('/backend/item/field', {
        placeholder : '---',
        indicator : 'Сохраняем...',
        tooltip   : 'Кликните, чтобы редактировать',
        type     : type,
        rows: 3,
        cols: 30,
        submit   : s,
        cancel   : c,
        width: '100px',
        submitdata : params,
        callback  : function(value, settings) {
             $.fn.yiiGridView.update('modelGrid',{data:{ }});
          }
     });
  });
}

$(function(){
   setInlineEdit();
});

");
?>
jquery.jeditable.mini.js брать тут http://www.appelsiini.net/projects/jeditable

Класс Tools лежит в components

Код: Выделить всё

class Tools {
   static public function inlineEdit($data, $field, $type='text') {
        return '<div class="inlineEdit" id="' . $data['id'] . '" field="'.$field.'" type="'.$type.'">' . $data[$field] . '</div>';
    }
}
Action

Код: Выделить всё

    public function actionField() {
        if (isset($_POST['field'])) {
            $field = $_POST['field'];
            if (isset($_POST['id'])) {
                $model = CActiveRecord::model($this->modelName)->resetScope()->findByPk($_POST['id']);
                if ($model != null) {
                    $model->$field = $_POST['value'];
                    $model->save();
                    Yii::app()->end();
                }
            }
        }
    }
 
Вот как-то так
Аватара пользователя
nizsheanez
Сообщения: 814
Зарегистрирован: 2011.04.29, 13:09
Откуда: Москва

Re: CGridView ajax редактирование

Сообщение nizsheanez »

Тоже использую jeditable, но получается что для каждого атрибута нужно будет заводить свой экшн, как-то это накладно вы не находите? Как с этим справляетесь?
Аватара пользователя
ARACOOL
Сообщения: 68
Зарегистрирован: 2011.05.21, 15:19
Контактная информация:

Re: CGridView ajax редактирование

Сообщение ARACOOL »

Так мне нужно что бы вся строка с данными "превратилась" в inputs. А не по отдельности каждая ячейка в строке
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

nizsheanez писал(а):Тоже использую jeditable, но получается что для каждого атрибута нужно будет заводить свой экшн, как-то это накладно вы не находите? Как с этим справляетесь?
Экшн один, я же передаю имя атрибута, и использую

Код: Выделить всё

    $model->$field = $_POST['value'];
Аватара пользователя
nizsheanez
Сообщения: 814
Зарегистрирован: 2011.04.29, 13:09
Откуда: Москва

Re: CGridView ajax редактирование

Сообщение nizsheanez »

ARACOOL - можно сделать это с jeditable, просто нужно отключить сохранение по onblur и добавить сохранение по клику на какую-нибудь кнопку. В примерах jeditable есть сэйв по кнопке.
Вот только вопрос целесообразности: если никто не собирается одновременно редактировать 2 инпута, зачем нужны 2 инпута? Кликнул отредактировал. В чем смысл сразу всю строку превращать в инпут?
Еще обходной вариант: Можно в popup вывести форму редактирования.

navy - Вообще что смущает в таком подходе: я могу откуда угодно отредактировать любое поле любой записи для заданной модели - это как бы не есть гуд с точки зрения безопасности. А если еще и название модели передовать, так тогда можно вообще все что угодно изменить, хоть пароль админа.
Вот и вопрос: можно ли как-то заткнуть эту дырку и одновременно сделать возможность не плодить одинаковые экшены в каждом контроллере админском?
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

nizsheanez писал(а): navy - Вообще что смущает в таком подходе: я могу откуда угодно отредактировать любое поле любой записи для заданной модели - это как бы не есть гуд с точки зрения безопасности. А если еще и название модели передовать, так тогда можно вообще все что угодно изменить, хоть пароль админа.
Вот и вопрос: можно ли как-то заткнуть эту дырку и одновременно сделать возможность не плодить одинаковые экшены в каждом контроллере админском?
Для безопасности этот экшн разрешен только админам, а чтобы не плодить его в каждом классе, нужно сделать его в виде отдельного класса и подключать в нужных контроллерах.
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

nizsheanez писал(а):ARACOOL - можно сделать это с jeditable, просто нужно отключить сохранение по onblur и добавить сохранение по клику на какую-нибудь кнопку. В примерах jeditable есть сэйв по кнопке.
Вот только вопрос целесообразности: если никто не собирается одновременно редактировать 2 инпута, зачем нужны 2 инпута? Кликнул отредактировал. В чем смысл сразу всю строку превращать в инпут?
Еще обходной вариант: Можно в popup вывести форму редактирования.
Или не в popup выводить, а при клике на любое поле в гриде, вместо текущей строки подгружать форму для редактирования, как сделано, например, в chive. Но тоже небезпроблемно получается, так как с валидацией придется заморочится
Аватара пользователя
nizsheanez
Сообщения: 814
Зарегистрирован: 2011.04.29, 13:09
Откуда: Москва

Re: CGridView ajax редактирование

Сообщение nizsheanez »

navy писал(а): Для безопасности этот экшн разрешен только админам
Не только админам. Например есть редакторы у новостных порталов, которым разрешено редактировать свой раздел сайта.
navy писал(а): а чтобы не плодить его в каждом классе, нужно сделать его в виде отдельного класса и подключать в нужных контроллерах.
Это само сабой. Но, даже этот подключаемый экшн таскать с собой не хочется. Это тоже повторяемость кода, хоть и оправданная.
Есть еще идеи?
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

nizsheanez писал(а): Не только админам. Например есть редакторы у новостных порталов, которым разрешено редактировать свой раздел сайта.
Скажем так, любому необходимому подмножеству пользователей
nizsheanez писал(а): Это само сабой. Но, даже этот подключаемый экшн таскать с собой не хочется. Это тоже повторяемость кода, хоть и оправданная.
Есть еще идеи?
Какой-то код все равно нужно писать, можно создать его в контроллере от которого наследуются backend контроллеры, тогда и подключать не придется, но тут другая проблема, как отключить там где этот экшн не нужен.
Аватара пользователя
nizsheanez
Сообщения: 814
Зарегистрирован: 2011.04.29, 13:09
Откуда: Москва

Re: CGridView ajax редактирование

Сообщение nizsheanez »

Ладно, с этим ясно.
А как разрешить редактировать данной роли, один атрибут и запретить другой?
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

nizsheanez писал(а):Ладно, с этим ясно.
А как разрешить редактировать данной роли, один атрибут и запретить другой?
Например завести в контроллере массив атрибутов, которые можно редактировать и при попытке редактировать проверять на наличие атрибута в списке, это кстати и решит проблему с запрещением там где не нужно.
Аватара пользователя
nizsheanez
Сообщения: 814
Зарегистрирован: 2011.04.29, 13:09
Откуда: Москва

Re: CGridView ajax редактирование

Сообщение nizsheanez »

че-нить вида attribute=>role.... может быть.
navy
Сообщения: 21
Зарегистрирован: 2010.11.15, 12:59

Re: CGridView ajax редактирование

Сообщение navy »

nizsheanez писал(а):че-нить вида attribute=>role.... может быть.
atribut->array(role,...) так наверное
Аватара пользователя
nizsheanez
Сообщения: 814
Зарегистрирован: 2011.04.29, 13:09
Откуда: Москва

Re: CGridView ajax редактирование

Сообщение nizsheanez »

ага
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: CGridView ajax редактирование

Сообщение lancecoder »

я бы реализовал через сценарии, они очень хороши для обеспечения безопасности, безопасными атрибутами защищаете поля которые нельзя редактировать по сценарию jeditеtable, ну и проверку в экшене на то может ли данный юзер чтото делать в этом экшене
Maxym
Сообщения: 3
Зарегистрирован: 2013.01.05, 04:01

Re: CGridView ajax редактирование

Сообщение Maxym »

Использую jeditеtable, как в примере выше.Все работает отлично, но после $.fn.yiiGridView.update('modelGrid',{data:{ }}); , компонент перестает работать. Т.е. когда на него нажимаешь то ничего не происходит.подскажи в чем может быть проблема???
Ответить