Reputation: 3370
At the moment I'm filtering an array with array.filter
, passing in a regex.
The array I am filtering is based on the contents of a div.
Each child div of that div has a text which I extract with $.text()
and put into its own array so I can filter it. Then I output the contents of the filtered array.
The problem is that the filtering needs an array of strings, and thus I make separate array which I filter and then print to the html. But, then when a user clicks one of the items in the list, nothing happens, because the user clicks on div which isn't bound to an event. I do the binding on document ready, and I use the bound event to get the value of the data-item-pageid
attribute.
I need a way to this which gives me access to the data-item-pageid
of the clicked element and still is fast. I would prefer not to bind the events all over again each time the user types, so I think the logic needs to be changed. I need to hide the divs that do not match the regex.
this is the html:
<div class="content">
<div class="categories">
<div class="item" data-item-pageid="1">text1</div>
<div class="item" data-item-pageid="2">text2</div>
<div class="item" data-item-pageid="3">text3</div>
</div>
<div class="categories">
<div class="item" data-item-pageid="4">text4</div>
<div class="item"data-item-pageid="5">text5</div>
<div class="item"data-item-pageid="6">text6</div>
</div>
</div>
<div class="filter_result"></div>
This is the JavaScript code:
// Binds the click event for each category item
$('.category_item').click(function() {
console.log($(this));
});
...
// Array for filter
filterArray = [];
for (var i = 0; i < $categoryItems.length; ++i) {
filterArray[i] = $($categoryItems[i]).text();
}
...
function filterList(key) {
var result = filterArray.filter(/./.test.bind(new RegExp(key, 'i')));
if (key != '' || key) {
var markup = []; //ugh
for (var i = 0; i < result.length; ++i) {
markup += '<div class="category_item">' + result[i] + '</div>';
}
if ($categoryItems.is(':visible'))
$categoriesDiv.toggle();
$filteredResult.html(markup);
} else {
$filteredResult.html('');
if (!$categoryItems.is(':visible'))
$categoriesDiv.toggle();
}
}
Upvotes: 0
Views: 196
Reputation: 13702
You could do delegated event handling
$(CONTAINER_SELECTOR).on('click', CHILD_SELECTOR, function(){
/* Your click handler*/
});
CONTAINER_SELECTOR
is an element that is not added/removed so it retains its listenersCHILD_SELECTOR
is the selector for the children which are added/removed, of whose clicks we wish to listen toIn your case $(CONTAINER_SELECTOR)
could be $filteredResult
and CHILD_SELECTOR
.category_item
.
For better understanding of delegated events check out the official docs or have a look at one of my other answers on delegated events.
You could easily retrieve the filtered list using:
$elements = $('.item');
$filteredList = $elements.filter(
function(index){
return conditionIsMetFor($(this).text()); // this refers to the element under iteration
}
);
Then you cant take $filteredList and:
$.clone()
it $.data()
they containUpvotes: 1