Ronald Wiplinger
Ronald Wiplinger

Reputation: 2203

Need an input numbers replacement

I got a php program displaying product items. The user should increase / decrease the amount to order. I tried input type='number'. That works on the desktop with a mouse fine. However, on a mobile device the arrows for plus and minus do not show up (mouse over) and a click will open the keyboard, which covers most of the screen.

I am looking now for a way to display this way:

Quantity: [+] 2 [-]

I tried the js code:

<script>
var i = 0;
function buttonClickAdd() {
    i++;
    document.getElementById('inc').value = i;
}
function buttonClickSub() {
    i--;
    document.getElementById('inc').value = i;
}

and the php part (within a foreach loop):

<button onclick="buttonClickAdd();">[plus]</button>
<input type="text" id="inc" value="0"></input>
<script>i</script>
<button onclick="buttonClickSub();">[minus]</button>

This code would trigger a submit to the order.php page, but I want to increase all values before I go there. I tried to use type="hidden" and with to display the variable. Did not work either.

How can I solve it?

Upvotes: 0

Views: 76

Answers (1)

user4639281
user4639281

Reputation:

To stop a button click from submitting a form, return false (or call .preventDefault() on the event) from the listener function.

In general inline JavaScript (html attributes for JavaScript) in production code should be avoided like the plague for maintainability reasons (as well as others).

You will want to avoid attaching an event listener to every single button so, because events bubble, we are going to listen for click events on a common parent. To do this we need to wrap the buttons and input inside a span tag.

<form>
  <span class="counter">
    <button class="counter-up">+</button>
    <input type="text" class="counter-num" value="0" readonly>
    <button class="counter-dn">-</button>
  </span>
</form>

Above you can see I added a bunch of classes. The parent needs a class so we can easily select them to listen for events; each button needs a class so we know what operation to perform; the input needs a class so we can select it and perform operations in its value.

Select all the counter parents; loop through the counters creating an IIFE and pass the counter and its corresponding text input as arguments; listen for click events on the parent; cache the classes of the clicked element; increment or reduce the value of the text input based on the class; return false;

var counters = document.querySelectorAll('.counter');
//                                   vv IIFE
for(var i in Object.keys(counters)) (function(counter, num){
  counter.onclick = function(e) {
    var cn = e.target.className;
    if(/counter-up/.test(cn)) return ++num.value, false;
    if(/counter-dn/.test(cn)) return --num.value, false;
    //                                          ^ comma operator
  }; 
})(counters[i], counters[i].querySelector('.counter-num'));

The comma operator is useful here to save space. The comma operator will evaluate each expression, then return the last. In the code above it is saying either increment or decrease the value of the input then return false. See the demo below for all of this in action.

var counters = document.querySelectorAll('.counter');
for(var i in Object.keys(counters)) (function(counter, num){
  counter.onclick = function(e) {
    var cn = e.target.className;
    if(/counter-up/.test(cn)) return ++num.value, false;
    if(/counter-dn/.test(cn)) return --num.value, false;
  };   
})(counters[i], counters[i].querySelector('.counter-num'));
.counter { display: block; } .counter * { border: 1px solid #bbb; border-radius: 2px; margin: 1px}
<form>
  <span class="counter"><button class="counter-up">+</button><input type="text" class="counter-num" value="0" readonly><button class="counter-dn">-</button></span>
  <span class="counter"><button class="counter-up">+</button><input type="text" class="counter-num" value="0" readonly><button class="counter-dn">-</button></span>
  <span class="counter"><button class="counter-up">+</button><input type="text" class="counter-num" value="0" readonly><button class="counter-dn">-</button></span>
  <span class="counter"><button class="counter-up">+</button><input type="text" class="counter-num" value="0" readonly><button class="counter-dn">-</button></span>
  <span class="counter"><button class="counter-up">+</button><input type="text" class="counter-num" value="0" readonly><button class="counter-dn">-</button></span>
</form>

Further reading

Upvotes: 1

Related Questions