Giter Club home page Giter Club logo

angular-multi-select's Introduction

AngularJS MultiSelect

Pure AngularJS directive which creates a dropdown button with multiple or single selections. Doesn't require jQuery and works well with other Javascript libraries.

Screenshot

Demo & How To

Go to http://isteven.github.io/angular-multi-select

Current Version

4.0.0

Change Log

See CHANGELOG.md. For those who's upgrading from version 2.x.x, do note that this version is not backward-compatible. Please read the manual thoroughly and update your code accordingly.

Test

  • Install all the packages using npm i command
  • Run karma start command to run test cases.

Bug Reporting

Please follow these steps:

  1. READ THE MANUAL AGAIN. You might have missed something. This includes the MINIMUM ANGULARJS VERSION and the SUPPORTED BROWSERS.
  2. The next step is to search in Github's issue section first. There might already be an answer for similar issue. Do check both open and closed issues.
  3. If there's no previous issue found, then please create a new issue in https://github.com/isteven/angular-multi-select/issues.
  4. Please replicate the problem in JSFiddle or Plunker (or any other online JS collaboration tool), and include the URL in the issue you are creating.
  5. When you're done, please close the issue you've created.

Licence

Released under the MIT license:

The MIT License (MIT)

Copyright (c) 2014-2015 Ignatius Steven (https://github.com/isteven)

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-multi-select's People

Contributors

buunguyen avatar erinwu avatar filaruina avatar flextras avatar greggroth avatar hypercubed avatar isteven avatar omkarv avatar pankajparkar avatar riggs333 avatar sssats 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  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  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

angular-multi-select's Issues

Required validation

Hey, is there any "required" validation? I mean, at least 1 item must be selected

$scope.selectionMode is undefined

According documentation is "selection-mode" optional. But when I don't use it, every click in expanded list generates error message in console (Firefox "selectionMode" undefined, Chrome: cannot call toUpperCase of undefined).

This behaviour happens also on demo site.

The impact of this bug is, that selection changes aren't propagated to "button" element content.

Otherwise: Thanks for this directive!

Breaks when minified

Brakes at 'prevTabIndex is not defined at link'

Can you please add the minified version

A couple of feature requests

I have looked at a few different "multi-select" plugins that could be used on our angular website.

We are currently using the angular-ui select2 component but it isn't ideal for our needs.

I think we would change over to your library if it offered the following functionality:

  1. Hitting the select all option only chooses the records that are currently filtered.
  2. Better formatting of the selected records (a border or something) as it becomes difficult to read
  3. An easy way to remove a selected record without opening the drop down (x).

For example:

image

Error in HTML template

There is a typo in the template HTML. The "form" element is closed with yet another "form" element. It should be a closing "/form" element instead.

This gives an angular error in IE8:
Error: [$compile:tplrt] Template for directive 'multiSelect' must have exactly one root element.

Update bower.json to only include the main file

Hello,
thanks for your useful directive.
Could you change the "main" key of your bower.json into the main file of your repo ? (angular-multi-select.js).
I ask that because I use debowerify, a transformer of browserify which can import automatically bower dependencies depending of their bower.json files. But as you put several files as your main file, debowerify is unable to import your directive correctly.

To recapitulate, could you change this :

"main": [
    "angular-multi-select.js",
    "angular-multi-select.min.js",
    "angular-multi-select.css",
    "LICENSE"
  ],

into this :

"main": "angular-multi-select.js",

Thanks for your help. :)

Add a hidden select tag with the options in sync with the directive

Hello again. :D
To be more semantic and to be able to use all the form's features angular offers, it would be interesting to add a hidden<select> element alongside with the directive element. The <div> element would be in sync with the <select> one.
Select2 works that way and IMHO it's a really good thing to do.

Make the helper buttons a part of the selection for uniform experience

Currently the helper buttons like 'all' lie as a special case on the top, with the "Select" text present all the time.
It would be awesome experience if 'All' could be a part of the drop down checkbox so that user feels like selecting the all checkbox when he needs to. Also, the "Select" text should be optional and i should be able to hide it

OnBlur event not calling the scope method

In HTML


In Controller


$scope.blur = function() {
console.log( 'multi-select: on-blur' );
}

onBlur the blur() is not getting called, please take a look.

Thanks
Ajith

Sends multiple clicks on one click

When I use the selection like this:

<div ng-click="getDataByUser(selectedUserList)"
    multi-select
    input-model="userList"
    output-model="selectedUserList"
    button-label="name"
    item-label="name"
    tick-property="ticked"
    max-labels="2">
