Kaare
Kaare

Reputation: 531

elegant implementation of increment button with jQuery?

In my toy project to learn javascript and jQuery, I need to implement increment and decrement buttons for some input fields. I am thinking that the below design should work, but somehow it doesn't. Am I misunderstanding something about jQuery, or is it a banal error?

<button type="button"  id="WS1inc" class="incbut"> + </button>  
<input type="number" id="WS1" value="1">        


function increment(field)
{
    field.val(field.val()+1);
}

$("#WS1inc").click($("#WS1"),increment);

The console says that the object does not have method "val()", so I guess I can't pass jQuery objects like this?

JSFiddle: http://jsfiddle.net/MycnR/

EDIT: In response to my discussion with Blender, some more extensive HTML: http://jsfiddle.net/4ELhf/

Upvotes: 1

Views: 1149

Answers (7)

Alnitak
Alnitak

Reputation: 339816

You need to tell the increment function which element it has to change.

This can be done using the data parameter to the .on() call, where the supplied parameter is available as ev.data within the event handler:

function increment(ev) {
     var el = ev.data || this;  // use the clicked element if it wasn't supplied
     el.value = parseInt(el.value, 10) + 1;
}

$('#WS1inc').on('click', document.getElementById('WS1'), increment);

Note the use of el.value - there's no need to use $(el).val() in most circumstances and el.value is far more efficient.

See http://jsfiddle.net/alnitak/W8fjX/

Upvotes: 1

gion_13
gion_13

Reputation: 41533

The first argument passed to an event handler is the event object. In jquery, the context of the event handler (this) is set to the element that listened to that event... maybe you could relate to that and might want to change your function to :

function increment(){
    var field = $(this).siblings('input');
    field.val( (+field.val() || 0) + 1);
}

Here's a live demo : http://jsfiddle.net/MycnR/5/

Upvotes: 1

mplungjan
mplungjan

Reputation: 177885

Generic function:

DEMO

html

<button type="button"  id="WS1dec" class="but"> - </button>  
<input type="number" id="WS1" value="1">        
<button type="button"  id="WS1inc" class="but"> + </button>  
<hr/>
<button type="button"  id="WS2dec" class="but"> - </button>  
<input type="number" id="WS2" value="1">        
<button type="button"  id="WS2inc" class="but"> + </button>  

jQuery

$(function() {
  $(".but").on("click",function() {
    var id=this.id;
    var fldId=id.substring(0,id.length-3);
    var inc=id.substring(id.length-3)=="inc";
    var fld = $("#"+fldId);
    var val = +fld.val();
    if (inc)val++;else val--;
    fld.val(val);
  });
});

Upvotes: 1

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382130

That's because you don't pass the field.

You may change the call to

$("#WS1inc").click(function(){increment($("#WS1")});

When you use eventData (the first argument you pass to click), those data aren't passed as argument directly to the handler but in event.data. So you can also do this :

function increment(e) {
    e.data.val(parseInt(e.data.val(), 10) +1);
}
$("#WS1inc").click($("#WS1"),increment);

Note that you must also parse the string in order to increment.

About this eventData argument, I found that the documentation of on is clearer :

Data to be passed to the handler in event.data when an event is triggered.

Upvotes: 2

Anton
Anton

Reputation: 32581

$("#WS1inc").click(function(){
     $("#WS1").val(parseInt($("#WS1").val())+1);
});

Demo here http://jsfiddle.net/MycnR/1/

Upvotes: 2

Blender
Blender

Reputation: 298166

You've got the syntax mixed up a little. Here's a super verbose way of doing it:

$("#WS1inc").click(function() {
    var $element = $("#WS1");
    var value = $element.val();
    var value_as_integer = parseInt(value, 10);

    $element.val(value_as_integer + 1);
});

Upvotes: 1

Curtis
Curtis

Reputation: 103358

There are a few issues here.

field.val()+1 is going to be classed as string concatenation rather than integer incrementation. You need to parseInt() first in order for this to calculate correctly.

Secondly, there is an issue with how you are calling increment().

Change your code to:

function increment(field)
{
    field.val(parseInt(field.val(),10)+1);
}

$("#WS1inc").click(function(){
   increment($("#WS1"));
});

Live Demo: http://jsfiddle.net/MycnR/2/

Upvotes: 2

Related Questions