Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PHP + AJAX Передача данных петодом POST 
:(
    Опции темы
nepster
Дата 20.4.2013, 03:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 26.4.2009

Репутация: нет
Всего: нет



Собственно вопрос такой, для работы с отправкой пост данных работаю с AJAX (jQUERY).

Код
    // НОВОСТИ
    function newsCpanel(csrfToken,action,obj_id)
    {
        if(action == 'addNews')
        {
            var data = 
            {
                "YII_CSRF_TOKEN":   encodeURIComponent(csrfToken),
                "action":           encodeURIComponent(action),
                "news_name":        encodeURIComponent(jQuery("input[name=news_name]").val()),
                "news_category":    encodeURIComponent(jQuery("select[name=news_category]").val()),
                "news_user_id":     encodeURIComponent(jQuery("input[name=news_user_id]").val()),
                "news_title":       encodeURIComponent(jQuery("input[name=news_title]").val()),
                "news_description": encodeURIComponent(jQuery("input[name=news_description]").val()),
                "news_keywords":    encodeURIComponent(jQuery("input[name=news_keywords]").val()),
                "news_status":      encodeURIComponent(jQuery("select[name=news_status]").val()),
                "news_short":       encodeURIComponent(CKEDITOR.instances.news_short.getData()),
                "news_full":        encodeURIComponent(CKEDITOR.instances.news_full.getData())
            };   
        }
        else if(action == 'editNews')
        {
            var data = 
            {
                "YII_CSRF_TOKEN":   encodeURIComponent(csrfToken),
                "action":           encodeURIComponent(action),
                "obj_id":           encodeURIComponent(obj_id),
                "news_name":        encodeURIComponent(jQuery("input[name=news_name]").val()),
                "news_category":    encodeURIComponent(jQuery("select[name=news_category]").val()),
                "news_user_id":     encodeURIComponent(jQuery("input[name=news_user_id]").val()),
                "news_date":        encodeURIComponent(jQuery("input[name=news_date]").val()),
                "news_title":       encodeURIComponent(jQuery("input[name=news_title]").val()),
                "news_description": encodeURIComponent(jQuery("input[name=news_description]").val()),
                "news_keywords":    encodeURIComponent(jQuery("input[name=news_keywords]").val()),
                "news_status":      encodeURIComponent(jQuery("select[name=news_status]").val()),
                "news_short":       encodeURIComponent(CKEDITOR.instances.news_short.getData()),
                "news_full":        encodeURIComponent(CKEDITOR.instances.news_full.getData())
            };      
        }
        else if(action == 'deleteNews')
        {
            var data = 
            {
                "YII_CSRF_TOKEN": encodeURIComponent(csrfToken),
                "action":    encodeURIComponent(action),
                "obj_id":   encodeURIComponent(obj_id)
            };      
        }
        else
        {
            return false;
        }
        
        
        // id для загрузки 
        var doom_id_load  = '.loader';
        // id для отображения ошибки
        var doom_id_error = '#loader';

        var request = jQuery.ajax({
            url: "/cpanel/news/control/",
            type: "POST",
            data: data,
            dataType: "JSON",
            
            // ЗАГРУЗКА
            beforeSend: function() { AJAXloadB(doom_id_load, true) },
            
            // ОБРАБОТКА AJAX ОШИБОК
            error:  function(xhr, str){ AJAXerror(xhr, str, doom_id_error);  AJAXloadB(doom_id_load, false) },
            
            // ЗАПРОС ПРОШЕЛ
            success: function(data)
            {
                AJAXloadB(doom_id_load, false)
                
                if(data.status == 1)
                {
                    // AJAX ОБНОВЛЕНИЕ КОНТЕНТА (если сервер возвращает content=reload)
                    // перезагрузим контент средствами AJAX
                    if(data.content == 'reload') ajaxContent(csrfToken,'news',action,doom_id_load);
                    /*****************************************************************/  
                }
                else
                {
                    switch(data.error)
                    {
                        case 'news_title>200':
                            jQuery(doom_id_error).html('ОШИБКА: поле "Заголовок" не может быть больше 200 символов').css({'color':'red'});
                        break;
                        case 'news_keywords>200':
                            jQuery(doom_id_error).html('ОШИБКА: поле "Ключевые слова" не может быть больше 200 символов').css({'color':'red'});
                        break;
                        case 'news_description>200':
                            jQuery(doom_id_error).html('ОШИБКА: поле "Описание" не может быть больше 200 символов').css({'color':'red'});
                        break;
                        case 'news_name>200':
                            jQuery(doom_id_error).html('ОШИБКА: поле "Название новости" не может быть больше 200 символов').css({'color':'red'});
                        break;
                        case 'category_id!is_numeric':
                            jQuery(doom_id_error).html('ОШИБКА: поле "Категория новости" должно быть числом').css({'color':'red'});
                        break;
                        case 'news_user_id!is_numeric':
                            jQuery(doom_id_error).html('ОШИБКА: поле "ID юзера" должно быть числом').css({'color':'red'});
                        break;
                        case 'news_status!is_numeric':
                            jQuery(doom_id_error).html('ОШИБКА: поле "Статус новости" должно быть числом').css({'color':'red'});
                        break;
                        case 'NOT_SAVED':
                            jQuery(doom_id_error).html('ОШИБКА: новость не сохранилась. Обратитесь к администратору!').css({'color':'red'});
                        break;
                        case 'THERE_IS_NO_NEWS':
                            jQuery(doom_id_error).html('ОШИБКА: новость не найдена. Обновите страницу').css({'color':'red'});
                        break;
                        case 'NEWS_ID_NAN':
                            jQuery(doom_id_error).html('ОШИБКА: Неверный формат ID новости').css({'color':'red'});
                        break;
                        default:
                            jQuery(doom_id_error).html('Возникла неизвестная ошибка').css({'color':'red'});
                    }
                }
            }
        });
    }


Все работает отлично. Только заметил одну не большую деталь. Если быстро нажимать (кучу раз тыкать по клавишам) на кнопку сохранить пока идет загрузка данных, данные будут дублироваться. 

Выглядит это так. Я нажима на сохранить, начинают грузится данные и не дожидаясь ответа от сервера я нажимаю еще кучу раз и в базу появляются дубликаты. Вместо 1 новости, я получаю 2 - 3 одинаковые. 

Подскажите пожалуйста как лучше всего бороться с такими ситуациям? 
Можно ли сделать так. что мы отправили запрос на сервер и пока сервер не ответит нельзя послать или игнорировать другой запрос от этой функции ? 
PM MAIL   Вверх
ksnk
Дата 20.4.2013, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Вариантов решения много.

На клиенте можно делать кнопке отправке "disabled" до получения данных или по таймауту. Это спасет от "дрожащих рук" нормального клиента. Рисовать окошко "форма отправляется, просим не суетится...". Красивенько, разумно, требует javascript.

На сервере, при генерации формы можно вставлять уникальное значение в скрытое поле. Каждый новый вывод формы клиенту вызовет генерацию нового значения. Это значение будет ключём для вставляемых записей. При получении данных проверяем, что эта форма ещё не пОстилась. Иначе - заменяем запись вместо вставки. Таким образом, одна форма, несколько раз подряд отправленная, вызовет только одно изменение. Если у клиента медленный (глючный, пропадающий) интернет и он успел перечитать свое сообщение исправить и послать его еще много  раз, то последнее исправление не пропадет ;)
Некоторый дискомфорт в этом решении вызывает добавление еще одного ключа в базу. Можно хранить эти ключики не в базе а в memcache или в отдельной таблице, которую подчищать со временем...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Sanchezzz
Дата 20.4.2013, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