</div>

The getDataByUser function is called twice for each click.
Is this a problem on my end or is it something I can turn off in the multiselect code?

Checkbox feature

Is it possible to convert the tick marks to checkboxes, so that it is very intuitive to user? Also, the click on the arrows/checkboxes should be handled. Currently only click action on the text is supported.

on-blur not called

on-blur appears to be called on clicking on an item after multi-select is open but it does not get called when clicking mouse outside multi-select (causing multi-select to close).
Here is an example of the code used:


Hard coded buttons for select 'all', 'none', 'reset' - allowing new buttons to be inserted.

Hi,

Looking at the code, currently the buttons for selection are relatively hard-coded. I want to insert a selected 'filtered' button, but it required hard edits into 'case' statements, and so didn't lend itself to an add-on js file.

I added the button, but was wondering if the ease of adding / changing the function / text of buttons will be easier in the new version you are working on?

Styling Issue for Disabled Item

Having an issue with styling the labels to items when they are disabled. I've tried to change the styling in the css file (the ".multiSelect .disabled label input:hover ~ span" line) but it doesn't seem to effect anything. Any suggestions on changing it to a little gray for any labels that are disabled or unchecked? Thanks.

Support for label templates

Hi! In our current project we use the multiselect to select from a list of components. One of the requirements is to also show the status of a component. Since the status is dynamic and based on properties of the component we decided to change the library to add support for templates.

We did a simple implementation by changing the following line:

<span ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>

to

<span ng-if="itemLabelTemplate === undefined" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>
<span ng-if="itemLabelTemplate !== undefined" ng-include="itemLabelTemplate"></span>

and added itemLabelTemplate to the scope.

Would it be an idea to add this to the project?

Controller updates to input-model not reflected in view

If I make a change to the input-model scope variable from the controller, I would expect the change to be reflected in the view, but in my test cases it is not.

By adding a third parameter with a value of true to the $watch at line 405 this issue appears to be resolved.

// Watch for changes in input model (allow dynamic input)
$scope.$watch( 'inputModel' , function( oldVal, newVal ) {
if ( $scope.inputModel !== 'undefined' ) {
validateProperties( $scope.itemLabel.split( ' ' ), $scope.inputModel );
validateProperties( new Array( $scope.tickProperty ), $scope.inputModel );
}
$scope.backUp = angular.copy( $scope.inputModel );
$scope.refreshSelectedItems();
},true);

Feature Request: Possibility to have no labels shown at all (max-labels = 0)

Hi,

First of all, thanks for the amazing plugin, just started using it after some pain trying some others and it works perfectly for us.
I would like to request one (probably) simple feature.
If I use max-labels="0" it would be displayed (Total: N) once I select one or more itens.
In my use case, the dropdown would show:
None selected
(Total: 1)
(Total: 3)
etc...

Thanks a lot!

PS: I'll take a look if that's so simple, if so, probably will submit a pull request whenever possible. =)

Limiting Number of Selections

This would be really helpful if we have an option to limit the maximum allowed selections. So that the user will be restricted to exceed this max limit. Optionally we could have another Boolean options to ask the user whether to deselect some other selected item on exceeding this limit. Also ideally if we could have a way to specify this deselection criteria (Say we have options with models including a "price" attribute. On exceeding maximum number of allowed selections, the user would have a way to specify to deselect the most pricey element among the previously selected elements in order to allow current selection).

AJAX call

I have a case where I may have thousands of possible options and I want to avoid having to retrieve all the possible options from my API before we can use the dropdown.

Is there a way to retrieve the list dynamically using asynchronous ajax calls to return the options based on a minimum character input from the user ?
Basically, this feature is available on the "select2" plugin using the "ajax" or "query" parameters (http://ivaynberg.github.io/select2/). I was using this plugin which is awesome but doesn't have any checkbox multi-select feature. I'm looking into using yours but this is the only thing where I'm afraid I'll get stuck having problems.

Scrolling long lists

I'm considering using this in a project I'm working on. However some of the lists in my application can be rather long, maybe 100 items or more. I don't see any examples with long lists so I wanted to ask if you supported scrolling once the list of items got to a certain size.

Blur event fires at the wrong time?

When I open the multi-select control and tick or untick an item, the blur event is immediately fired. When I then tick or untick other elements and click outside the multi-select control (so it closes) the blur event is NOT fired.
This would make it impossible to correctly act on changes after the user has closed the multi-select control by clicking some other area.

Ability to fix the width of component

I need one multiple select input with fixed width, so that these inputs won't update its width by the count of selected item. At present, there is a property to set max count of selected items, but there is no way to restrict the max width of input.

Problem if the checkboxLayer is too close to right margin

I've got a problem with your component. My item list contains items with long lables and, if the widget is to close to right screen border, the list goes out of sight. How to tell to the widget that if it goes out of sight it needs to set its css property right: 0px; (which I've found that makes the widget behave correctly)?
Thanks

