📜 ⬆️ ⬇️

Components. Example

to the beginning of the notes about the components

Drop-down list



Create a simple component dropdown list. (Note that in the code of all notes there will be no jQuery). Suppose we have an anchor (input form), and let, when it receives focus, a drop-down list of predefined values ​​appears under it. When you click on the list item, we get its value in an arbitrary function.
')
image text

The sample code is available at https://github.com/mbykov/component-dropdown-example . Clone it and open the file test/example.html in the browser, click on input .



Create the skeleton components of this example:

 $ component create dropdown-example repo (username/project): mbykov/component-dropdown-example description: simple dropdown example . . . 


in components.json you need to specify the components we need:

 "dependencies": { "component/domify": "*", "component/each": "*", "component/classes": "*" }, 


And execute $ make . In the Makefile file you will see, in particular, (about the makefile format in the makefile vs. grunt note):

 build: components index.js dropdown.css @component build --dev components: component.json @component install --dev 


This means that the component install all the dependencies and create the build/build.js build/build.css . (I renamed the original dd-example.css to dropdown.css, and corrected the Makefile accordingly).

creating an example



Now create an example. Create a test directory and in it a file example.html , the essence of which

  <p><input type="text" id="anchor"><p> <script> var anchor = document.querySelector('#anchor'); var Dropdown = require('dd-example'); var dd = new Dropdown(anchor); </script> 


And in the index.js file we add the main content:

 var domify = require('domify'); var classes = require('classes'); var each = require('each'); module.exports = Dropdown; function Dropdown(anchor) { console.log(anchor); return this; } 


Pay attention to return this - this is important. Now we can create a chain of methods for our component. Each following method gets all the same this.

Now make again, and reload the test page (as long as we don’t use watch, so make manually). In Fayerbag we see that everything goes as it should, we see an anchor.

Let's write the dropdown component itself.

 function Dropdown(anchor) { var _div = domify('<div class="dropdown-div"></div>'); var _list = domify('<ul class="dropdown-list"></ul>'); _div.appendChild(_list); this.list = _list; this.div = _div; this.anchor = anchor; anchor.parentNode.insertBefore(_div, anchor.nextSibling); anchor.focus(); return this; } 


What's going on here?

We create two objects, _list and _list . Underlining it is convenient for me to select DOM objects (we no longer need underscore, and the $ sign somehow doesn’t look, but it's a matter of taste). In real life, of course, you need to place the html in template.html, and call it require('template') . I do not here for clarity of the code.

In the lines of this.list = _list save these objects as attributes of this object, this is useful in the method chain. And add a new object to the page.

 $ make 


But nothing has changed? That's right, now you need to show a list with predefined values ​​when clicking on the anchor. Add to the _div and the .css file the class hidden, and to the Dropdow function, click on the anchor, and the toggle () method:

  var self = this; anchor.onclick = function(e){ self.toggle(); classes(this.div).remove('hidden'); return false; } 


and create a method that will show the values

 Dropdown.prototype.render = function(values) { var self = this; values.each(function(value){ var added = domify('<li class="dropdown-line"></li>'); added.textContent = value; self.list.appendChild(added); }); return this; } 


let's add in the example text example.html a call to the render method with predefined values: var values = [' '...

  dd.render(values) 


There is no semicolon after the line. This is not an error; on the next line, the following component method will be called - .select ().

Now we will output the value when clicking on the list row in an arbitrary callback to our component (Kolbek in the example will be just console.log).

 Dropdown.prototype.select = function(cb){ var self = this; this.list.onclick = function(e) { var value = e.target.textContent; anchor.value = value; self.hide(); cb(value); }; } 


here we do not need to return return this at the end of the function, because this is the end of the chain. Call the .select method in example.html , in which we output the value to the console. Voila.

conclusion



Quite the last, and not directly related to the example - the list is displayed not under the anchor, but at the beginning of the line. But for beauty, we align the list - this is one line in the main function:

  _div.style.left = getOffset(anchor).left +'px'; 


I got the getOffset function from Mathew Muellera, thanks to him.

When creating this example and my “adult” dropdown component, I was guided by the examples of older colleagues: component/dropdown , stagas/dropdown , bmcmahen/dropdown , matthewmueller/autocomplete . True, they all use jQuery, which is why I wrote my mbykov/dropdown - it is designed for json-data obtained from couchdb , so it has its own characteristics.

Now you can use this drop-down list as many times as you like, with any predefined values, on one page or on many.

to be continued

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


All Articles