Avraam Mavridis
Avraam Mavridis

Reputation: 8920

set events to DOM objects using loop

I have some DOM inputs and I added some events to them, the inputs are like:

$("#hotel2city").keyup(function(){
    getDestinations($("#hotel2city"));
});

$("#hotel2name").keyup(function(){
    getHotels($("#hotel2city").val(),$("#hotel2name"));
});

which works, what I want to do is to not repeat every time the above code but to have a for loop that attach the events. So I wrote an IIFE:

var setControlls = function(){
    for(var i=1; i<=5; i++){
        $("#hotel" + i +"city").keyup(function(){
                getDestinations($("#hotel"+i+"city"));
        });

        $("#hotel"+i+"name").keyup(function(){
            getHotels($("#hotel"+i+"city").val(),$("#hotel"+i+"name"));
        });
    }
}();

but this does not work, any idea what I am doing wrong?

Upvotes: 0

Views: 30

Answers (3)

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

just add a class to them and pass the id of the element to the function instead of writing multiple events on id basis:

<input id="hotel2city" class="hotelcity"/>

<input id="hotel2name" class="hotelname"/>

and write event on class selector:

$(".hotelcity").keyup(function(){
    getDestinations(this.id);
});

$(".hotelname").keyup(function(){
    getHotels($(this).val(),this);
});

Upvotes: 0

Adam Jenkins
Adam Jenkins

Reputation: 55613

Use a class to add the event once to all the elements, then use the ID of the element to perform the specific functionality you want inside the listener:

<input type='text' class='keyup-hotel-input' id="hotel2name">
<input type='text' class='keyup-hotel-input' id="hotel2city">
...
<input type='text' class='keyup-hotel-input' id="hotel5name">
<input type='text' class='keyup-hotel-input' id="hotel5city">

$('.keyup-hotel-input').on('keyup',function(e) {
   if(this.id.match('city')) {
       getDestinations($(this).val());
   } else {
       getHotels($(this).val());
   }
});

Upvotes: 1

Niels
Niels

Reputation: 49919

It's better to give it a class and then a data-id or something, so its scalable.:

HTML:

<div class="hotelCity" data-id="10"></div>

JS:

$(".hotelCity").on("keyup", function(){
    getDestinations($(this).data("id"));
});

And so on.

The issue you have is the scope, the i will always be the highest number. If you want to solve your issue, use this:

var setControlls = function(){
    for(var i=1; i<=5; i++){
        (function(j){ // Create scope
            $("#hotel" + j +"city").keyup(function(){
              getDestinations($("#hotel"+j+"city"));
            });

            $("#hotel"+i+"name").keyup(function(){
                getHotels($("#hotel"+j+"city").val(),$("#hotel"+j+"name"));
            });
        })(i); // Call scope j=i;
    }
}();

Upvotes: 0

Related Questions