Обновление определенного div по ajax

Вопросы по вёрстке и JavaScript
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Обновление определенного div по ajax

Сообщение greatdane »

Как сделать обновление содержимого определенного div через ajax? Примерно как это сделано в пагинаторе.
Объясню чуть подробнее. Имеется фотогалерея, в которой у фоток есть поле num — порядок сортировки. В админке фотогалереи имеются стрелочки — «переместить фото левее», «переместить фото правее». Есть собственно экшены контроллера, которые перемещают фото на один шаг (меняют местами с предыдущим или со следующим). Сейчас у меня стоят на этих стрелочках обычные ссылки на эти экшены, и соответственно в экшене после выполнения перемещения фото делается редирект обратно на админку галереи. Как мне сделать, чтобы по нажатию на ссылку экшен перемещения выполнялся без перезагрузки страницы, а после его выполнения обновлялся div, содержащий фотки?
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение kosenka »

Присмотритесь к zii.widgets.jui.CJuiSortable. У меня через этот CJuiSortable реализована сортировка фоток в админке.
После того как "завершена сортировка", в сторону сервера отправляется ajax в котором указаны id файлов в том порядке в котором вы их выстроили. Вам останется только пробежаться по массиву id и проставить в базе "нужные цифры".
Вот пример:

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

<?
        $this->widget('zii.widgets.jui.CJuiSortable',
                 array(
                       'id'=>'ulThumbnailList',
                       'items'=>$items,
                       'itemTemplate'=>'<li id="{id}" class="ifl">{content}</li>',
                       //'htmlOptions'=>array('id'=>'ulThumbnailList'),
                       'options'=>array(
                                        'start'=>'js:$("li.ifl").disableSelection()',
                                        'stop'=>'js:function(){ jQuery("li.ifl").disableSelection(); var ifl= $("li.ifl"); var items = []; for(var x=0; x<ifl.length; x++){ items.push(ifl[x].id); } $.post("/catalog/ItemsPosition/", {"catalogid":"'.$catalogid.'","itemids":[items],"YII_CSRF_TOKEN":"'.Yii::app()->request->csrfToken.'"}); }'
                                       ),
                      )
                );
?>
В {id} передаю id файла-фотки
В {content} лежит

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

<div><img src=".."/></div> 
Последний раз редактировалось kosenka 2011.10.10, 15:32, всего редактировалось 1 раз.
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

Открою страшную тайну, пагинаторы и остальные zii плагины, это ужас )
Они ажаксом запрашивают ссылку, по которому экшн возвращает всю страницу целиком, потом плагин яваскриптом находит нужный кусочек и меняет. С этим нужно повнимательнее )
Жду Yii 3!
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

Не, таскание мышью мне пока не нужно. Мне нужно именно обновление без перезагрузки... у меня народ уже привык к этим стрелочкам. Таскание может попозже и сделаю.
Посмотрела виджет — непонятно, как там сохранять в базу после этого таскания?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

greatdane, а для чего вообще перегружать фотку? на яваскрипт лучше поменять картинки местами.
точнее отправить запрос на экшн /movephoto/1/to/next, вернуть JSON ответ (успех, ошибка), в $.getJSON, в onCompete, проверить ответ и поменять местами нужные картинки. Зачем загружать снова весь html ?
Жду Yii 3!
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение kosenka »

mc-bear писал(а):Открою страшную тайну, пагинаторы и остальные zii плагины, это ужас )
Они ажаксом запрашивают ссылку, по которому экшн возвращает всю страницу целиком, потом плагин яваскриптом находит нужный кусочек и меняет.
По первости у меня так и было. Потом руки "выпрямились" и все стало нормально :)
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

mc-bear писал(а):Открою страшную тайну, пагинаторы и остальные zii плагины, это ужас )
Они ажаксом запрашивают ссылку, по которому экшн возвращает всю страницу целиком, потом плагин яваскриптом находит нужный кусочек и меняет. С этим нужно повнимательнее )
хм, но работает почему-то все равно шустрее намного, чем при полной перезагрузке страницы. Все-таки повторно не рендерятся стили, картинки; да и layout тоже. А то, что вьюшку целиком рендерит по-новой — ну так в большинстве случаев ее и надо целиком перерендерить.
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение kosenka »

greatdane писал(а):Не, таскание мышью мне пока не нужно. Мне нужно именно обновление без перезагрузки... у меня народ уже привык к этим стрелочкам. Таскание может попозже и сделаю.
Лучше сразу сделать "таскание мышкой".
greatdane писал(а): Посмотрела виджет — непонятно, как там сохранять в базу после этого таскания?
Запись в базу придется сделать самому. Виджет только дает представление и обработку "таскания".
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

layout рендерится :), просто браузер не меняет все а только нужны блок, но по сети все равно идет весь html
Жду Yii 3!
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

mc-bear писал(а):greatdane, а для чего вообще перегружать фотку? на яваскрипт лучше поменять картинки местами.
точнее отправить запрос на экшн /movephoto/1/to/next, вернуть JSON ответ (успех, ошибка), в $.getJSON, в onCompete, проверить ответ и поменять местами нужные картинки. Зачем загружать снова весь html ?
Очень верно! Ну вот чайник я в вопросах ajax и json :-(
Поделитесь примерным кодом? Если нетрудно — с разжевывающими комментами...
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

kosenka писал(а): Лучше сразу сделать "таскание мышкой".
Люди 10 (!) лет жали на стрелки, сроднились уже с ними ;) Насчет таскания мы уже с ними вместе обдумаем-обсудим, надо ли им оно...
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение rak »

