Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Выделение ошибочного ввода и сброс значения при проверке (https://javascript.ru/forum/dom-window/52725-vydelenie-oshibochnogo-vvoda-i-sbros-znacheniya-pri-proverke.html)

Veterinar 03.01.2015 17:43

Выделение ошибочного ввода и сброс значения при проверке
 
При редактировании вводе данных в форме нужно проверить введенное значение на сервере и, в соответствии с результатом проверки либо показать ошибку ввода, либо ничего не делать. Проверять до нажатия submit, например, при событии onchange или смене фокуса на поле [b]onblur[b].

Функция проверки отправляет аяксом значение переменной и получает ответ сервера в XML. Но, сволочь, сама JS функция возвращает всегда одно и то же значение...

Функция проверки:
function checkFieldName(nm){
check_field_name = false;
$.post(
"checkfieldName.php",
{
	name: nm,
	dataType: 'xml'
},
function(responseXML, check_field_name){
	$(responseXML).find("result").each(function() {
	check_field_name = $(this).find('status').text()==1)?true:false; // ВОТ ЭТА ГАДЮКА НИХРЕНА НЕ ПРИСВАИВАЕТ
});
})
	return check_field_name;
}


Подскажите, ради Деда Мороза, где я накосячил?

DjDiablo 03.01.2015 18:58

return checkFieldName сработает раньше чем отработает асинхронный кэлбек в post

то есть
1) устанавливается check_field_name=false
2) отправляется запрос на сервер, но результат ещё не приходит и function(responseXML, check_field_name) не отрабатывает
3) срабатывает return check_field_name который всегда вернёт false, так как только false ты и установил в 02 строке
4) твоя программа отработает с результатом false полученный от функции checkFieldName
5) наконец то придёт ответ от сервера, и function(responseXML, check_field_name) установит настоящий результат, правда случится это когда уже всё закончилось и результат уже нахрен не нужен

Кстатии если ты в each перебераещь несколько result (хотя на мой взгляд это как то странно) то результат true будет только в случае если самый последний result будет содержать 1, в противном случае всегда false. у

ещё один косяк в том что check_field_name в строке 9 у тебя локальная переменная так как ты её объявил в заголовке функции. И даже если бы запрос был синхронным то результат бы всё равно не мог выйти за пределы функции так как помещается в локальную переменную функции. Иными словами результат работы checkFieldName по прежнему всегда был бы false

и ещё один косяк в том что check_field_name во 2й строке у тебя глобальная переменная, глобальные переменные зло

Более менее правильый вариант выглядит как то так.

function checkFieldName(nm,callback){
   $.post("checkfieldName.php",{
         name: nm,
         dataType: 'xml'
      },
      function(responseXML){
         var check_field_name = false;
         $(responseXML).find("result").each(function() {
    	      check_field_name = $(this).find('status').text()==1)?true:false; 
         });
         callback(check_field_name)
      }
   );
}

checkFieldName(абгдзюзю,function(result){
     alert('результат проверки '+result)
})


P.S. То что checkfieldName.php у тебя на сервере отдельным файлом это тоже очень плохой стиль :(

Veterinar 03.01.2015 19:50

DjDiablo, спасибо, но...
FireBug: "TypeError: callback is not a function
callback(check_field_name)
"

DjDiablo 03.01.2015 20:04

Ну это ты постарайся отвтить почему callback у тебя не функция
Быть может ты в checkFieldName вторым параметром функцию не передаешь.

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

function checkFieldName(nm,callback){
  setTimeout(function(){
       var result=(Math.random()>0.5);
      callback( result )
  },10)
}
checkFieldName(12,function(result){
     alert('результат проверки '+result)
})


Часовой пояс GMT +3, время: 05:11.