0

THIS IS NOT A DUPLICATE BECAUSE I USE .data() and NOT .attr() LIKE ATTACHED SUGGESTS

I need to change a data attribute value when a variable is updated. I'm making a dropdown that ties to a discount field and I need to update both the text and the data attribute that is in the <option> tag.

The relevant pieces looks like this:

$(function() {
  $("#plan-options").change(function() {
    var moneyAmount = $(this).find('option:selected').data('amount');
    $("#selected-price").text("$" + moneyAmount);
    $("#purchase-warning").toggle();
    $(".default-encouragement").toggle();
  });
});

#plan-options is a <select> tag with <option>s that have data-attributes.

after that:

...
let selected = $("select option:selected");
let selectedAmount = selected.data("amount");
let selectedStr = selected.text();
let amountOffMoney = (data.amount_off / 100).toFixed(2);
if (data.percent_off != null) {
    selectedAmount = selectedAmount * (100 - data.percent_off) / 100
} else if (data.amount_off != null) {
    selectedAmount = selectedAmount - amountOffMoney;
    // this variable doesn't update - why?
    $("select option:selected").data("amount", selectedAmount);
} else {
    alert("Someting wrong happened!");
    return;
}

The most relevant piece is here:

selectedAmount = selectedAmount - amountOffMoney;
$("select option:selected").data("amount", selectedAmount);

My expectation is that I assign selectedAmount a new value, and changing the data attribute to selectedAmount should change to the new assignment but that is not happening. The value stays the same.

Is it because it's let? Is it a scoping issue?

FULL CODE SNIPPET:

$(function() {
  $("#plan-options").change(function() {
    var moneyAmount = $(this).find('option:selected').data('amount');
    $("#selected-price").text("$" + moneyAmount);
    $("#purchase-warning").toggle();
    $(".default-encouragement").toggle();
  });
});
...
jQuery(function ($) {
          $(document).on("click",'.apply_coupon', function (e) {
            e.preventDefault();
            let plan = $('select[name="plan"]').val();
            let coupon = $('input[name="coupon"]').val();
            $.get('/premium/coupon/', {
              coupon: coupon,
              plan: plan
            }, function (data) {
              console.log("got data from calling coupon api:", data)
              if (data.success) {
                //discounted amount display handling
                let selected = $("select option:selected");
                let selectedAmount = selected.data("amount");
                let selectedStr = selected.text();
                let amountOffMoney = (data.amount_off / 100).toFixed(2);
                if (data.percent_off != null) {
                  selectedAmount = selectedAmount * (100 - data.percent_off) / 100
                } else if (data.amount_off != null) {
                  selectedAmount = selectedAmount - amountOffMoney;
                  console.log(selectedAmount);
                  $("#plan-options option:selected").data("amount", selectedAmount);
                } else {
                  alert("Someting wrong happened!");
                  return;
                }

                let regex = /\d+\.*\d*/;
                let newStr = selectedStr.replace(regex, selectedAmount.toString());
                selected.text(newStr);

                $('.apply_coupon').text("Remove");
                $('.apply_coupon').addClass("remove_coupon").removeClass('apply_coupon');
                $('input[name="couponVerified"]').val(1);
                $('input[name="coupon"]').hide();
                $('.coupon-results').show();
                $('.coupon-results__code').text(data.name);
                $('.coupon-results__info').text("$" + amountOffMoney + " off " + data.duration);
                $("#selected-price").text("$" + selectedAmount);
              } else {
                alert(data.message);
              }
            })
          });

          $(document).on('click','.remove_coupon', function (e) {
            e.preventDefault();
            $.get('/premium/coupon/remove/', function (data) {
              if (data.success) {
                //discounted amount reverting handling
                let selected = $("select option:selected");
                let selectedAmount = selected.data("amount");
                let selectedStr = selected.text();
                let regex = /\d+\.*\d*/;
                let newStr = selectedStr.replace(regex, selectedAmount.toString());
                selected.text(newStr);
                $('.remove_coupon').text("apply");
                $('.remove_coupon').addClass("apply_coupon").removeClass('remove_coupon');
                $('input[name="couponVerified"]').val(0);
                $('input[name="coupon"]').show();
                $('.coupon-results').hide();
                $("#selected-price").text("$" + selectedAmount);
              }
            });
          });
        });
