Custom angular directives and jquery-implemented bootstrap style data two-way binding of the single & multi-select drop-down box

Source: Internet
Author: User
Tags angular scope

First of all, a little gossip, the apes who are familiar with angular will love this plugin.

00. putting the cart before the horse

I have to admit that I am a person who likes to put the cart before the horse, and students like to do the homework first, leaving the homework to be handed out immediately, and then slowly finish the unimportant work, lying trough, XX homework immediately to pay, hurriedly fill in fill. Now do this project, because did not find the right multi-choice drop-down Web plugin, and do not want to use HTML to bring the ugly <select multiple></select> it took me a whole day to do one. Perhaps the time for the development of the main functions in this way will be more a sense of urgency. I feel like I'm a self-abusing ape with a program of CSS and code indentation Obsessive-compulsive disorder.

01. Lily

Angular powerful controllers seem to be able to meet most of the UI requirements, but Nodejs applications often use a template engine like Ejs,jade to dynamically generate HTML pages, so the problem comes when I want to pass the background to express in Res.render () The parameters are displayed directly to the interface and bound to the corresponding Ng-model what to do?

Workaround 1, don't do anything at once, angular's controller sends a POST request to get the data.

Workaround 2, use the template to temporarily present the HTML, and then let the controller initialize the value of the $scope based on the data on the page

Solution 3, my humble angular and ejs Caishuxueqian, who has a good way to teach me Bai

For example now to do a choice drop-down box <select>n a <option>xx</option></select>, option in the background, I do not want to send a separate post to take, do not want to put on the page, Controller alone write logic processing, and the angular community has a ui-select plug-in, it seems that the data is taken from the $scope, not directly take the <option/> tag data, then I fire, not a drop-down box, I do Bai.

10. The Optimistic procedural ape

The idea is clear, define a angular directive, take the option value out, all events Gagaga, scope data binding, end of scatter

I estimate the time is half a day, but actually spent how long can only hehe, CSS obsessive-compulsive disorder, angular understanding not deep (so a lot of HTML operation is still in jquery), the incident is not fully caused by the end of time spent more than twice times to finish,

No nonsense, simple and practical, can be instantly binding ng-model $scope. XXX, you can also directly tune jquery's $ ("tag id"). val () can also get the value,

Git portal Duang:https://git.oschina.net/code2life/easy-select.git

Demo Portal duang~duang:http://ydxxwb.sinaapp.com/easy-select-demo/(the code is not up-to-date, with two fix bugs not yet deployed)

11. Release Code

1. How to use: Introduce library file bootstrap, angular1.x, introduce the Style.css file (you can modify CSS to customize the style you want), easy-select.js, define angular controller, rely on Easyselect module, like this ↓

