remove class to sibling of elemnt jquery - javascript

I have this Jquery function, with a filter that adds a class named selected to the filter by click and shows all that data filter tags of the selected filter.
I want to define that if the sibling of the chosen element has a class named selected, that class needs to be removed from the rest and has to be added to only the selected element.
Function Script
(function ($) {
"use strict";
$.fn.filter = function (options) {
var defaults = {
nav: '[data-filter]' //
}
var $this = this,
settings = $.extend(defaults, options),
$target = $(settings.target),
selected = [];
return this.each( function() {
var $element = $(this);
$(settings.nav).each( function() {
$(this).click( function(event) {
// add selected class
$(this).toggleClass('selected');
// manipulate selected terms array
if ($.inArray($(this).data('filter'), selected) < 0 ) {
selected.push($(this).data('filter'));
} else {
var index = $.inArray($(this).data('filter'), selected);
selected.splice(index, 1);
}
// show/hide elements
$element.find('[data-filter-tags]').each( function() {
var terms = $(this).data('filter-tags').split(','),
show = null;
for (var i=0;i<selected.length;i++) {
show = ($.inArray(selected[i], terms) >= 0 && show !== false);
}
if (show || selected.length == 0) {
$(this).fadeIn();
} else {
$(this).fadeOut();
}
});
event.preventDefault();
});
});
});
};
}(jQuery));
HTML
<div id="tags">
<div id="cities" data-activeclass="selected">
תל אביב
רמת גן
הכל
<div>
</br>
משרה מלאה
משרה חלקית
הכל
</br>
מזכירות
הפעלה
הכל
</br>
</nav>
<div id="filter">
<div class="block" style="background: green" data-filter-
tags="time,kind,city,telaviv,full,sec">תל אביב משרה מלאה מזכירות</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,full,sec">רמת גן מלאה מזכירות</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,part,op">רמת גן חלקית הפעלה</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,telaviv,full,op">תל אביב מלאה הפעלה</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,part,sec">רמת גן חלקית מזכירות</div>
</div>

I want to define that if the sibling of the choosen elemnts has class named
"selected" remove the class from them and add it only to the selected element.
If clicking the element selects it and deselects all of its siblings, then in your click handler:
$(this).addClass("selected").siblings().removeClass("selected");
Simplified live example:
$("[data-filter]").on("click", function() {
$(this).addClass("selected").siblings().removeClass("selected");
});
[data-filter] {
border: 1px solid blue;
}
.selected {
background-color: yellow;
}
<div>
<span data-filter="1">one</span>
<span data-filter="2">two</span>
<span data-filter="3">three</span>
<span data-filter="4">four</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If clicking the element toggles it, we want toggleClass (which you have) but the rest is the same:
$(this).toggleClass("selected").siblings().removeClass("selected");
...since the .siblings().removeClass("selected"); part just won't do anything if the current element was the one that was selected.
Simplified live example:
$("[data-filter]").on("click", function() {
$(this).toggleClass("selected").siblings().removeClass("selected");
});
[data-filter] {
border: 1px solid blue;
}
.selected {
background-color: yellow;
}
<div>
<span data-filter="1">one</span>
<span data-filter="2">two</span>
<span data-filter="3">three</span>
<span data-filter="4">four</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

How could this JavaScript function be simplified. I have 100 buttons controlling the show/hide display of 100 content areas