kawnah
  • 3,204
  • 8
  • 53
  • 103
  • How are you telling whether it has changed? – Barmar Apr 30 '19 at 16:01
  • This may be a duplicate of https://stackoverflow.com/questions/28335833/get-wrong-value-in-data-attribute-jquery/28335905#28335905 – Barmar Apr 30 '19 at 16:01
  • 3
    How do you know it is the same, have you log the value after the change, like this: `console.log($("select option:selected").data("amount");`. Note, in the [docs](https://api.jquery.com/data/) says: _Using the data() method to update data does not affect attributes in the DOM. To set a data-* attribute value, use attr._ – Shidersz Apr 30 '19 at 16:02
  • What is the value of data.percent_off when you reach the if? – Lajos Arpad Apr 30 '19 at 16:26
  • If you *really* need to change a **data attribute** then you need to use `$().attr("data-amount", newval);`. This is highly unlikely. More likely you just need to change the data value in the way you have - but this **does *not* change the DOM**, so don't then read it from the DOM/look in the browser - read it using `$().data("amount");` – freedomn-m Apr 30 '19 at 16:30
  • Possible duplicate of [get wrong value in data attribute jquery](https://stackoverflow.com/questions/28335833/get-wrong-value-in-data-attribute-jquery) – freedomn-m Apr 30 '19 at 16:30
  • No, not a duplicate because I use `.data()`...? – kawnah Apr 30 '19 at 16:51
  • @Shidersz the data attr just will not update. I did that and it throws the correct value but in the DOM inspector I can still see it's the same. So lost... – kawnah Apr 30 '19 at 16:59
  • @kawnah `JQuery` saves the updated values internally when using `data()`, the DOM attribute isn't changed, as the documentation says. – Shidersz Apr 30 '19 at 17:34

1 Answers1

0

It looks like you are specifying variables data.amount_off and data.percent_off that are undefined? I'm assuming these are also supposed to be data attributes on the <option> tag? The below snippet calls a test function on change of the select box value, to trigger your value calculations using the data attributes. Please let me know if you have any questions. Note that switching from the $15.00 option back to the default "Select" option and then back to the $15.00 option will update the data-amount value each time.

$(function() {
  $("#plan-options").change(function() {
    var moneyAmount = $(this).find('option:selected').data('amount');

    $("#selected-price").text("");
    $("#purchase-warning").toggle();
    $(".default-encouragement").toggle();

    // call code function below for testing
    if (moneyAmount > 0) {
      // Amount data attribute value on select
      console.log('current data-amount value: ' + moneyAmount);
      $("#selected-price").text("$" + moneyAmount);
      testDataAttr();
    }
  });
});

function testDataAttr() {
  let selected = $("#plan-options option:selected");
  let selectedAmount = selected.data("amount");
  let selectedAmountOff = selected.data("amount-off");
  let selectedPercentOff = selected.data("percent-off");
  let selectedStr = selected.text();
  let amountOffMoney = (selectedAmountOff / 100).toFixed(2);

  if (selectedPercentOff > 0) {

    selectedAmount = (selectedAmount * (100 - selectedPercentOff) / 100).toFixed(2);

  } else if (selectedAmountOff > 0) {

    selectedAmount = (selectedAmount - amountOffMoney).toFixed(2);
    $("#plan-options option:selected").data("amount", selectedAmount);

    // Log updated amount that was set on data-amount attr
    console.log('updated data-amount value: ' + selected.data("amount"));

  } else {
    alert("Someting wrong happened!");
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="plan-options">
  <option value="">-Select-</option>
  <option value="" data-amount="15.00" data-amount-off="5.00" data-percent-off="">15.00</option>
</select>
<div id="selected-price"></div>
Woodrow
  • 2,740
  • 1
  • 14
  • 18