How can I add a property to my custom element and be able to trigger an action when its value changes

In fact, the name does not fully cover what I need. I created my own select element. It consisted of some div, ul / li and hidden input elements. Of course, he got the markup and part of javascript. Here's the html:

<div id="ddlCars" class="ma-select" style="width:350px;"> <div class="ma-select-box"><input class="ma-select-box-filter" type="text"></div> <div class="ma-select-options"> <ul class="ma-select-ul"> <li class="ma-select-li ma-visible-option" optvalue="7">MERCEDES</li> <li class="ma-select-li ma-visible-option" optvalue="10">BMW</li> <li class="ma-select-li ma-visible-option" optvalue="14">AUDI</li> <li class="ma-select-li ma-visible-option" optvalue="3">VOLKSWAGEN</li> </ul> </div> <input class="ma-select-hidden" type="hidden"> </div> 

Javascript code is just a bunch of functions that capture events like click, freeze, keyup, etc. and are tied to the above elements (by class) according to the finished method. I did not declare any type for this custom selection.

Using a regular DOM select element, I can do this:

  document.getElementById("mySelect").selectedIndex=0; 

Now I would like to achieve something similar. I can find the wrapper div by id or class name. But is there a way to do something like this?

 $('#ddlCars').selectedIndex=1; 

So, anyway, I need to add a property to my custom select and catch its change in order to set the highlighted value to the corresponding li element.

+5
source share
2 answers

in order to get the same behavior as the selection element that you might want to extend, for example, like a regular class. maybe use a library like Polymer, github.com/richardanaya/webblock or github.com/SaulDoesCode/Crafter.js to create your own element this way.

Otherwise, you should manually use getters and setters.
You will need to use Object.defineProperty to create this custom behavior using getters and seters on elements.

here is a small little function that will simplify

  function newGetSet(element ,key, get, set) { Object.defineProperty(element, key, { set: set, get: get }); } // then use it - just a rough example newGetSet( myElement , 'selectedIndex' , index => { // perhaps then apply a class or something to make it active document.querySelectorAll('ul > li')[index].classList.add('active'); }, () => { let active_index = 0; Array.from(document.querySelectorAll('ul > li')).forEach((item,index) => { if(item.classList.contains('active')) active_index = index; }); return active_index; }); 

Of course, as mentioned in another answer, in order to get the desired effect from the elements in the user selection list, it is possible to attach an EventListener.

so assume that the "selectedIndex" property is defined in the parent element, so you can just add Listeners, which will update the parent element.

 [...document.querySelectorAll('ul > li')].forEach((item,index) => { item.addEventListener('click',evt => { item.parentNode.selectedIndex = index; }); }); 
+2
source

I am afraid that .selectedIndex only works with the <select> element. If you really want to work with something similar, try

 $('ul li').live('click', function() { var index = $(this).index(); }); 

Use .delegate instead of .live if you are using jQuery 1.9+ as it is deprecated.

+1
source

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


All Articles