Coder Social home page Coder Social logo

angular-select2's Introduction

angular-select2

select2 bindings for Angular.JS

Installation

Add angular-select2 to your project:

bower install --save angular-select2

Add it to your HTML file:

<script src="bower_components/angular-select2/dist/angular-select2.min.js"></script>

Reference it as a dependency for your app module:

angular.module('myApp', ['rt.select2']);

Usage

Usage a similar to a normal select with ngOptions:

<select2 ng-model="obj.field" s2-options="val.id as val.name for val in values"></select2>

Note: using ng-options was supported until Angular 1.4 made this impossible. When upgrading to Angular.JS 1.4, be sure to replace all instances of ng-options to s2-options.

In fact, you can replace any <select> tag by a <select2> tag and it should just work.

A multi-selection works similarly: add a multiple attribute.

You can set any select2 option by passing an options object:

<select2 ng-model="obj.field" s2-options="val.id as val.name for val in values" options="{ allowClear: true }"></select2>

Async loading of data

Async-loaded data can by used by leaving out the s2-options attribute and by specifying a query function:

angular.module('myApp').controller('MyController', function ($scope) {
    $scope.queryOptions = {
        query: function (query) {
            var data = {
                results: [
                    { id: "1", text: "A" },
                    { id: "2", text: "B" }
                ]
            };

            query.callback(data);
        }
    };
});
<select2 ng-model="values.query" options="queryOptions"></select2>

Custom formatting, restrictions, tokenization, ...

This directive is just simple glue to the underlying select2.

Check the select2 documentation for an overview of the full capabilities.

Configuring global defaults

You can set a default for any option value by using select2Config:

angular.module("myApp").run(function (select2Config) {
    select2Config.minimumResultsForSearch = 7;
    select2Config.dropdownAutoWidth = true;
});

License

(The MIT License)

Copyright (C) 2013-2015 by Ruben Vermeersch <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

angular-select2's People

Contributors

dompuiu avatar kimgressens avatar punkchameleon avatar rbatllet avatar realrunner avatar rubenv avatar sbiaudet avatar toonketels avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

angular-select2's Issues

Not watching model change in multiple

Now You have code for watching of external model change:

controller.$render = function () {
    getSelection(function (selection) {
        if (isMultiple) {
            element.select2("data", selection);
        } else {
            element.select2("val", selection.id);
        }
    });
};

Problem is that it works only on strings or numbers: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

If we have multiple option turned on and make external change of model nothing happens.
Here is my workaround:

if (isMultiple) {
    scope.$watch(function () {
        return controller.$modelValue;
    }, function (newVal, oldVal) {
        if (newVal !== oldVal) {
            getSelection(function (selection) {
                if (isMultiple) {
                    element.select2("data", selection);
                } else {
                    element.select2("val", selection.id);
                }
            });
        }
    }, true);
} else {
    controller.$render = function () {
        getSelection(function (selection) {
            if (isMultiple) {
                element.select2("data", selection);
            } else {
                element.select2("val", selection.id);
            }
        });
    };
}

If is multiple then use deep watcher - if not stay with $render

EDIT:
I see that initial value for multiple is not working also - controller.$render(); in $timeout Here You have to trigger:

getSelection(function (selection) {
                    if (isMultiple) {
                        element.select2("data", selection);
                    } else {
                        element.select2("val", selection.id);
                    }
                });

How can I catch keydown event?

How can I catch keydown event, like .on("keydown", function(){})? I can catch events like select2-open, select-close but I can't catch events like keydown.
The code below works only for close event but It does not work for keydown event.