Ужас...
encodeURIComponent не обязательно использовать для $.ajax
Switch error можно упросить если обрабатывать это циклом 
Код

$.each(m.error, function(key,item){});
  
И да решение вашей проблемы 
Код

.click(function(){
 var _this = $(this);
 if(!_this.hasClass('disable')){
   _this.addClass('disable');
   $.ajax({
     success:function(m){
      // Удачно  
        _this.removeClass('disable');
     },
     error:function(){
      _this.removeClass('disable');
     }
     //...
   });

 } 
});


По рекламирую полезную штуку для сбора данных с указанной области инпутов.  




--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
nepster
Дата 21.4.2013, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 26.4.2009

Репутация: нет
Всего: нет



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

Но буду еще более хитрожопие, воспользуюсь:

Код

serializeArray()





Код

    $(".AJAX_POST").submit( function(evt) {
    
        // останавливаем поведение браузера по умолчанию для submit
        evt.preventDefault();
        
        // объект формы 
        var FormObj = $(this);
        // загрузщик
        var LOADER_CLASS   = ".loader";
        // загрузщик
        var RESPONSE_CLASS = ".response";
        
        $.ajax({

            // action из формы
            url:  FormObj.attr('action'),
            
            // метод отправки данных из формы
            type: FormObj.attr('method'),
            
            // все данные формы
            data: FormObj.serializeArray(),
            
            // ответ от сервера 
            dataType: "JSON",
            
            //старт запроса
            beforeSend : function()
            {
                // заблокировать кнопку 
                FormObj.find("input[type=submit]").attr('disabled', 'disabled');
                // загрузка
                FormObj.find($(LOADER_CLASS)).show();  
            },
            
            // ОБРАБОТКА AJAX ОШИБОК
            error:  function(data,codeError)
            {
                if(codeError == 'parsererror')
                    FormObj.find(RESPONSE_CLASS).html('Возникла ошибка при получении данных с сервера! ('+codeError+')').css({'color':'red'});
                else 
                    FormObj.find(RESPONSE_CLASS).html('Сервер не отвечает! Код ошибки: '+data.status).css({'color':'red'});
            },
           
            // ЗАПРОС ПРОШЕЛ
            success:  function(data,codeError) 
            {
                if(codeError == 'success')
                {
                    var action = FormObj.serializeSearch('action');
                    switch(action)
                    {
                        // НОВОСТИ 
                        case 'addNews':
                        case 'editNews':
                        case 'deleteNews':
                            // AJAX ОБНОВЛЕНИЕ КОНТЕНТА (если сервер возвращает content=reload)
                            // перезагрузим контент средствами AJAX
                            if(data.content == 'reload') ajaxContent(FormObj.serializeSearch('csrfToken'),action,LOADER_CLASS);
                            /*****************************************************************/ 
                            newsCpanel(FormObj,data,RESPONSE_CLASS);
                        break;
                        .................
                    }          
                      
                }
                else
                {
                    FormObj.find(RESPONSE_CLASS).html('Возникла ошибка при получении данных с сервера! ('+(codeError)+')').css({'color':'red'});
                } 
            },
    
            //завершение запроса
            complete : function()
            {        
                // разблокировать кнопку 
                //FormObj.find("input[type=submit]").removeAttr('disabled');
                // выключить загрузку 
                FormObj.find($(LOADER_CLASS)).hide();
            }
        });  
            
    }); 