inputModelIndex is undefined

Hi Steven,

I found and implemented the multi-select earlier this week and I absolutely love it. So thank you for this! It works just fine, but Firebug keeps catching an error whenever I click on an item. It doesn't seem to break anything, so this issue is probably as low-priority as they can get, but I figured I'd report it just in case.

The error message reads as follows:

TypeError: $scope.inputModel[inputModelIndex] is undefined

Or to be more precise:

Error: $scope.inputModel[inputModelIndex] is undefined
.link/$scope.syncItems@http://localhost:8080/my-project/resources/js/angular-multi-select.js:384:21 bb.prototype.functionCall/<@http://localhost:8080/my-project/resources/js/angular.min.js:174:178 jc[c]</<.compile/</</<@http://localhost:8080/my-project/resources/js/angular.min.js:191:167 Yd/this.$get</h.prototype.$eval@http://localhost:8080/my-project/resources/js/angular.min.js:111:110 Yd/this.$get</h.prototype.$apply@http://localhost:8080/my-project/resources/js/angular.min.js:111:375 jc[c]</<.compile/</<@http://localhost:8080/my-project/resources/js/angular.min.js:191:147 ne/c/<@http://localhost:8080/my-project/resources/js/angular.min.js:31:223 q@http://localhost:8080/my-project/resources/js/angular.min.js:7:278 ne/c@http://localhost:8080/my-project/resources/js/angular.min.js:31:207

The version of AngularJS I'm using is v1.2.17.

On first glance, it appears inputModelIndex remains undefined even after line 383 is executed:
inputModelIndex = $scope.filteredModel[ index ][ $scope.indexProperty ];

And then in line 384, it tries to use that undefined var and the error pops.

My HTML:

<multi-select input-model="myInputObject.items"
output-model="myOutputObject.selectedItems"
button-label="name"
item-label="name"
tick-property="isSelected"
orientation="horizontal"
helper-elements="all none filter">
</multi-select>

Leon

scroll bar with many items

Great widget! I'm glad I stumbled upon it.

Is there a way to control the size of the drop-down and give it a scrollbar?

Internationalization of all the labels elements

Hi,
it would be great to be able to change the default labels text such as : 'All, None, Reset, Select, Filter, Clear, None Selected...'.
I have to develop in french and for now if I want to change the text I have to edit the source.

Two ideas :

  • Being able to modify each text by passing an option such as : textOptions = { all: 'All', none: 'None', select: 'Select'.....}
  • Create a 'lang' or 'i18n' folder with files in several languages that we can import before the angular-multi-select.js file as default values. For example : angular-multi-select-fr-FR.js and angular-multi-select-en-US.js which contains only the textOptions object translated, in my case : textOptions = { all: 'Tous', none: 'Aucun', select: 'Sélectionner'.....}. We can also imagine an option in the api to change the langage at runtime for international applications.

What do you think ? :)

How to achieve Fix width and Below mentioned behavior.

  1. How to achieve fix width( in the declaration tag for ex. width = 200px) of dropdown no matter what is selected. If selected options text width is big, it will show ... after truncated text. If it is small it would show empty space.
  2. A Dropdown with multiple select option where at least one option must be selected. (A kind of Mix of Radio and Check-box Behavior).

Error in documentation

In your documentation in the Usage section you have used multi-select as an attribute which caused my code to break:

<multi-select
    multi-select 
    input-model="modernWebBrowsers"    
    button-label="icon name"
    item-label="icon name maker"
    tick-property="ticked"
>
</multi-select>

should be

<multi-select
    input-model="modernWebBrowsers"    
    button-label="icon name"
    item-label="icon name maker"
    tick-property="ticked">
</multi-select>

need for scrolling

Hi Isteven,

I have a dropdown menu that has many values. It's going below the screen. How do I enable scrollbar?

Thanks,

Neil

can't get selected value using single selection mode

Hi,