The abbreviated JS file below provides the same functionality for 100 buttons.
All buttons are identified by ID names such as #btn1, #btn2 etc.
The buttons trigger the hide/show of content contained within div tags labelled within corresponding class names such as .btn1, .btn2, etc.
For example, selecting #btn1 is tied to the content within content content content .
The process is to select a button, then whichever button is selected, hide the content within all the 100 DIVs and then show the selected button’s associated content.
In writing the JS file I have written out the whole function 100 times - listing each one of 100 buttons to be selected, all 100 div areas to be hidden, and then the one div area to be shown.
How could this be simplified into a smarter and more concise function?
// JavaScript Document
$(document).ready(function() {
$('#btn0').click(function() {
location.reload();
});
});
$(document).ready(function() {
$('#btn1').click(function() {
$('.btn0').hide();
$('.btn1').hide();
$('.btn2').hide();
$('.btn3').hide();
$('.btn4').hide();
$('.btn5').hide();
$('.btn6').hide();
$('.btn7').hide();
$('.btn8').hide();
$('.btn9').hide();
$('.btn10').hide();
$('.btn11').hide();
$('.btn11').hide();
$('.btn12').hide();
$('.btn13').hide();
$('.btn14').hide();
$('.btn15').hide();
$('.btn16').hide();
$('.btn17').hide();
$('.btn18').hide();
$('.btn19').hide();
$('.btn20').hide();
$('.btn21').hide();
$('.btn22').hide();
$('.btn23').hide();
$('.btn24').hide();
$('.btn25').hide();
$('.btn26').hide();
$('.btn27').hide();
$('.btn28').hide();
$('.btn29').hide();
$('.btn30').hide();
$('.btn31').hide();
$('.btn32').hide();
$('.btn33').hide();
$('.btn34').hide();
$('.btn35').hide();
$('.btn36').hide();
$('.btn37').hide();
$('.btn38').hide();
$('.btn39').hide();
$('.btn40').hide();
$('.btn41').hide();
$('.btn42').hide();
$('.btn43').hide();
$('.btn44').hide();
$('.btn45').hide();
$('.btn46').hide();
$('.btn47').hide();
$('.btn48').hide();
$('.btn49').hide();
$('.btn50').hide();
$('.btn51').hide();
$('.btn52').hide();
$('.btn53').hide();
$('.btn54').hide();
$('.btn55').hide();
$('.btn51').hide();
$('.btn52').hide();
$('.btn53').hide();
$('.btn54').hide();
$('.btn55').hide();
$('.btn56').hide();
$('.btn57').hide();
$('.btn58').hide();
$('.btn59').hide();
$('.btn60').hide();
$('.btn61').hide();
$('.btn62').hide();
$('.btn63').hide();
$('.btn64').hide();
$('.btn65').hide();
$('.btn66').hide();
$('.btn67').hide();
$('.btn68').hide();
$('.btn69').hide();
$('.btn70').hide();
$('.btn71').hide();
$('.btn72').hide();
$('.btn73').hide();
$('.btn74').hide();
$('.btn75').hide();
$('.btn76').hide();
$('.btn77').hide();
$('.btn78').hide();
$('.btn79').hide();
$('.btn80').hide();
$('.btn81').hide();
$('.btn82').hide();
$('.btn83').hide();
$('.btn84').hide();
$('.btn85').hide();
$('.btn86').hide();
$('.btn87').hide();
$('.btn88').hide();
$('.btn89').hide();
$('.btn90').hide();
$('.btn91').hide();
$('.btn92').hide();
$('.btn93').hide();
$('.btn94').hide();
$('.btn95').hide();
$('.btn96').hide();
$('.btn97').hide();
$('.btn98').hide();
$('.btn99').hide();
$('.btn100').hide();
$('.btn98').hide();
$('.btn99').hide();
$('.btn100').hide();
$('.btn1').show();
});
});
$(document).ready(function() {
$('#btn2').click(function() {
$('.btn0').hide();
$('.btn1').hide();
$('.btn2').hide();
$('.btn3').hide();
$('.btn4').hide();
$('.btn5').hide();
$('.btn6').hide();
$('.btn7').hide();
$('.btn8').hide();
$('.btn9').hide();
$('.btn10').hide();
$('.btn11').hide();
…………………….. BTN12 to 97 ……………………..
$('.btn98').hide();
$('.btn99').hide();
$('.btn100').hide();
$('.btn1').show();
});
});
Etc., up to 100 buttons
// JavaScript Document
Assuming you can't change the html structure, I would probably do:
$('[id^="btn"]').on('click', function() {
const id = $(this).attr('id');
$('[class^="btn"]').hide();
$(`.${id}`).show();
});
Which will listen to the click event on any element where the id starts with btn, then hide all elements where the class starts with btn, then show the element with the same class as the id that was just clicked (e.g. #btn2 click will show .btn2)
something like this.
for(let i = 0;i<=99;i++){
let btnclass= ".btn" + i;
$(btnclass).hide()
}
You can use a for loop to iterate from 0 to 100:
$(document).ready(function() {
$("#btn1").click(function() {
for (let i = 0; i <= 100; i++) {
$(`.btn${i}`).hide();
}
});
})
Full version:
// JavaScript Document
$(document).ready(function() {
$("#btn0").click(function() {
location.reload();
});
});
$(document).ready(function() {
$("#btn1").click(function() {
for (let i = 0; i <= 100; i++) {
$(`.btn${i}`).hide();
}
});
})
$(document).ready(function() {
$("#btn2").click(function() {
for (let i = 0; i <= 100; i++) {
$(`.btn${i}`).hide();
}
});
});
Common class and data attributes along with event delegation makes the code easier to maintain.
document.querySelector("#wrapper").addEventListener("click", function (event) {
var toggles = event.target.dataset.toggles;
// Hide previous selected elements
var selectedElems = document.querySelectorAll(".out.selected");
if (selectedElems.length){
selectedElems.forEach(function (elem) {
elem.classList.remove("selected");
});
}
// show the new active elements
const activeElems = document.querySelectorAll(toggles);
if (activeElems.length){
activeElems.forEach(function (elem) {
elem.classList.add("selected");
});
}
});
.out {
display: none;
}
.out.selected {
display: block;
}
<div id="wrapper">
<button id="btn1" data-toggles=".out1">1</button>
<button id="btn2" data-toggles=".out2">2</button>
<button id="btn3" data-toggles=".out3">3</button>
<button id="btn4" data-toggles=".out4">4</button>
</div>
<div class="out out1">1</div>
<div class="out out2">2</div>
<div class="out out3">3</div>
<div class="out out4">4</div>
If you want to use jQuery
$("#wrapper").on("click", "[data-toggles]", function (event) {
var toggles = $(this).data('toggles');
$(".out.selected").removeClass("selected");
$(toggles).addClass("selected");
});
.out {
display: none;
}
.out.selected {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
<button id="btn1" data-toggles=".out1">1</button>
<button id="btn2" data-toggles=".out2">2</button>
<button id="btn3" data-toggles=".out3">3</button>
<button id="btn4" data-toggles=".out4">4</button>
</div>
<div class="out out1">1</div>
<div class="out out2">2</div>
<div class="out out3">3</div>
<div class="out out4">4</div>

How to remove highlighted multiple html contenteditable elements?

How can I highlight multiple HTML elements and remove them by pressing the Backspace key? WordPress block editor and Editor.js has this feature. Users can select/ Highlight multiple block and remove them by pressing the Backspace key.
From this code below, If I highlight by selecting(mouse) not by clicking the .block-1, .block-2, .block-3 and press Backspace key then it should delete these elements.
[NOTE]
Every block should have contenteditable attribute.
Please, go to Editor.js first for demo what I exact want.
<div class="block-1" contenteditable="true"> 1st Block </div>
<div class="block-2" contenteditable="true"> 2nd Block </div>
<div class="block-3" contenteditable="true"> 3rd Block </div>
<div class="block-4" contenteditable="true"> 4th Block </div>
We need 2 listeners:
1 - on mouseup, which catches selected text, and use TreeWalker to get all the highlighted elements and toggle selected class on .blocks.
2 - on keyup, which will catch backspace
Edit:
Used This and improved the answer .
$(document).on({
'keyup': function(e) {
if (e.which == 8)
$('div.block.selected').remove();
},
'mouseup': getSelectedElementTags
});
function rangeIntersectsNode(range, node) {
var nodeRange;
if (range.intersectsNode) {
return range.intersectsNode(node);
} else {
nodeRange = node.ownerDocument.createRange();
try {
nodeRange.selectNode(node);
} catch (e) {
nodeRange.selectNodeContents(node);
}
return range.compareBoundaryPoints(Range.END_TO_START, nodeRange) == -1 &&
range.compareBoundaryPoints(Range.START_TO_END, nodeRange) == 1;
}
}
function getSelectedElementTags() {
var win = window;
var range, sel, elmlist, treeWalker, containerElement;
sel = win.getSelection();
if (sel.toString().length == 0) return
if (sel.rangeCount > 0) {
range = sel.getRangeAt(0);
}
if (range) {
containerElement = range.commonAncestorContainer;
if (containerElement.nodeType != 1) {
containerElement = containerElement.parentNode;
}
treeWalker = win.document.createTreeWalker(
containerElement,
NodeFilter.SHOW_ELEMENT,
function(node) {
return rangeIntersectsNode(range, node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
},
false
);
elmlist = [treeWalker.currentNode];
while (treeWalker.nextNode()) {
elmlist.push(treeWalker.currentNode);
}
elmlist.forEach(function(e) {
if ($(e).hasClass('block')) {
$(e).toggleClass('selected');
}
});
sel.empty()
}
}
div.block.selected {
background-color: #ddf;
}
div.block {
margin: 24px;
border-bottom: 1px solid #ddd;
font-size: 13px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container" contenteditable="true">
<div class="block block-1" contenteditable="true"> 1st Block</div>
<div class="block block-2" contenteditable="true"> 2nd Block </div>
<div class="block block-3" contenteditable="true"> 3rd Block</div>
<div class="block block-4"> 4th Block </div>
</div>
The CSS and the contenteditable attribute are not necessary. Here is the code
var targeted;
document.getElementById('container').addEventListener('click', function(event) {
console.log(event.target); // You can see here the targeted element
if(event.target.id !== 'container') {
targeted = event.target;
} else {
targeted = undefined;
};
});
document.addEventListener('keydown', function(event) {
if(event.keyCode === 8 && targeted) {
targeted.parentNode.removeChild(targeted);
};
});
#container {
padding: 20px;
background-color: black;
}
#container div {
margin-bottom: 5px;
height: 50px;
width: 200px;
background-color: white;
}
<div id="container">
<div contenteditable="true">1</div>
<div contenteditable="true">2</div>
<div contenteditable="true">3</div>
<div contenteditable="true">4</div>
<div contenteditable="true">5</div>
</div>

How can I toggle between two sections while keeping one element visible?

var toggles = document.querySelectorAll("[data-toggle-content-section]");
var sections = document.querySelectorAll(".content-bar__section");
var toggleSections = function(event) {
event.preventDefault();
sections.forEach(function(elem) {
console.log(elem) ;
elem.classList.toggle("active");
});
};
toggles.forEach(function(elem) {
elem.addEventListener("click", toggleSections, ) ;
});
Depending on your HTML you could do something like this:
Note that this is just an example and might have to adjusted to reflect your own markup
var toggles = document.querySelectorAll("[data-toggle-content-section]");
var sections = document.querySelectorAll(".content-bar__section");
var toggleSections = function(event) {
event.preventDefault();
sections.forEach(function(elem) {
elem.classList.remove("active");
});
// get the child element of the just clicked toggle element
event.target.querySelector('.content-bar__section').classList.add("active");
};
toggles.forEach(function(elem) {
elem.addEventListener("click", toggleSections);
});
.content-bar__section{
display: none;
}
.active{
display: block;
}
<div data-toggle-content-section>
Headline 1
<div class="content-bar__section">
Section 1
</div>
</div>
<div data-toggle-content-section>
Headline 2
<div class="content-bar__section">
Section 2
</div>
</div>
<div data-toggle-content-section>
Headline 3
<div class="content-bar__section">
Section 3
</div>
</div>
As you also tagged jQuery here the same solution depending on jQuery:
var $toggles = $("[data-toggle-content-section]");
var $sections = $(".content-bar__section");
$toggles.on('click', function() {
event.preventDefault();
$sections.removeClass('active');
$(this).find('.content-bar__section').addClass('active');
});
.content-bar__section {
display: none;
}
.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-toggle-content-section>
Headline 1
<div class="content-bar__section">
Section 1
</div>
</div>
<div data-toggle-content-section>
Headline 2
<div class="content-bar__section">
Section 2
</div>
</div>
<div data-toggle-content-section>
Headline 3
<div class="content-bar__section">
Section 3
</div>
</div>
In the case where you have n areas and you want to only show/activate one at a time, the nearly canonical way to do this is:
function selectOne(e) {
document.querySelectAll(".commonClass").forEach(function(elem) {
//disable element
elem.disabled = true;
});
//enable selected element
document.getElementById(e.target).disabled = false;
}

Displaying a message when jQuery filter returns nothing

I found code online that filters elements by their text content.
How can I display a message when there is no match?
$("button").click(function() {
var value = $(this).data('value').toUpperCase();
$("div").filter(function(index) {
$(this).toggle($(this).text().indexOf(value) > -1)
});
});
<button>example</button>
You're using filter() to toggle each item based on state, like using each(). But one advantage of filter() is that you can return a reduced selection and count the items it contains. That value can determine whether a "no match" message should be displayed.
... the .filter() method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against each element; all elements matching the selector will be included in the result. -- filter().
For each element, if the function returns true (or a "truthy" value), the element will be included in the filtered set; otherwise, it will be excluded. -- Using a Filter Function
So, instead of toggling items directly from the filter call, consider returning a Boolean measure of whether the current item is a match. Save the resulting filtered selection in a variable. After filtering, you can toggle that selection as a whole:
var $filtered = $items.filter(function() {
return $(this).text().indexOf(value) > -1;
});
$items.toggle(false);
$filtered.toggle(true);
This hides all items and then shows only the filtered items.
You might even consider some fading animation:
$items.hide(250);
$filtered.stop(true,false).show(250);
Then you can reference the filtered selection's length.
If it's zero, show the "not found" message:
var hasMatches = $filtered.length;
if (hasMatches) {
// there were matches.
} else {
// no matches.
}
You can also pass a selector to a filter. jQuery's :contains() selector selects "all elements that contain the specified text", which makes a nice choice.
Working Example:
var $items = $('.item');
var $none = $('#none');
var fade = 250;
function filterContent() {
// get word from value of clicked button.
var word = this.value;
// hide items; filter; show filtered; count matches
var hasMatches = $items
.hide(fade)
.filter(':contains(' + word + ')')
.stop(true, false)
.show(fade)
.length;
// if no matches, show message.
if (hasMatches) {
$none.hide(fade);
} else {
$none.show(fade);
}
}
$('button').on('click', filterContent);
#none {
display: none;
color: darkred;
}
#buttons {
margin: 1em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">Here is some text.</div>
<div class="item">Here is some other text.</div>
<div class="item">Here is some other different text.</div>
<div class="item">Here is something else.</div>
<div class="item">Here is some additional text.</div>
<div id="none">No matches found.</div>
<nav id="buttons">
<button type="button" value="">all</button>
<button type="button" value="text">text</button>
<button type="button" value="other">other</button>
<button type="button" value="additional">additional</button>
<button type="button" value="bazooka">bazooka</button>
</nav>
Another way:
If you prefer, you can toggle inside the filter as long as you still return the state Boolean from the function. I suggest making a separate function to pass to the filter. In this case, toggleItem() determines the state of an item (match or non-match), toggles the item according to that state, and returns the state.
var $items = $('.item');
var $none = $('#none');
function toggleItem(word) {
return function(k, el) {
var $item = $(el);
var state = $item.text().indexOf(word) > -1;
$item.toggle(state);
return state;
}
}
function filterContent() {
// get word from value of clicked button.
var word = this.value;
// filter while toggling and count result.
var hasMatches = $items
.filter(toggleItem(word))
.length;
// if no matches, show message.
$none.toggle(!hasMatches);
}
$('button').on('click', filterContent);
#none {
display: none;
color: darkred;
}
#buttons {
margin: 1em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">Here is some text.</div>
<div class="item">Here is some other text.</div>
<div class="item">Here is some other different text.</div>
<div class="item">Here is something else.</div>
<div class="item">Here is some additional text.</div>
<div id="none">No matches found.</div>
<div id="buttons">
<button type="button" value="">all</button>
<button type="button" value="text">text</button>
<button type="button" value="other">other</button>
<button type="button" value="additional">additional</button>
<button type="button" value="bazooka">bazooka</button>
</div>
In my opinion, this is a bit harder to read and not as clear as the chained "hide,filter,show,length" commands, but that's somewhat a matter of style. You can see that there are many ways to bake this cake!
This one's pretty short and sweet:
var $none = $("#none");
var $items = $(".item");
$("button").click(function() {
var value = $(this).data('value');
$items.each(function() {
$(this).toggle($(this).text().indexOf(value) > -1);
});
$none.toggle(!$items.filter(':visible').length);
});
#none {
display: none;
color: darkred;
}
#buttons {
margin: 1em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">Here is some text.</div>
<div class="item">Here is some other text.</div>
<div class="item">Here is some other different text.</div>
<div class="item">Here is something else.</div>
<div class="item">Here is some additional text.</div>
<div id="none">No matches found.</div>
<nav id="buttons">
<button type="button" data-value="">all</button>
<button type="button" data-value="text">text</button>
<button type="button" data-value="other">other</button>
<button type="button" data-value="additional">additional</button>
<button type="button" data-value="bazooka">bazooka</button>
</nav>
You can create a variable to count match item.
$("button").click(function(){
var value = $(this).data('value').toUpperCase();
var count = 0;
$("div").filter(function(index) {
if($(this).text().indexOf(value) > -1) count++;
$(this).toggle($(this).text().indexOf(value) > -1)
});
if(count == 0) alert('Not match');
});
$("button").click(function(){
var value = $(this).data('value').toUpperCase();
var count = 0;
$("div").filter(function(index) {
if($(this).text().indexOf(value) > -1) count++;
$(this).toggle($(this).text().indexOf(value) > -1)
});
if(count == 0) alert('Not match');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>TEST1</div>
<div>example</div>
<div>test1</div>
<button data-value='test1'>example</button>
filter() returns the value. Check if the length is 1 or more.
$(".filter").click(function() {
var value = $(this).text(); //Get the text of the button
var result = $("div").hide().filter(function(i, o) { //Hide All and filter
return $(o).text().includes(value); //Return true if the content of div contains text of the button
}).show(); //Show all result
if (result.length) { //Check the length of the result
//Found match/es
$(".msg").text('');
} else {
//No match
$(".msg").text(`${value} not found`);
}
});
$(".show-all").click(function() {
$("div").show();
});
.msg {
border: 1px solid black;
}
div {
background-color: pink
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="msg"></span>
<br /><br />
<div> apple </div>
<div> orange </div>
<div> rock melon</div>
<div> pineapple </div>
<div> pineapple pie</div>
<br /><br />
<button class="filter">example</button>
<button class="filter">pineapple</button>
<button class="filter">rock</button>
<br /><br />
<button class="show-all">Show all</button>

Filter elements in DOM based on data-attr with jQuery

I'm trying to filter these items with jQuery autocomplete according to their data-name, but I got stuck with it a bit. Generally, I want to start typing the text in the input field and remove items from DOM if they don't match. Any help is much appreciated.
Pen: https://codepen.io/anon/pen/aVGjay
$(function() {
var item = $(".item");
$.each(item, function(index, value) {
console.log($(value).attr("data-name"));
var everyItem = $(value).attr("data-name");
});
$("#my-input").autocomplete({
source: everyItem, //?
minLength: 1,
search: function(oEvent, oUi) {
// get current input value
var sValue = $(oEvent.target).val();
// init new search array
var aSearch = [];
// for each element in the main array
$(everyItem).each(function(iIndex, sElement) {
// if element starts with input value
if (sElement.substr(0, sValue.length) === sValue) {
// add element
aSearch.push(sElement);
}
});
// change search array
$(this).autocomplete("option", "source", aSearch);
}
});
});
.items {
width: 200px;
}
.item {
background-color: red;
margin-top: 2px;
}
<input type="text" placeholder="Filter items" id="my-input">
<div class="items">
<div class="item" data-name="one">one</div>
<div class="item" data-name="two">two</div>
<div class="item" data-name="three">three</div>
<div class="item" data-name="four">four</div>
</div>
It's a little odd to use autocomplete for this, as that's intended to build a filtered option list from a provided object or remote data source, not from DOM content.
You can build the functionality yourself by attaching an input event listener to the #my-input which in turn goes through the .item elements and uses a regular expression to filter ones with matching data-name attributes and displays them, something like this:
$(function() {
var $items = $(".item");
$('#my-input').on('input', function() {
var val = this.value;
$items.hide().filter(function() {
return new RegExp('^' + val, 'gi').test($(this).data('name'));
}).show();
});
});
.items {
width: 200px;
}
.item {
background-color: red;
margin-top: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" placeholder="Filter items" id="my-input">
<div class="items">
<div class="item" data-name="one">one</div>
<div class="item" data-name="two">two</div>
<div class="item" data-name="three">three</div>
<div class="item" data-name="four">four</div>
</div>

Categories