📜 ⬆️ ⬇️

Filter elements in cuSel

image

At one of the sites, which I have the honor to maintain, a wonderful jQuery plugin cuSel is used to customize the select . It is convenient because it is quite simple to configure and allows you to customize even the scroll bar.
But sometimes it happens that the list of items can be very large. And quickly find the desired item is not so easy.

Once I received the task to implement the ability to enter text and filter elements by the first letters. The list consisted of the names of cities in Ukraine and was quite long. Since this opportunity was absent in the plugin itself, and like me and the customer did not want to give up a beautiful select, it was decided to make minor improvements to the script code.

Today I will try to repeat it all with you. To do this, take a demo from the page of the plugin. The archive contains all the necessary libraries and styles. On the index.html page, the author has prepared several examples of connecting and using the plugin. Let's add filtering for the first select, which contains a list of countries.
')
To enter text, we will use a transparent text field, which will be adjusted by clicking on the top layer of the select. Add a corresponding css-class for this field to the css / cusel.css file and set the same dimensions for the block that displays the text of the selected list item.

.cusel .search-field { position: absolute; outline:0; border: 0; background: transparent; display:none; } .cusel .search-field, .cuselText { width: 144px; height: 20px; line-height:20px; padding: 3px 30px 3px 6px; } 


In order to be able to add filtering only to the necessary selects, we will mark them with an additional filtering class.

  <select class="sel80 filtering" id="country" name="country" tabindex="2"> 


Open the js / cusel.js file and add the following code to the cuselEvents function.

 jQuery(".cusel").each(function () { var itv; var elm = $(this); if (elm.hasClass("filtering") && elm.find(".search-field").length == 0) { var f = $("<input type='text' />") f.addClass("search-field"); f.keydown(function () { clearInterval(itv); var list = elm.find(".cusel-scroll-pane > span"); itv = setInterval(function () { list.each(function () { var item = $(this); item.show(); if (item.text().toLowerCase().indexOf(f.val().toLowerCase()) != 0) item.hide(); }); var d = elm.find(".cusel-scroll-pane").eq(0).attr("id"); jQuery("#" + d)[0].scrollTo(0); clearInterval(itv); }, 100); }); f.click(function () { $(this).val('').hide(); elm.focus(); }); elm.append(f); } }); 


What does this code do? Finds on the page all the elements with the class «cusel». It is this class that is used in stylized selects. Further, if the filtering class is specified for the select and it does not have a child element with the search-field class (our text field), then such a field is created and an event handler is hung on it. The handler, for each keystroke in the field, finds items in the list whose text does not match the text in the field and simply hides them.

Now we need to do so that by clicking on the select above it appears our transparent field. To do this, in the same cuselEvents function, we find the “click” event handler. It is necessary to find a part of the code marked by the author’s comment “if you clicked on the select (text)” and change it as follows.

 /*      () */ if((clickedClass.indexOf("cuselText")!=-1 || clickedClass.indexOf("cuselFrameRight")!=-1) && clicked.parent().prop("class").indexOf("classDisCusel")==-1) { var cuselWrap = clicked.parent().find(".cusel-scroll-wrap").eq(0); var parent = clicked.parents(".cusel"); if (parent.hasClass("filtering")) { var txt = parent.children(".cuselText"); var sf = parent.children(".search-field"); if(sf.is(":hidden")) { txt.text(""); sf.show().focus(); } else { txt.text(parent.find(".cuselActive").eq(0).text()); sf.val("").hide(); } } /*     -  */ cuselShowList(cuselWrap); } 


Since the text field is transparent so as not to overlap the background, we clear the text of the selected item in the select box. A second click will return the original state of the item.

Now we’ll do so that when you select an item in the list, the field is the opposite. Below, find the block marked by the author’s comment “if you chose a position in the list” and add the following code there

  else if(clicked.is(".cusel-scroll-wrap span") && clickedClass.indexOf("cuselActive")==-1) { var parent = clicked.parents(".cusel"); if (parent.hasClass("filtering")) { parent.children(".search-field").val('').hide(); parent.find(".cusel-scroll-pane > span").show(); } //  } 


As you can see, we make the list items hidden when filtering visible.

It would be logical if the user clicks the entire list, close the list and hide the filter field. Therefore, we find the block below, marked by the author's comment “hide the opened lists if clicked outside the list” and change it as follows.

 /*   ,     */ else { var wrap = jQuery(".cusel-scroll-wrap"); var parent = wrap.parents(".cusel"); parent.each(function () { var elm = $(this); if (elm.hasClass("filtering")) { elm.find(".cuselText").text(elm.find(".cuselActive").eq(0).text()); elm.find(".search-field").val('').hide(); elm.find(".cusel-scroll-pane > span").show(); } }); wrap.hide(); parent.removeClass("cuselOpen") } 


And now the final touch. At the very end of the cuselEvents function , you will find a piece of code marked with the following comment.

  /*      ( Alexey Choporov)           0.5  keypress       */ 


Alexey's function selects the appropriate value for the first letter. We realize the possibility of selection by several letters. Therefore, to avoid conflicts, the Alexey code must be commented out.

Sources

Source: https://habr.com/ru/post/175623/


All Articles