mc-bear писал(а):layout рендерится :), просто браузер не меняет все а только нужны блок, но по сети все равно идет весь html
в контроллере можно проверять, если аякс запрос - рендерить облегченный лайаут
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

поэтому я написал, нужно быть осторожнее с использованием этих плагинов.
Жду Yii 3!
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение kosenka »

rak писал(а):
mc-bear писал(а):layout рендерится :), просто браузер не меняет все а только нужны блок, но по сети все равно идет весь html
в контроллере можно проверять, если аякс запрос - рендерить облегченный лайаут
У себя сделал так:

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

class ItemsList extends CAction
{
        public function run()
        {
                $model=new Items('search');
        if(Yii::app()->getRequest()->getQuery('Items')) $model->attributes=Yii::app()->getRequest()->getQuery('Items');

                if(Yii::app()->getRequest()->getQuery('ajax'))//если в запросе есть "ajax" - рендерим облегченный html
                {
                        $this->controller->renderPartial('itemsListGrid',array('model'=>$model,'catId'=>null));
                }
                else
                {
                        $this->controller->render('itemsList',array('model'=>$model,'catId'=>null)); // рендерим "тяжелый" html
                }
    }
} 
itemsList:

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

<table width="100%" cellpadding="0" cellspacing="1">
        <tr>
                <td>
                <? $this->renderPartial('itemsListGrid',array('model'=>$model,'catId'=>$catId)); ?>
                </td>
        </tr>
</table>
itemsListGrid:

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

                <?
                $this->widget('zii.widgets.grid.CGridView', array());
                ?>
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

greatdane писал(а):Ну вот чайник я в вопросах ajax и json :-(
Поделитесь примерным кодом? Если нетрудно — с разжевывающими комментами...
примерно так

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

$('a.moveNext').click(function(){
    var lnk=$(this);
    var prn=lnk.parent(); // предпологается что родительский объект для ссылки,
                          // является div-конейнер для картинки и всего что к ней относится
    var nxt=prn.next();      // следующий контейнер

    $.getJSON('/images/move',{photoId:123,move:'next'},function(data) {
        if(data.answer!=undefined && data.answer=='success') {
            prn.detach().insertAfter(nxt);
        }
        else {
            alert('Ошибка!');
        }
    });
}); 

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

class ImagesController extends CController {
        function moveAction() {
            $photoId=$_POST['photoId'];
            $to=$_POST['move'];
            $photo=PhotoModel::model()->findByPk($photoId);

            if($photo!==null && $photo->move($to)) {
                return CJavascript::encode(array(
                    'answer'=>'success'
                ));
            }

            return CJavascript::encode(array(
                'answer'=>'error'
            ));
        }
} 
Жду Yii 3!
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

mc-bear, огромное спасибо, буду пробовать!
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

Это в случае если нужно только поменять местами, потому что если по ответу нужно рисовать новый элементы, то ходят слухи что лучше на сервере генерировать html, чем на клиенте. Тогда вот так

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

$('a').click(function(){$('#images').load('images/move/123/next');}); 
// где <div id="images"> - контейнер для всех картинок 
а в действии возвращать renderPartial('view')
Жду Yii 3!
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

Большое спасибо, это тоже возможно пригодится!
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение greatdane »

$.getJSON('/images/move',{photoId:123,move:'next'},function(data)

Тут 123 — это идентификатор фотки, которую надо двигать. Он же должен браться из ссылки? Плюс у меня еще одна переменная берется из самой модели в этом вью.

В общем у меня получилась вот такая штука, которая не работает :(

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

    $('a.moveNext').click(function(){
        var lnk=$(this);
        var ID = $(this).attr("id"); // это мы в ссылке прописываем ид фотки, а потом берем его оттуда
        var dog = <?php echo $model->dog_id; ?>;
        var prn=lnk.parent(); // предпологается что родительский объект для ссылки,
                              // является div-конейнер для картинки и всего что к ней относится
        var nxt=prn.next();      // следующий контейнер

        $.getJSON('/rus/admin/dogs/move/',{parId:ID,move:'next',dog:dog},function(data) {
            if(data.answer!=undefined && data.answer=='success') {
                prn.detach().insertAfter(nxt);
            }
            else {
                alert('Ошибка!');
            }
        });
        return false;
    });
</script>
И в контроллере:

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

public function actionMove() {
        $parId=intval($_POST['parId']);
        $to=$_POST['move'];
        $dog = intval($_POST['dog']);
        $par=DogPages::model()->findByPk($parId);
        if($par!=null && $to == "next") {
            $criteria = new CDbCriteria();
            $criteria->order = "rd_par_num ASC";
            $criteria->select = "rd_par_num,rd_par_id";
            $criteria->limit = 1;
            $criteria->condition = "rd_par_num>".$par->rd_par_num." and dog_id=".$dog;
            $next= DogPages::model()->find($criteria);
            $par->saveAttributes(array("rd_par_num"=>$next->rd_par_num));
            $next->saveAttributes(array("rd_par_num"=>$par->rd_par_num));
            return CJavascript::encode(array(
                'answer'=>'success'
            ));
        }

        return CJavascript::encode(array(
            'answer'=>'error'
        ));
    }
 
А FireBug говорит 404 ошибку на адрес, хотя адрес правильный... Что не так? Может быть дело в том, что модуль admin закрыт для неавторизованных?
И почему мы передаем переменные гетом, а ищем их потом в посте?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Обновление определенного div по ajax

Сообщение slavcodev »

то что модуль закрыт не важно, ведь ссылка тоже в админке значит доступ есть.
getJSON кажется передает по умолчанию постом, но могу и ошибаться.
а в файрбаге и в логах что показывает какую ссылку запрашивается ажаксом?
Жду Yii 3!
Ответить