от свича в обработке ошибок не хотел бы отходить, очень удоьно и четебельно выглядит оформление всех ошибок 
PM MAIL   Вверх
Sanchezzz
Дата 21.4.2013, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



Если мне память не изменяет то Ckeditor в массив не входит его отдельно надо запихать надо.
Пробывал  я serializeArray 1 Мне не подошел так как не умет работать с указанного элемента только с формы, а это печально и прискорбно.  2 Возвращает массив  вида { name: 'имя поля' , value:'значение'} тоже не подходит для меня.

 


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
nepster
Дата 22.4.2013, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 26.4.2009

Репутация: нет
Всего: нет



хм, я еще не разбирал serializeArray() + Ckeditor, но стало интересно. 

При том же коде, вот результат

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  Новый_точечный_рисунок.jpg 70,12 Kb
PM MAIL   Вверх
Sanchezzz
Дата 22.4.2013, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



Скажу вам повезло, у меня получалось вот такой случай при отправке textarea пустое поле, возможно Ckeditor при submit формы  вставляет в textarea данные либо у меня была старая версия)


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
nepster
Дата 22.4.2013, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 26.4.2009

Репутация: нет
Всего: нет



ну да, интересно если просто обычным постом кидать, в любом случае он бросает содержимое textarea на сервер. 

Тоесть если бы в вашей старой версии была просто отправка данных методом пост, то данные бы не долетели ? 
Думаю просто где-то ошиблись. 

Вроде очень удобная вещь 
Код

serializeArray()


только вот достать данные не удобно. Даже вроде нет возможности как я понял, пришлось писать функцию:

Код

$.fn.serializeSearch = function(action)
{
    var r = false;
    var a = this.serializeArray();
    $.each(a, function() {
        
        if(action !== undefined && action == this.name)
        {
            r =  this.value;
        }
    });
    return r;
};




Код

serializeSearch('action'); // вернет value (name="action")

PM MAIL   Вверх
Sanchezzz
Дата 22.4.2013, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



Цитата

Тоесть если бы в вашей старой версии была просто отправка данных методом пост, то данные бы не долетели ? 
Как рас самое интересное что долетали, а вот просто обратится к textarea.val() я получал пустую строку=)
Я лучше останусь при своем костыле по причине 2) которую я писал пару постов выше.


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
nepster
Дата 22.4.2013, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 26.4.2009

Репутация: нет
Всего: нет



Код

а вот просто обратится к textarea.val() я получал пустую строку=)


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


всмсле, что нельзя данные добавлять? 
Код

<input type="hiden" name="test" value="Тестовые данные" />


и в целях навясчивости удобнее, тоесть если у пользователя отключен JS , что бы летели просто данные. Я так вставил к примеру csrfToken
PM MAIL   Вверх
Sanchezzz
Дата 22.4.2013, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



Таких людей очень маленькое количество. Если нужна совместимость то я реализую такой же метод как и у вас тут вы без условно вы правы.  smile 




--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
seregadgl
Дата 22.3.2017, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 2.10.2012

Репутация: нет
Всего: нет



Скажу вам повезло, у меня получалось вот такой случай при отправке qsn пустое поле, возможно Ckeditor при submit формы  вставляет в textarea данные либо у меня была старая версия) 
PM MAIL WWW   Вверх
_zorn_
Дата 23.3.2017, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: 6
Всего: 12



Цитата
Дата 23.4.2013

Цитата(seregadgl @  22.3.2017,  23:59 Найти цитируемый пост)
Скажу вам повезло

Только хотел написать и перешел по ссылке. Тфутымля, опять эти дизайнеры интерьеров. 
Ребята это же АНТИреклама. Я вот как увижу ваш сайт у кого нибудь, В ПЕРВУЮ ОЧЕРЕДЬ отговаривать буду. Чтобы вообще не связывались.
Хоть и делаете потолки вы возможно не плохо...

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1801 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.