Dejavu
Dejavu

Reputation: 713

Append a string to the end of an element attribute

I am trying to create a function that will add/remove checkbox values into the array. I want to create the array name from the element's ID attribute (I am not sure if it's the best way to achieve). If ID is "color" values will be pushed to "colorFilter" or if ID is "size" it will be pushed to "sizeFilter". Problem is that I get "filterArray.push is not a function" error.

var colorFilter = [];
var sizeFilter = [];

$('.filter').each(function () {
    var filterName = $(this).attr("id");
    var filterArray = filterName + "Filter";
    $(this).find('a').on( 'click', function( event ) {

        var $target = $( event.currentTarget );
        var val = $target.attr( 'data-value' );
        var $input = $target.find( 'input' );
        var idx;

        if ( ( idx = filterArray.indexOf( val ) ) > -1 ) {
            filterArray.splice( idx, 1 );
            setTimeout( function() { $input.prop( 'checked', false ) }, 0);
        } else {
            filterArray.push( val );
            setTimeout( function() { $input.prop( 'checked', true ) }, 0);
        }

        getItems();
    });
});
function getItems() {
    $.ajax({
        url: "#",
        type: "GET",
        dataType: "JSON",
        data: {
            'color': colorFilter,
            'size': sizeFilter
        }
    });
}

Here is my html:

<ul id="color" class="filter">
    <li>
        <a href="#" data-value="red">
            <input type="checkbox"/>Red
        </a>
    </li>
    <li>
        <a href="#" data-value="blue">
            <input type="checkbox"/>Blue
        </a>
    </li>
</ul>

<ul id="size" class="filter">
    <li>
        <a href="#" data-value="10x14">
            <input type="checkbox"/>10x14
        </a>
    </li>
    <li>
        <a href="#" data-value="3x5">
            <input type="checkbox"/>3x5
        </a>
    </li>
</ul>

Upvotes: 0

Views: 65

Answers (2)

Thesane
Thesane

Reputation: 1398

you need to create a variable with the desired name before accessing it

window[filterArray] = new Array(); then use this variable instead. The way you implemented it filterArray is just a string not an array so your code will be

$('.filter').each(function () {
   var filterName = $(this).attr("id");
   var filterArray = filterName + "Filter";
   if(typeof(window[filterArray]) == 'undefined' || window[filterArray] == null)
       window[filterArray] = new Array();
   $(this).find('a').on( 'click', function( event ) {

       var $target = $( event.currentTarget );
       var val = $target.attr( 'data-value' );
       var $input = $target.find( 'input' );
       var idx;

       if ( ( idx = window[filterArray].indexOf( val ) ) > -1 ) {
           window[filterArray].splice( idx, 1 );
           setTimeout( function() { $input.prop( 'checked', false ) }, 0);
       } else {
           window[filterArray].push( val );
           setTimeout( function() { $input.prop( 'checked', true ) }, 0);
       }

   });
});

Upvotes: 2

andi
andi

Reputation: 6522

First of all, you're expecting the filter array name to be $(this).attr("id") + "Filter", and you defined colorFilter and sizeFilter, but your elements ids are "colors" and "sizes", not "color" and "size".

Second, instead of var filterArray = filterName + "Filter";, you need var filterArray = window[filterName + "Filter"];. This will capture the array that you're looking for.

Finally, move the declarations of filterName and filterArray inside the onclick event handler, like this:

$(this).find('a').on( 'click', function( event ) {
    var filterName = $(this).closest("ul").attr("id");
    var filterArray = window[filterName + "Filter"];
    var $target = $( event.currentTarget );
    var val = $target.attr( 'data-value' );
    var $input = $target.find( 'input' );
    var idx;

    if ( ( idx = filterArray.indexOf( val ) ) > -1 ) {
        filterArray.splice( idx, 1 );
        setTimeout( function() { $input.prop( 'checked', false ) }, 0);
    } else {
        filterArray.push( val );
        setTimeout( function() { $input.prop( 'checked', true ) }, 0);
    }

});

Upvotes: 0

Related Questions