"<select2 ng-model="fmData.data.value" s2-options="option.value as option.label for option in options"
options="optionsSelect"` id="{{item.id}}-{{fmData.name}}" style="width:100%"></select2>"

            jQuery('#'+ id)
              .on("select2-close",  function(e) {
                console.log("here");
              })
             .on("keydown", function (e) {
               console.log("keydown");
             });

Filter options by value in another selectbox

I have two selectboxes and the second one filters its options depending on the value of the first selectbox. This actually works, but the console is full of "Infinite $digest Loop" errors. The reason for these errors lies on line number 160 in the file angular-select2-1.3.8.js. When I remove the $watch, the errors disappear. The selectbox still works, at least it looks so. I'm not sure if this $watch is really needed or not. Maybe someone can help me here.

Here's a Plunker: http://plnkr.co/edit/pBe8eCs0C3DxGfdgIfZx?p=preview

Uncaught ReferenceError: $ is not defined

I'm familiar with this error, it usually comes up when you try to call Jquery before it has been loaded.
I'm loading Jquery way before I even touch Select2.

Copying the example on async load data, char by char, stills yields the same error.

Any ideas on this?

Grouping not working

Now grouping is not working. Here is work around - parse all children elements.

You have to change code:

query.callback = function (data) {
        for (var i = 0; i < data.results.length; i++) {
            var result = data.results[i];
            optionItems[result.id] = result;
        }
        cb(data);
    };
queryFn(query);

To:

query.callback = function (data) {
        for (var i = 0; i < data.results.length; i++) {
            var result = data.results[i];
            if (!angular.isDefined(result.id)) {
                if (angular.isArray(result.children)) {
                    for (var ch in result.children) {
                        var child = result.children[ch];
                        optionItems[child.id] = child;
                    }
                }
            } else {
                optionItems[result.id] = result;
            }
        }
        cb(data);
    };
queryFn(query);

Update for select 4.x?

The new select2 introduces quite a few BC, among them is the deprecation of hidden field in various places. I wonder if this plugin is ready for 4.x and if not do you have any plan to support it?

Paging together with multiple selections not working

I have a select2 element that gets its data via ajax paged from the server. The select element shall allow multiple selections.
Selecting elements from page 1 works fine.
However, when selecting elements from page > 1 they appear briefly in the input box and then dissappear.
From scanning the source code I think whats happening is that a query request with search terms = "" is issued (without page field so my server returns page 1). Then the current viewValues are filtered by the result, so anything not on the first page gets ditched. This is the code block where that happens: https://github.com/rubenv/angular-select2/blob/master/src/select2.js#L199

Am I doing something wrong with my query function? Or is this a bug?

Travis CI is broken

Protractor seems to be highly unreliable when using Travis. Need to investigate why that is.

How to delay http request ?

Hi

I read the select2 documentation that there is ajax.delay options to avoid triggered request in every keystroke. How to implement it ?

Yours sincerely

virtual keyboard popup on phones

Hi,

I am following this long and old issue (select2/select2#1541) about the virtual keyboard popping up when not using minimumResultsForSearch:-1.

Is there a way we can fix this with the directive? On guy suggested to set a focus on another element onchange (which to me doesn't make sense). However maybe we can do it on the event when the options list is rendered?

Anyway, I am not sure if it has been resolved in Select2 version 4 but since this directive is not yet supporting that I was wondering if there are solutions I / we can implement.

I found one fix:

$('select').on('select2:open', function(e) {
    $('.select2-search input').prop('focus',false);
})

and will try if this works. If so, maybe it could be an option?

cheers

how about ditching bower in favour of npm

Hi,

I can already get this great directive on NPM, however, its select2 dependency still requires bower.
I would like to suggest to remove bower and add the dependency to the package.json?

TypeError: d.select2 is not a function

Hi Ruben, this might be similar to #39.

I followed your instruction and used the current version. It always brings up the same error. Do you have any clue what could cause this?

Versions:
Angular: 1.4.7
rubenv/angular-select2: 1.4.3 and 1.4.2
(with and without select2: 3.5.4, 3.5.2 and 4.0.2)

Basically the code is: angular module: 'rt.select2'
<select2 ng-model="obj.field" s2-options="val.id as val.name for val in values" options="{ allowClear: true }"></select2>

Matcher is hardcoded

Configuring a matcher like this

<select2 class="form-control" ng-model="ngModel.selectedItem" ng-options="item.id as item.text for item in items" options="{matcher: fooMatcher}" required></select2>

has no effect when using angular-select2.

The custom query implementation has the matcher logic hardcoded instead of utilizing opts.matcher.

See c7b700f:

// line 136
opts.query = function (query) {
    var values = filterValues(valuesFn(scope));
    var keys = (keyName ? sortedKeys(values) : values) || [];

    var options = [];
    for (var i = 0; i < keys.length; i++) {
        var locals = {};
        var key = i;
        if (keyName) {
            key = keys[i];
            locals[keyName] = key;
        }
        locals[valueName] = values[key];

        var value = valueFn(scope, locals);
        var label = displayFn(scope, locals) || "";

        if (label.toLowerCase().indexOf(query.term.toLowerCase()) > -1) {  // <-- here! should be "if (opts.matcher(query.term, label)) {"
            options.push({
                id: value,
                text: label,
                obj: values[key]
            });
        }
    }

    query.callback({
        results: options
    });
};

HTML5 required attribute

Hi,

I usually use this library extension in my project's forms and I want to use the HTML5 required attribute to validate if my select is fulfilled correctly. I tried putting it on the select2 tag, but didn't work as expected.

Is there support for it? If not, can I make a PR with this improvement?

Thanks for this awesome library.

Losing selection in multiple with custom query

If using multiple with custom query it's llosing selection.
in getSelection You call custom query function to fetch options. But often those option are defferent because of ajax. and earlier selected options are gone.
That's why You have to store previous selection
Change:

function getSelection(callback) {
    if (isMultiple) {
        getOptions(function (options) {
            var selection = [];
            for (var i = 0; i < options.length; i++) {
                var option = options[i];
                var viewValue = controller.$viewValue || [];
                if (viewValue.indexOf(option.id) > -1) {
                    selection.push(option);
                }
            }
            callback(selection);
        });
    } else {
        getOptions(function () {
            callback(optionItems[controller.$viewValue] || {obj: {}});
        });
    }
}

To:

var previousSelection = [];

function getSelection(callback) {
    if (isMultiple) {
        getOptions(function (options) {
            var selection = [];
            options = options.concat(previousSelection || []);
            for (var i = 0; i < options.length; i++) {
                var option = options[i];
                var viewValue = controller.$viewValue || [];
                if (viewValue.indexOf(option.id) > -1) {
                    selection.push(option);
                }
            }
            previousSelection = angular.copy(selection);
            callback(selection);
        });
    } else {
        getOptions(function () {
            callback(optionItems[controller.$viewValue] || {obj: {}});
        });
    }
}

ng-options with "orderBy" Error: [$rootScope:infdig]

Hi,

when I try something like

<select2 ng-model="form.channel"
             multiple
             data-allow-clear="true"
             data-placeholder="Channel"
             class="form-control input-sm"
             ng-options="channel._id as channel.name for channel in theChannels | orderBy:'name'">
    </select2>

the dropdown list gets sorted by "name" but in the Console I get multiple

http://errors.angularjs.org/1.3.8/$rootScope/infdig?p0=10

What am I doing wrong?

Thanks for the help

Benjamin

Add Angular 1.5.x compatibility

Please, remove the restriction about Angular 1.5.x

$ bower list

...
├─┬ angular-select2#1.5.1
│ ├── angular#1.5.6 incompatible with ~1.4.0 (1.4.11 available, latest is 1.5.7-build.4877+sha.8cd9848)
...

Using angular-select2 with ES6

Well, I'm having some troubles with using select2 in Javascript ES6.

When I try to use it, i have an error message "TypeError: element.select2 is not a function.

I have installed angular-select2 with bower, then I imported with the ES6 syntax import and then i injected it in the module.

Examples

Thanks for this awesome project!

I'm trying to implement the lazy loading options but am getting nothing going. Would you be interesting in include a repo of 'examples' to show this live in action? Could help in many other issues as well.

fix(directive): priority with value 1 blocks proper loading when inside another directive

Hello, thanks for you work, I really appreciate it!

I need to alert you for one issue founded when using this kind of priority with angular-select2.

Suppose that you want to provide a directive, with angular-select2 inside it, to handle some common stuff together (e.g.: like a search box, with some filters together, component-like search bundle), and you need to provide options for angular-select2 with a scope variable.

Due to the higher priority of angular-select2, over the wrapper directive one, which isn't even declared (to be added in the queue as it was loaded), those options declared on the scope of the wrapper directive are not available for angular-select2 (are coming undefined on line 55 (https://github.com/rubenv/angular-select2/blob/master/src/select2.js#L55).

Also, these options, if for some reason they need to be changed, it doesn't reflects on angular-select2 instance that's already running.

Plunker to the test case: https://plnkr.co/edit/XxMYjSEuoH9yImawAxhp

NgChange

Hi,

Great job! I have a question about ng-change, this was implemented?

TypeError: element.select2 is not a function

Select2 for angular with below versions
Select2 : https://github.com/rubenv/angular-select2
Angular : v1.4.9

Iam getting the below error

TypeError: element.select2 is not a function
at link.getOptions (app.js:31163)
at getSelection (app.js:31231)
at link.controller.$render (app.js:31250)
at Object.ngModelWatch (app.js:25987)
at Scope.$digest (app.js:16229)
at Scope.$apply (app.js:16501)
at bootstrapApply (app.js:1822)
Here's the fiddle:

http://jsfiddle.net/r23mjL01/1/

Directive assumes that the identity field is always called "id"

Hi,

When a datasource contains objects that dont use id as the name of the id field, the ngModel is not populated. eg

[
    { key: 1, name: 'Foo'}, 
    { key: 2, name : 'Bar' }
]

I have gotten it to work by modifying the source, but I'm not sure if my solution is the way you want to go (added an id attribute that defaults to "id", then used that value to reference the datasource objects id field )

Providing default data

I'm trying to figure out how to provide default selections when editing a form. Can someone please provide an example?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.