I made a dropdown using your example on number 5, Single selection mode with no helper elements, just like a normal drop down menu.

I can't figure out which value will contain the selected menu. I tried $scope.name but it was undefined. I tried output-model but it's for multiple selections.

Any help would be greatly appreciated!

thanks

i'm using this directive in my work now

while editing default select value in reference table

while editing default select element in reference table

two table
1.user
2.country -- is master table

user table refer the country

while editing the user table how to view the selected existing country(because country is another table)

Feature request - output-model populate with desired properties

First of all - thanks for great ui component, this is probably best multi-select component I've ever seen (been developing for 15+ years).

I was wondering if it would be possible to add output-model-property that would determine how output-model gets populated. Currently, whole objects get cloned into output-model, i.e:

$scope.inputList = [
    { id: 0,    firstName: "Peter",    lastName: "Parker",     pic: "<img src='[...]/peter.png  class='multiSelect'  />",   selected: false },
    { id: 1,    firstName: "Mary",     lastName: "Jane",       pic: "<img src='[...]/mary.png   class='multiSelect'  />",   selected: false },
    { id: 2,    firstName: "Bruce",    lastName: "Wayne",      pic: "<img src='[...]/bruce.png  class='multiSelect'  />",   selected: true  },
    { id: 3,    firstName: "David",    lastName: "Banner",     pic: "<img src='[...]/david.png  class='multiSelect'  />",   selected: false },
    { id: 4,    firstName: "Natalia",  lastName: "Romanova",   pic: "<img src='[...]/natalia.png class='multiSelect' />",   selected: false },
    { id: 5,    firstName: "Clark",    lastName: "Kent",       pic: "<img src='[...]/clark.png  class='multiSelect'  />",   selected: true  }
];

$scope.outputList = [
    { id: 2,     firstName: "Bruce",    lastName: "Wayne",      pic: "<img src='[...]/bruce.png  class='multiSelect'  />",   selected: true  },
    { id: 5,     firstName: "Clark",    lastName: "Kent",       pic: "<img src='[...]/clark.png  class='multiSelect'  />",   selected: true  }  
];

What I would like is if it was possible to specify output-model-property="id" and then output list would be:

$scope.outputList = [
    2,
    5
];

Reason being - most dropdowns/comboboxes are bound to some unique IDs, and something like this would allow to avoid using angular.forEach(param, function(value,key) { ... }) every time you need to fetch what's selected.

This would allow for lots of cool stuff, like:

If you want to preserve selected states across pages, you can simply pass selected ids in querystring (like ?States=JSON.stringify($scope.outputList))
You can bind $scope.outputList to and use that as part of the

...

For some crazy scenarios it would be great if this was possible to do with multiple properties (like item-label="icon name maker", although this would change format from [2,5] to [{id:2,name:Do},{id:5,name:La}]), but even one property for start would be great to save us from doing angular.forEach every time we need to get selected values.

Regardless of what you decide to do about this - thanks again for great component.

problem using selection-mode="single" in Chrome Version 35.0.1916.153 m

Hi!

I get this error when using selection-mode="single" in Chrome.

TypeError: Cannot read property 'previousSibling' of null
at Scope.link.$scope.toggleCheckboxes (http://localhost:3000/bower_components/isteven-angular-multiselect/angular-multi-select.js:553:34)
at Parser.functionCall (http://localhost:3000/bower_components/angular/angular.js:10735:21)
at Parser.statements (http://localhost:3000/bower_components/angular/angular.js:10513:29)
at http://localhost:3000/bower_components/angular/angular.js:18942:17
at Scope.$get.Scope.$eval (http://localhost:3000/bower_components/angular/angular.js:12595:28)
at Scope.$get.Scope.$apply (http://localhost:3000/bower_components/angular/angular.js:12693:23)
at HTMLButtonElement. (http://localhost:3000/bower_components/angular/angular.js:18941:21)
at HTMLButtonElement.jQuery.event.dispatch (http://localhost:3000/bower_components/jquery/jquery.js:3074:9)
at HTMLButtonElement.jQuery.event.add.elemData.handle (http://localhost:3000/bower_components/jquery/jquery.js:2750:46)

Using Firefox it works just fine.
Would appreciate if you have time to look into this, because I really like your directive and need this functionality pretty soon.

BR
Stefan

"Total" text should be configurable

It would be nice if the "(Total: X)" text on the multiselect would be configurable. This would allow localization (or other customization) for the component. Of course, it would make sense to extend this configurability to the helper-elements as well.

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.