За последние 24 часа нас посетили 23002 программиста и 1700 роботов. Сейчас ищут 1686 программистов ...

Ложное? значение data атрибута

Тема в разделе "JavaScript и AJAX", создана пользователем rewuxiin, 12 июл 2018.

  1. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    Возможно я уже глаз замылил - но косяк уже меня раздражает.
    В общем каждый раз, после внесения изменений - выбор количества пользователей, оплата сертификатом или, в данном случае, поиск купона который дает скидку в 20% или не дает скидку.

    У input установлен data-percent = "0" - ищем купон на сервере в ajax приходит ответ - установить data-percent="20" или нет, после этого вызываем функцию калькуляции которая собирает все данные по форме и пересчитывает.

    При первом открытии страницы - в поле купона ввожу номер от балды и получаю естественно data-percent = "0" - происходит калькуляция - все хорошо.
    Теперь ввожу верный номер купона - получаю data-percent = "20" - происходит калькуляция и все не хорошо потому, что откуда-то скрипт берет у data-percent - 0 и калькулирует.
    Точно такая же история наоборот - загрузил страницу - впервый раз ищу реальный купон - получаю data-percent = "20" и любой последующий за ним запрос - в DOM и стеке я вижу data-percent = "0" - но скрипт откуда-то уверенно берет 20

    Прикреплю чуть кода и скрин из консоли где видно, что у атрибута стоит value 0 но в результате amount я вижу 20

    это поиск купона
    Код (Javascript):
    1.    
    2.     this.applicationCouponSearch = function (form) {
    3.         var coupon = $(form).find('input[name="use_coupon"]');
    4.        
    5.         //Устанавливаем процент скидки в 0, пока не придет ответ из поиска
    6.         $(coupon).attr('data-percent',0);
    7.        
    8.         var url = ls.routerUrl('admin') + 'gr_coupon_search/' + $(coupon).val();
    9.        
    10.         var params = $(form).serializeArray();      
    11.        
    12.         ls.progressStart();
    13.         ls.ajax(url, params, function (response) {
    14.             ls.progressDone();
    15.             if (!response) {
    16.                 ls.msg.error(null, 'System error #1001');
    17.             } else {
    18.                 ls.msg.notice(response.sMsgTitle, response.sMsg);
    19.                
    20.                     $(coupon).attr('data-percent',response.percent);
    21.                    
    22.                     ls.applicationCalcPriceTotal(form);
    23.                
    24.             }
    25.         });
    26.        
    27.        
    28.     };
    Это калькуляция

    Код (Javascript):
    1. this.applicationCalcPriceTotal = function(form){
    2.        
    3.         if(!form){
    4.             var form = $('.modal-body form');
    5.         }
    6.  
    7.         var price = $(form).find('select[name="time"] option:selected').data('price');
    8.         var team = $(form).find('select[name="team"]').val();
    9.         var payment_method_id = $(form).find('select[name="payment_method_id"] option:selected').val();
    10.         var discount = $(form).find('select[name="discount"] option:selected');
    11.  
    12.         var result = price;
    13.        
    14.         //От команды отнимаем 6 чел и остаток умножаем на 5, для получения суммы за лишних людей
    15.         if(team > 6){
    16.             var teamResult = (team-6) * 5;
    17.             result = result + teamResult;
    18.         }
    19.        
    20.            
    21.             //Дополнительные условия скидок
    22.             //если ид скидки равен ид купона - устанавливаем размер скидки исходя из data атрибута полученного из поиска по номеру купона
    23.             if(discount = id_coupon_discount){
    24.                 discount = $(form).find('input[name="use_coupon"]');
    25.             }
    26.            
    27.             var amount = $(discount).data('amount');//скидка в рублях
    28.             var percent = $(discount).data('percent');//скидка в процентах
    29.  
    30.             //отсюда калькуляция
    31.             if(amount){
    32.                 result = price - amount;
    33.             }else if(percent){
    34.                 result = price - ((price / 100) * percent);
    35.             }        
    36.      
    37.        
    38.          $(form).find('input[name="total_price"]').val(result)
    39.  
    40.     }
    cons.jpg
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    @rewuxiin, а ничего, что для установки значений вы используете метод .attr(), а для получения .data()?
    Код (Javascript):
    1. // Измените эту строку
    2. $(coupon).attr('data-percent',0);
    3. // на следующую
    4. $(coupon).data('percent',0);
    И в других местах, где похожая ситуация
     
    rewuxiin нравится это.
  3. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    хм. это настолько существенные вещи?
    т.е. если я создал атрибут через .attr то мне теперь только и работать с .attr?
     
  4. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @rewuxiin, нет, через attr() - нормально реагирует. Вот если-бы .prop() использовали - тогда да... .data() не читала бы это значение.
    Присмотритесь лучше к 23-й строке выложенного кода "калькуляции".
     
    rewuxiin нравится это.
  5. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    упс
     
  6. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    такс, я исправился - но по прежнему я вижу в стеке 20, а в $(discount).data('percent') - получаю 0 ;((

    Код (Javascript):
    1.     this.applicationCalcPriceTotal = function(form){
    2.        
    3.         if(!form){
    4.             var form = $('.modal-body form');
    5.         }
    6.  
    7.         var price = $(form).find('select[name="time"] option:selected').data('price');
    8.         var team = $(form).find('select[name="team"]').val();
    9.         var payment_method_id = $(form).find('select[name="payment_method_id"] option:selected').val();
    10.         var discount = $(form).find('select[name="discount"]').val();
    11.        
    12.         var result = price;
    13.  
    14.        
    15.         //От команды отнимаем 6 чел и остаток умножаем на 5, для получения суммы за лишних людей
    16.         if(team > 6){
    17.             var teamResult = (team-6) * 5;
    18.             result = result + teamResult;
    19.         }
    20.                  
    21.             //Дополнительные условия скидок
    22.             //если ид скидки равен ид купона - устанавливаем размер скидки исходя из data атрибута полученного
    23.             //из поиска по номеру купона
    24.             if(+discount === id_coupon_discount){
    25.                 discount = $(form).find('input[name="use_coupon"]');
    26.             }
    27.            
    28.             var amount = $(discount).data('amount');//скидка в рублях
    29.             var percent = $(discount).data('percent');//скидка в процентах
    30.  
    31.             //отсюда калькуляция
    32.             if(amount){
    33.                 result = price - amount;
    34.             }else if(percent){
    35.                 result = price - ((price / 100) * percent);
    36.             }        
    37.        
    38.        
    39.          $(form).find('input[name="total_price"]').val(result)
    40.  
    41.     }
    42.    
     
  7. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @rewuxiin, вероятно, нельзя выполнять калькуляцию до того, как отработает асинхронный ajax-запрос на процент по указанному купону.
     
  8. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    Sail, так я же функцию выполняю после ответа из ajax
     
  9. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Напишите в 21-й строке первого кода: console.log($(coupon).attr('data-percent'), response.percent);
    Что покажет консоль?
     
  10. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
     
  11. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    и там-же проверьте значение $(form).find('input[name="use_coupon"]').data('percent'); /или .attr('data-percent')/
     
  12. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    а вот тут прикол:

    console.log($(form).find('input[name="use_coupon"]').data('percent')); - выдает 0
    console.log($(form).find('input[name="use_coupon"]').attr('data-percent')); - выдает 20

    это что-то из области магии наследия proto?
    которое я уже благополучно подзабыл. нужно опять идти на Learn.javascript
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    странно.
    если там data выставлена, то должно выдавать правильное число.

    мм

    а как оно устанавливается? через data или через attr?
     
  14. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    Создаю его с помощью .attr, т.к. изначально этого атрибута не существует

    Код (Javascript):
    1. $(coupon).attr('data-percent',response.percent);
     
  15. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    отныне создавай через .data('percent', val)
     
    rewuxiin нравится это.
  16. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    так я так и делал, но дело в том, что это не работает.
    у меня в DOM у <input name="use_coupon"> атрибут не создавался, потому я стал использовать .attr

    ни вот так
    $(coupon).attr('data-percent',response.percent);
    ни так
    $('input[name="use_coupon"]').data('percent',response.percent);

    data-percent - не создается (
     
  17. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    не создавался - очень размытое понятие
    если сделать .data('ajaja', 42) и потом сразу .data('ajaja') то покажет 42?
     
  18. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    хм. да, есть результат. но изменения в DOM нет.
    и как я полагаю - при следующей калькуляции js не обнаружит этот data?
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    я думаю, ты просто не видишь это изменение, но оно работает и можно на него полагаться.
    а как ты проверяешь, что изменение есть или нет в дом?
     
  20. rewuxiin

    rewuxiin Активный пользователь

    С нами с:
    17 апр 2012
    Сообщения:
    611
    Симпатии:
    87
    да, я уже это проверил - работает.

    я предполагал, что в инструментах вкладка Elements должна содержать все обновленные данные. по крайней мере обычное Html содержимое созданное с помощью Js - там отображается
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ну на самом деле значение какого-то поля элемента из jquery и значение поля элемента из дом - это разные вещи. Jquery может его хранить где-то в другом месте, т.к. jquery может просто использовать элемент как ключ к обычному массиву в js, в котором уже содержатся значения, чтобы не тормозить при смене атрибутов.
    --- Добавлено ---
    т.е. юзай .data('string') чтобы прочесть и .data('string', value) чтобы установить и не парься
     
    rewuxiin нравится это.