0

I want to listen to two input change events, when one of the changes, check the checkbox and disable the element. Likewise, it needs to roll the checkbox back to the previous state when the value of input boxes back to the default values. The click function looks like 90% resemblance, how to DRY them?

var payment = 'old payment';        
var billAdr = 'old billAdr';

$('#payment').val(payment);
$('#bill-adr').val(billAdr);

$('#payment').on('input', function() {
  var newPayment = $('#payment').val();
  if(newPayment !== payment) {
    $("#save-nxt-time").attr('checked', true);
    $("#save-nxt-time").prop('disabled', true);
  } else {
    var newBillAdr = $('#bill-adr').val();
    if(newBillAdr === billAdr) {
      $("#save-nxt-time").prop('disabled', false);
      $("#save-nxt-time").attr('checked', false);
    }
  }
});

$('#bill-adr').on('input', function() {
  var newBillAdr = $('#bill-adr').val();
  if(newBillAdr !== billAdr) {
    $("#save-nxt-time").attr('checked', true);
    $("#save-nxt-time").prop('disabled', true);
  } else {
    var newPayment = $('#payment').val();
    if(newPayment === payment) {
      $("#save-nxt-time").prop('disabled', false);
      $("#save-nxt-time").attr('checked', false);
    }
  }
});
<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
  <form action="/#">
    <label for="payment">payment</label>
    <input type="text" id="payment" name="payment">
    <br>
    <label for="bill-adr">bill address</label>
    <input type="text" id="bill-adr" name="bill-adr">
    <br>
    <input type="checkbox" id="save-nxt-time">
    <label for="save">Save to next time</label><br><br>
    <input type="submit" value="Submit">
  </form>
</body>
</html>
Barmar
  • 741,623
  • 53
  • 500
  • 612
rj487
  • 4,476
  • 6
  • 47
  • 88
  • Is the goal to have the checkbox checked and disabled if either of the inputs change? – GitGitBoom Sep 10 '20 at 00:14
  • `for="other"` other? – Roko C. Buljan Sep 10 '20 at 00:17
  • Can you please explain this sentence? *"Likewise, it needs to roll the checkbox back to the previous state when the value of input boxes back to the default values"* ... when... what? – Roko C. Buljan Sep 10 '20 at 00:20
  • Why both inputs have the same `name="fname"`? – Roko C. Buljan Sep 10 '20 at 00:22
  • @RokoC.Buljan sorry about that, I didn't use these values so I forgot to check them. I updated the HTML part. "Likewise.." -> because previously I disable the checkbox if the value of one of them is different from the default value. So, if the value back to the default value, the checkbox should be undisabled. – rj487 Sep 10 '20 at 00:27

3 Answers3

1

const oldPa = 'old payment';
const oldBi = 'old billAdr';

const $next = $('[name="save-nxt-time"]');
const $paym = $('[name="payment"]').val(oldPa);
const $bill = $('[name="bill-adr"]').val(oldBi);
const $paBi = $paym.add($bill);

$paBi.on('input', () => {
  const bool = $paym.val() !== oldPa || $bill.val() !== oldBi;
  $next.prop({disabled: bool, checked: bool});
});
form label {display: block;}
<form action="/#">
  <label><span>Payment</span> <input type="text" name="payment"></label>
  <label><span>Billing address</span> <input type="text" name="bill-adr"></label>
  <label><input type="checkbox" name="save-nxt-time"> <span>Save to next time</span></label>
  <input type="submit" value="Submit">
</form>

<script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
0

Like this ?

// first load
checkTest(true);

$('#payment, #bill-adr').on('input', function() { 
   checkTest(false, $(this).attr('id'), $(this).val(), "#save-nxt-time");  
});
  
function checkTest(init = false, id, value, input) {
  var payment = 'old payment', billAdr = 'old billAdr';
 
  if (init === true) {
    $('#payment').val(payment);
    $('#bill-adr').val(billAdr);
  }

  console.clear();
  console.log(value);

  if (value === billAdr || value === payment) {
    $(input).prop('disabled', false).attr('checked', false);
  } else {
    $(input).attr('checked', true).prop('disabled', true);    
  }
}
<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
  <form action="/#">
    <label for="other">payment</label>
    <input type="text" id="payment" name="fname">
    <br>
    <label for="other">bill address</label>
    <input type="text" id="bill-adr" name="fname">
    <br>
    <input type="checkbox" id="save-nxt-time">
    <label for="save">Save to next time</label><br><br>
    <input type="submit" value="Submit">
  </form>
</body>
</html>
SKJ
  • 2,184
  • 1
  • 13
  • 25
0

how about putting the text and ids of the elements in an array and looping through run snippet below

$(document).ready(function() {
  const p = new PaymentMgr();
  p.init();
});

class PaymentMgr {
  constructor() {
    this.data = [{
      text: 'old payment',
      id: 'payment'
    }, {
      text: 'old bill address',
      id: 'bill-adr'
    }];
  }

  init() {
    this.data.forEach(element => $(`#${element.id}`)
      .val(element.text)
      .on("input", (e) => {
        ['checked', 'disabled'].forEach(attribute =>
          $("#save-nxt-time")
          .attr(attribute, $(e.target).val() !== element.text))
      })
    );
  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form action="/#">
  <label for="payment">payment</label>
  <input type="text" id="payment" name="payment">
  <br>
  <label for="bill-adr">bill address</label>
  <input type="text" id="bill-adr" name="bill-adr">
  <br>
  <input type="checkbox" id="save-nxt-time">
  <label for="save">Save to next time</label><br><br>
  <input type="submit" value="Submit">
</form>
Bryan Dellinger
  • 4,724
  • 7
  • 33
  • 79