angular. Module(' Datadisplay ', [' Easyselect ']). Controller(' Selectcontroller ', [' $scope ', ' $http ',function ( $scope, $http) {//Your code }]);Then refer to the Specification Definition selection box for the demo sample, is it good to have the intimacy of the HTML native Select tag 2. SOURCE interpretation: DOM operations and events are implemented in jquery, each with a brief comment, The key to implementing two-way binding is to get the Ng-model defined on the label, then set the value of Scope[ng-model] in the event, and Call the $digest () loop to let angular update the DOM according to Ng-model, $digest is one of the core of the angular implementation of two-way binding, the principle is to synchronize the variable scope value to all the need to update the place, the implementation of the temporary is not clear, have time to study the angular inside the $,$$ of the beginning of things. 3. Adaptive and Css,bootstrap is adaptive, CSS can customize the different styles, style.css have relevant comments

Easy-select.js

var comdirective = angular.module (' Easyselect ', []) comdirective.directive ("Easyselect", function () {return {            Link:function (scope, element, attrs) {var Ngmodel = $ (Element). attr ("Ng-model");            if (!ngmodel | | ngmodel.length = = 0) {Ngmodel = "Defaultselectmodel"; } var status = false;            Toggle Boolean var valueMap = "";            var options = $ (Element). Children ();            $ (Element). attr ("style", "padding:0"); Hide original options $.each (options, function (OPT) {$ (options[opt]). attr ("Style", "Display:            None ");            }); Build ul var html = "<div id=" + attrs.id + "-root ' style= ' width:100%;p osition:relative;left:-1px ' >" + "<p id= ' display-" +attrs.id + "' style= ' padding:6px 12px" + ((attrs.multiple! = undefined)? " 4px ":" 7px ") +" 12px;margin:0;border:none;width:95%;margin-left:2px;background-color: Transparent ' > "+" <span style= ' display:inline-block;padding-bottom:3px ' > </span>&lt  ;/p> "+//this is a dummy span" <ul id= ' "+ attrs.id +"-container ' class= ' List-group Easy-select-container ' style= ' display:none ' > ';                    Options ' container if (attrs.multiple! = undefined) {$.each (options, function (opt) {                    HTML + = "<li value= '" + $ (options[opt]). Val () + "' class= ' My-li-container list-group-item option-" +                    Attrs.id+ "' ><div style= ' width:100%;d isplay:inline-block ' >" + $ (options[opt]). HTML () + "</div><span value= '" + $ (options[opt]). Val () + "' class= ' my-li-option glyphicon glyphicon-ok ' ></span                ></li> ";            }); } else {$.each (options, function (opt) {if ($ (options[opt]). attr ("default")! = Undefine d) {Scope[ngmodel] = $ (optionS[opt]). Val ();                        ValueMap = $ (options[opt]). HTML ();                        HTML + = "<li value=" + $ (options[opt]). Val () + "' class= ' My-li-container list-group-item option-" + attrs.id+ "' >"                    + $ (options[opt]). HTML () + "</li>";  } else {html + = "<li value= '" + $ (options[opt]). Val () + "' class= ' My-li-container list-group-item                    option-"+ attrs.id+" > "+ $ (options[opt]). HTML () +" </li> ";            }                }); }//if multiple, add button if (attrs.multiple! = undefined) {html + = "<li class= ' List-group-item ' for= ' ensure-li ' ><button class= ' btn btn-default ' "+" for= ' ensure-btn ' style= ' Paddi            ng:2px ' >   ok   </button></li> ';            }//render UI html + = "</ul></div>";     $ (Element). append (HTML);       $ (". My-li-option"). each (function () {$ (this). FadeOut (0);            });            if (attrs.multiple = = undefined) $ ($ ("#display-" +attrs.id). Children () [0]). HTML (VALUEMAP);            Adjust width $ ("#" + attrs.id + "-root"). Width ($ ("#" + attrs.id + "-root"). Width () + 2);                    Mouse Leave event $ (element). MouseLeave (function () {$ (". My-li-container"). each (function () {                $ (this). attr ("Style", "" ");                });                    if (status) {$ ("#" + attrs.id + "-container"). attr ("style", "Display:none");                status =!status;            }            });                Multiple select seems complex if (attrs.multiple! = undefined) {//click event $ (Element). Click (function (e) {//if Click on tags, remove it if ($ (e.target). attr ("F or ") = =" Option-tag ") {//Change Val and digest change item in angular Scope[ngmodel] = $ (Element). val (). Replace ($ (e.target). attr ("value"), ""). Replace (/;+/, ";").                        Replace (/^;/, "");                        $ (Element). val (Scope[ngmodel]);                        Scope. $digest ();                        $ (e.target). Remove ();                                $ (". My-li-option"). each (function () {if ($ (). attr ("value") = = $ (e.target). attr ("value") {                            $ (this). CSS ("opacity", "0.01");                    }                        });  } else if ($ (this). attr ("for")! = ' Ensure-li ') {//toggle ul $ ("#" + attrs.id + "-container"). attr ("style", status?                        "Display:none": "");                    status =!status;                }                }); $ (". option-" +attrs.id). each (function () {$ (The). On (' click ', function () {var Selec TVAlue = $ (Element). Val ();                        var CurrentValue = $ (this). attr ("value");                        var selected = false;                        If option is selected, remove it var temp = Selectvalue.split (";");                                $.each (temp,function (obj) {if (Temp[obj].indexof (currentvalue)! =-1) {                            selected = true; }}) if (selected) {$ (this). Children () [1]). Fade                            to (300,0.01); Scope[ngmodel] = $ (Element). val (). replace (CurrentValue, ""). Replace (/;{ 2}/, ";").                            Replace (/^;/, "");                            $ (Element). val (Scope[ngmodel]);                            Scope. $digest (); $ ("#display-" +attrs.id + "span"). each (function () {if ($ (). attr ("value") = = CurrentValue ) {$ (tHis). Remove ();                        }                            }); } else {//add option to Val () and UI $ ($ (this). Children () [1]). Fadet                            O (300,1); Scope[ngmodel] = ($ (Element). val () + ";" +currentvalue). Replace (/;{ 2}/, ";").                            Replace (/^;/, "");                            $ (Element). val (Scope[ngmodel]);                            Scope. $digest (); $ ("#display-" +attrs.id). Append ("<span for= ' option-tag ' value= '" + $ (This). attr ("value")                        + "' class= ' P-option-tag ' >" +$ (This). Children () [0].innerhtml+ "</span>"); } status =!status;                    Prevent bubble}); Control background $ (this). MouseEnter (function () {$ (". My-li-container"). each (f                          Unction () {  $ (this). attr ("Style", "" ");                        });                    $ (this). attr ("style", "Background-color: #eee");                });            }); } else {$ (". option-" +attrs.id). each (function () {$ (this). MouseEnter (function () {$                        (". My-li-container"). each (function () {$ (this). attr ("Style", "");                        });                    $ (this). attr ("style", "Background-color: #eee");                });                }); Single Select, just add value and remove UL $ (Element). Click (function () {$ ("#" + att Rs.id + "-container"). attr ("style", status?                    "Display:none": "");                status =!status;                }); $ (". option-" +attrs.id). each (function () {$ (The). On (' click ', Function () {SCOPE[NGM                        Odel] = $ (this). attr ("value"); $ (Element). Val (SCOPE[ngmodel]);                        Scope. $digest ();                        Console.log (Ngmodel);                        Console.log (Element.val ());                    $ ($ ("#display-" +attrs.id). Children () [0]). HTML ($ (this). html ());                });            }); }        }    }});

100. If you see this, it shows interest in this little thing, git on it together, Custom option templates, option grouping These two features are not implemented yet. Youth, join the Army of Open source.

Custom angular directives and jquery-implemented bootstrap style data two-way binding of the single & multi-select drop-down box

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.