diff --git a/Apollo/assets/js/app.js b/Apollo/assets/js/app.js index 1ba34fe9..95138825 100755 --- a/Apollo/assets/js/app.js +++ b/Apollo/assets/js/app.js @@ -19,5 +19,6 @@ angular.module("clip-two", [ 'ipCookie', 'angularUtils.directives.dirPagination', 'htmlToPdfSave', + 'ui.select2', ]); diff --git a/Apollo/assets/views/status-update/answer_booklet_status.html b/Apollo/assets/views/status-update/answer_booklet_status.html index c2fb96d2..b4c323fd 100755 --- a/Apollo/assets/views/status-update/answer_booklet_status.html +++ b/Apollo/assets/views/status-update/answer_booklet_status.html @@ -19,7 +19,7 @@
-
+
@@ -32,18 +32,18 @@
-
+
-
-
+
diff --git a/Apollo/assets/views/status-update/application_status.html b/Apollo/assets/views/status-update/application_status.html index a664f900..b4a5a6f4 100755 --- a/Apollo/assets/views/status-update/application_status.html +++ b/Apollo/assets/views/status-update/application_status.html @@ -19,7 +19,7 @@
-
+
@@ -32,18 +32,18 @@
-
+
-
-
+
diff --git a/Apollo/assets/views/status-update/certification_status.html b/Apollo/assets/views/status-update/certification_status.html index c98b1bf6..ff296fb4 100755 --- a/Apollo/assets/views/status-update/certification_status.html +++ b/Apollo/assets/views/status-update/certification_status.html @@ -37,7 +37,7 @@ Course - diff --git a/Apollo/assets/views/status-update/fees_status.html b/Apollo/assets/views/status-update/fees_status.html index a16eb4fd..a7b19941 100755 --- a/Apollo/assets/views/status-update/fees_status.html +++ b/Apollo/assets/views/status-update/fees_status.html @@ -81,7 +81,7 @@ - + diff --git a/Apollo/assets/views/student/student_details.html b/Apollo/assets/views/student/student_details.html index 68e861d1..d351cec7 100755 --- a/Apollo/assets/views/student/student_details.html +++ b/Apollo/assets/views/student/student_details.html @@ -96,7 +96,7 @@ Course - diff --git a/Apollo/assets/views/student/student_details_SuperAdmin.html b/Apollo/assets/views/student/student_details_SuperAdmin.html index 265ebb3a..5a1543c0 100644 --- a/Apollo/assets/views/student/student_details_SuperAdmin.html +++ b/Apollo/assets/views/student/student_details_SuperAdmin.html @@ -137,7 +137,7 @@ Course - diff --git a/Apollo/bower_components/select2/dist/css/select2.css b/Apollo/bower_components/select2/dist/css/select2.css index c69b7273..9218a6ca 100755 --- a/Apollo/bower_components/select2/dist/css/select2.css +++ b/Apollo/bower_components/select2/dist/css/select2.css @@ -8,7 +8,7 @@ box-sizing: border-box; cursor: pointer; display: block; - height: 28px; + height: 34px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--single .select2-selection__rendered { @@ -115,7 +115,7 @@ .select2-container--default .select2-selection--single { background-color: #fff; border: 1px solid #aaa; - border-radius: 4px; } + border-radius: 0px; } .select2-container--default .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } diff --git a/Apollo/bower_components/ui-select2-master/.bowerrc b/Apollo/bower_components/ui-select2-master/.bowerrc new file mode 100644 index 00000000..deceb62e --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} \ No newline at end of file diff --git a/Apollo/bower_components/ui-select2-master/.gitignore b/Apollo/bower_components/ui-select2-master/.gitignore new file mode 100644 index 00000000..d8d73943 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/.gitignore @@ -0,0 +1,3 @@ +node_modules +bower_components +demo/bower_components \ No newline at end of file diff --git a/Apollo/bower_components/ui-select2-master/.jshintrc b/Apollo/bower_components/ui-select2-master/.jshintrc new file mode 100644 index 00000000..1b83bfb4 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/.jshintrc @@ -0,0 +1,11 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "sub": true, + "boss": true, + "eqnull": true +} diff --git a/Apollo/bower_components/ui-select2-master/.travis.yml b/Apollo/bower_components/ui-select2-master/.travis.yml new file mode 100644 index 00000000..ffa35634 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/.travis.yml @@ -0,0 +1,13 @@ + language: node_js + node_js: + - "0.8" + - "0.10" + + before_install: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - npm install -g karma bower grunt-cli + - bower install + - npm install + + script: "grunt" diff --git a/Apollo/bower_components/ui-select2-master/CONTRIBUTING.md b/Apollo/bower_components/ui-select2-master/CONTRIBUTING.md new file mode 100644 index 00000000..cb66f02b --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/CONTRIBUTING.md @@ -0,0 +1,8 @@ +CONTRIBUTING +============ + +* Open a [Pull Request (PR)](https://github.com/angular-ui/ui-select2/pull/new/master) +* Make sure your PR is on a **new branch** you created off of the latest version of master +* Do **not** open a PR from your master branch +* Open a PR to start a discussion even if the code isn't finished (easier to collect feedback this way) +* Make sure all previous tests pass and add new tests for added behaviors diff --git a/Apollo/bower_components/ui-select2-master/Gruntfile.js b/Apollo/bower_components/ui-select2-master/Gruntfile.js new file mode 100644 index 00000000..f2148422 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/Gruntfile.js @@ -0,0 +1,59 @@ +module.exports = function (grunt) { + 'use strict'; + + var initConfig; + + // Loading external tasks + require('load-grunt-tasks')(grunt); + + // Project configuration. + initConfig = { + bower: 'bower_components', + pkg: grunt.file.readJSON('package.json'), + watch: { + test: { + // Lint & run unit tests in Karma + // Just running `$ grunt watch` will only lint your code; to run tests + // on watch, use `$ grunt watch:karma` to start a Karma server first + files: ['src/select2.js', 'test/select2Spec.js'], + tasks: ['jshint', 'karma:unit:run'] + } + }, + karma: { + options: { + configFile: 'test/karma.conf.js', + browsers: ['Firefox', 'PhantomJS'] + }, + unit: { + singleRun: true + }, + watch: { + autoWatch: true + }, + server: { + background: true + } + }, + jshint: { + all:[ + 'gruntFile.js', + 'src/**/*.js', + 'test/**/*Spec.js' + ], + options: { + jshintrc: '.jshintrc' + } + }, + changelog: { + options: { + dest: 'CHANGELOG.md' + } + } + }; + + // Register tasks + grunt.registerTask('default', ['jshint', 'karma:unit']); + grunt.registerTask('watch', ['jshint', 'karma:watch']); + + grunt.initConfig(initConfig); +}; diff --git a/Apollo/bower_components/ui-select2-master/LICENSE b/Apollo/bower_components/ui-select2-master/LICENSE new file mode 100644 index 00000000..dfc5e0ca --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com + +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. diff --git a/Apollo/bower_components/ui-select2-master/README.md b/Apollo/bower_components/ui-select2-master/README.md new file mode 100644 index 00000000..7b32cb75 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/README.md @@ -0,0 +1,183 @@ +ui-select2 (deprecated) [![Build Status](https://travis-ci.org/angular-ui/ui-select2.png)](https://travis-ci.org/angular-ui/ui-select2) +======================== + +# Annoucement + + +This **directive is now obsolete**. A new initiative, more active, and 100% angular is available at https://github.com/angular-ui/ui-select. + +As development slowed down on ui-select2, it is getting unlikely that bugs will be fixed. So the new alternative should be used as soon as possible. + +# Description + +This directive allows you to enhance your select elements with behaviour from the [select2](http://ivaynberg.github.io/select2/) library. + +# Requirements + +- [AngularJS](http://angularjs.org/) +- [JQuery](http://jquery.com/) +- [Select2](http://ivaynberg.github.io/select2/) + +## Setup + +1. Install **Karma**, **Grunt** and **Bower** + `$ npm install -g karma grunt-cli bower` +2. Install development dependencies + `$ npm install` +3. Install components + `$ bower install` +4. ??? +5. Profit! + +## Testing + +We use [Grunt](http://gruntjs.com/) to check for JavaScript syntax errors and execute all unit tests. To run Grunt, simply execute: + +`$ grunt` + +This will lint and test the code, then exit. To have Grunt stay open and automatically lint and test your files whenever you make a code change, use: + +`$ grunt karma:server watch` + +This will start a Karma server in the background and run unit tests in Firefox and PhantomJS whenever the source code or spec file is saved. + +# Usage + +We use [bower](https://github.com/bower/bower) for dependency management. Install AngularUI Select2 into your project by running the command + +`$ bower install angular-ui-select2` + +If you use a `bower.json` file in your project, you can have Bower save ui-select2 as a dependency by passing the `--save` or `--save-dev` flag with the above command. + +This will copy the ui-select2 files into your `bower_components` folder, along with its dependencies. Load the script files in your application: +```html + + + + + +``` + +(Note that `jquery` must be loaded before `angular` so that it doesn't use `jqLite` internally) + + +Add the select2 module as a dependency to your application module: + +```javascript +var myAppModule = angular.module('MyApp', ['ui.select2']); +``` + +Apply the directive to your form elements: + +```html + +``` + +## Options + +All the select2 options can be passed through the directive. You can read more about the supported list of options and what they do on the [Select2 Documentation Page](http://ivaynberg.github.com/select2/) + +```javascript +myAppModule.controller('MyController', function($scope) { + $scope.select2Options = { + allowClear:true + }; +}); +``` + +```html + +``` + +Some times it may make sense to specify the options in the template file. + +```html + +``` + +To define global defaults, you can configure the `uiSelect2Config` injectable: + +```javascript +myAppModule.run(['uiSelect2Config', function(uiSelect2Config) { + uiSelect2Config.placeholder = "Placeholder text"; +}]); +``` + +## Working with ng-model + +The ui-select2 directive plays nicely with ng-model and validation directives such as ng-required. + +If you add the ng-model directive to same the element as ui-select2 then the picked option is automatically synchronized with the model value. + +## Working with dynamic options +`ui-select2` is incompatible with ` + + + +``` + +## Working with placeholder text +In order to properly support the Select2 placeholder, create an empty ` + + + + +``` + +## ng-required directive + +If you apply the required directive to element then the form element is invalid until an option is selected. + +Note: Remember that the ng-required directive must be explicitly set, i.e. to "true". This is especially true on divs: + +```html + +``` + +## Using simple tagging mode + +When AngularJS View-Model tags are stored as a list of strings, setting +the ui-select2 specific option `simple_tags` will allow to keep the model +as a list of strings, and not convert it into a list of Select2 tag objects. + +```html + +``` + +```javascript +myAppModule.controller('MyController', function($scope) { + $scope.list_of_string = ['tag1', 'tag2'] + $scope.select2Options = { + 'multiple': true, + 'simple_tags': true, + 'tags': ['tag1', 'tag2', 'tag3', 'tag4'] // Can be empty list. + }; +}); +``` diff --git a/Apollo/bower_components/ui-select2-master/bower.json b/Apollo/bower_components/ui-select2-master/bower.json new file mode 100644 index 00000000..2cf5041e --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/bower.json @@ -0,0 +1,20 @@ +{ + "author": "AngularUI", + "name": "angular-ui-select2", + "version": "0.0.5", + "homepage": "http://angular-ui.github.com", + "keywords": [ + "angular", + "angularui", + "select2" + ], + "main": "./src/select2.js", + "dependencies": { + "angular": ">=1.2.0", + "select2": "~3.4", + "jquery": ">=1.6.4" + }, + "devDependencies": { + "angular-mocks": ">=1.0.2" + } +} diff --git a/Apollo/bower_components/ui-select2-master/demo/app.js b/Apollo/bower_components/ui-select2-master/demo/app.js new file mode 100644 index 00000000..7530204c --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/demo/app.js @@ -0,0 +1,114 @@ + +var app = angular.module('angular-ui-select2-demo', ['ui.select2']); + +app.controller('MainCtrl', function ($scope, $element) { + + var states = [ + { text: 'Alaskan/Hawaiian Time Zone', children: [ + { id: 'AK', text: 'Alaska' }, + { id: 'HI', text: 'Hawaii' } + ]}, + { text: 'Pacific Time Zone', children: [ + { id: 'CA', text: 'California' }, + { id: 'NV', text: 'Nevada' }, + { id: 'OR', text: 'Oregon' }, + { id: 'WA', text: 'Washington' } + ]}, + { text: 'Mountain Time Zone', children: [ + { id: 'AZ', text: 'Arizona' }, + { id: 'CO', text: 'Colorado' }, + { id: 'ID', text: 'Idaho' }, + { id: 'MT', text: 'Montana' }, + { id: 'NE', text: 'Nebraska' }, + { id: 'NM', text: 'New Mexico' }, + { id: 'ND', text: 'North Dakota' }, + { id: 'UT', text: 'Utah' }, + { id: 'WY', text: 'Wyoming' } + ]}, + { text: 'Central Time Zone', children: [ + { id: 'AL', text: 'Alabama' }, + { id: 'AR', text: 'Arkansas' }, + { id: 'IL', text: 'Illinois' }, + { id: 'IA', text: 'Iowa' }, + { id: 'KS', text: 'Kansas' }, + { id: 'KY', text: 'Kentucky' }, + { id: 'LA', text: 'Louisiana' }, + { id: 'MN', text: 'Minnesota' }, + { id: 'MS', text: 'Mississippi' }, + { id: 'MO', text: 'Missouri' }, + { id: 'OK', text: 'Oklahoma' }, + { id: 'SD', text: 'South Dakota' }, + { id: 'TX', text: 'Texas' }, + { id: 'TN', text: 'Tennessee' }, + { id: 'WI', text: 'Wisconsin' } + ]}, + { text: 'Eastern Time Zone', children: [ + { id: 'CT', text: 'Connecticut' }, + { id: 'DE', text: 'Delaware' }, + { id: 'FL', text: 'Florida' }, + { id: 'GA', text: 'Georgia' }, + { id: 'IN', text: 'Indiana' }, + { id: 'ME', text: 'Maine' }, + { id: 'MD', text: 'Maryland' }, + { id: 'MA', text: 'Massachusetts' }, + { id: 'MI', text: 'Michigan' }, + { id: 'NH', text: 'New Hampshire' }, + { id: 'NJ', text: 'New Jersey' }, + { id: 'NY', text: 'New York' }, + { id: 'NC', text: 'North Carolina' }, + { id: 'OH', text: 'Ohio' }, + { id: 'PA', text: 'Pennsylvania' }, + { id: 'RI', text: 'Rhode Island' }, + { id: 'SC', text: 'South Carolina' }, + { id: 'VT', text: 'Vermont' }, + { id: 'VA', text: 'Virginia' }, + { id: 'WV', text: 'West Virginia' } + ]} + ]; + + function findState(id) { + for (var i=0; i=1.2.0", + "select2": "~3.4", + "jquery": ">=1.6.4", + "bootstrap": "~3.0.3", + "angular-ui-select2": "~0.0.5" + } +} diff --git a/Apollo/bower_components/ui-select2-master/demo/index.html b/Apollo/bower_components/ui-select2-master/demo/index.html new file mode 100644 index 00000000..c7145a92 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/demo/index.html @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + +
+ +
+

The Basics

+
+
+ + +
+
+

Value

+
{{ basicsValue }}
+
+
+
+ +
+

Multi-Value

+
+
+ + +
+
+

Value

+
{{ multiValue }}
+
+
+
+
+ + +
+
+

Config

+
{
+    multiple: true,
+    query: function (query) {
+      query.callback({ results: states });
+    },
+    initSelection: function(element, callback) {
+      var val = $(element).select2('val'),
+        results = [];
+      for (var i=0; i<val.length; i++) {
+        results.push(findState(val[i]));
+      }
+      callback(results);
+    }
+  }
+

Value

+
{{ multi2Value }}
+
+
+
+ +
+

Placeholders

+
+
+ + +
+
+

Value

+
{{ placeholdersValue }}
+
+
+
+
+ + +
+
+

Config

+
{{ placeholders }}
+

Value

+
{{ placeholdersMultiValue }}
+
+
+
+ +
+

Array Data

+
+
+ + +
+
+

Config

+
{{ array }}
+

Value

+
{{ arrayValue }}
+
+
+
+
+ + +
+
+

Config

+
{
+    query: function (query) {
+      query.callback({ results: states });
+    },
+    initSelection: function(element, callback) {
+      var val = $(element).select2('val');
+      return callback(findState(val));
+    }
+  }
+

Value

+
{{ arrayAsyncValue }}
+
+
+
+ +
+ + diff --git a/Apollo/bower_components/ui-select2-master/docs/index.html b/Apollo/bower_components/ui-select2-master/docs/index.html new file mode 100644 index 00000000..ff373e78 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/docs/index.html @@ -0,0 +1,47 @@ +
+ +
+
+

Demo

+
+

Value is: {{select2}} (choose second)

+ +
+ +
+

Value is: {{select2multiple}} (choose second)

+ +
+
+
+

Options

+

You can pass an object to Select2 as the expression: ui-select2="{allowClear:true}" that will be passed directly to $.fn.select2(). You can read more about the supported list of options and what they do on the Select2 Documentation Page. AngularUI will leverage properties passed to Select2 for any complex behavior, there are no parameters necessary for that are specific to AngularUI.

+
+
+

ui-select2 is incompatible with <select ng-options>. For the best results use <option ng-repeat> instead

+

In order to properly support the Select2 placeholder, create an empty <option> tag at the top of the <select> and either set a data-placeholder on the select element or pass a placeholder option to Select2.

+ +

How?

+
+<p>Value is: {{select2}} <a ng-click="select2='two'">(choose second)</a></p>
+<select ui-select2 ng-model="select2">
+<option value="">Pick a number</option>
+<option value="one">First</option>
+<option value="two">Second</option>
+<option value="three">Third</option>
+</select>
+
+

Or try playing around with this sandbox demo to see how AJAX works

+
\ No newline at end of file diff --git a/Apollo/bower_components/ui-select2-master/docs/styles.css b/Apollo/bower_components/ui-select2-master/docs/styles.css new file mode 100644 index 00000000..08611a47 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/docs/styles.css @@ -0,0 +1,4 @@ + +#directives-select2 select { + width: 200px; +} \ No newline at end of file diff --git a/Apollo/bower_components/ui-select2-master/package.json b/Apollo/bower_components/ui-select2-master/package.json new file mode 100644 index 00000000..9b831360 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/package.json @@ -0,0 +1,30 @@ +{ + "author": "https://github.com/angular-ui/ui-select2/graphs/contributors", + "name": "angular-ui-select2", + "keywords": [ + "angular", + "angularui", + "select2" + ], + "description": "AngularUI - The companion suite for AngularJS", + "version": "0.0.5", + "homepage": "http://angular-ui.github.com", + "repository": { + "type": "git", + "url": "git://github.com/angular-ui/ui-select2.git" + }, + "engines": { + "node": ">= 0.8.4" + }, + "dependencies": {}, + "devDependencies": { + "async": "0.1.x", + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.6.4", + "grunt-contrib-watch": "~0.5.3", + "grunt-karma": "~0.6.2", + "karma": "~0.10.2", + "grunt-conventional-changelog": "~1.0.0", + "load-grunt-tasks": "~0.2.0" + } +} diff --git a/Apollo/bower_components/ui-select2-master/src/select2.js b/Apollo/bower_components/ui-select2-master/src/select2.js new file mode 100644 index 00000000..c3b99ae9 --- /dev/null +++ b/Apollo/bower_components/ui-select2-master/src/select2.js @@ -0,0 +1,238 @@ +/** + * Enhanced Select2 Dropmenus + * + * @AJAX Mode - When in this mode, your value will be an object (or array of objects) of the data used by Select2 + * This change is so that you do not have to do an additional query yourself on top of Select2's own query + * @params [options] {object} The configuration options passed to $.fn.select2(). Refer to the documentation + */ +angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelect2', ['uiSelect2Config', '$timeout', function (uiSelect2Config, $timeout) { + var options = {}; + if (uiSelect2Config) { + angular.extend(options, uiSelect2Config); + } + return { + require: 'ngModel', + priority: 1, + compile: function (tElm, tAttrs) { + var watch, + repeatOption, + repeatAttr, + isSelect = tElm.is('select'), + isMultiple = angular.isDefined(tAttrs.multiple); + + // Enable watching of the options dataset if in use + if (tElm.is('select')) { + repeatOption = tElm.find( 'optgroup[ng-repeat], optgroup[data-ng-repeat], option[ng-repeat], option[data-ng-repeat]'); + + if (repeatOption.length) { + repeatAttr = repeatOption.attr('ng-repeat') || repeatOption.attr('data-ng-repeat'); + watch = jQuery.trim(repeatAttr.split('|')[0]).split(' ').pop(); + } + } + + return function (scope, elm, attrs, controller) { + // instance-specific options + var opts = angular.extend({}, options, scope.$eval(attrs.uiSelect2)); + + /* + Convert from Select2 view-model to Angular view-model. + */ + var convertToAngularModel = function(select2_data) { + var model; + if (opts.simple_tags) { + model = []; + angular.forEach(select2_data, function(value, index) { + model.push(value.id); + }); + } else { + model = select2_data; + } + return model; + }; + + /* + Convert from Angular view-model to Select2 view-model. + */ + var convertToSelect2Model = function(angular_data) { + var model = []; + if (!angular_data) { + return model; + } + + if (opts.simple_tags) { + model = []; + angular.forEach( + angular_data, + function(value, index) { + model.push({'id': value, 'text': value}); + }); + } else { + model = angular_data; + } + return model; + }; + + if (isSelect) { + // Use element', function () { + describe('compiling this directive', function () { + it('should throw an error if we have no model defined', function () { + expect(function(){ + compile(''); + }).toThrow(); + }); + it('should create proper DOM structure', function () { + var element = compile(''); + expect(element.siblings().is('div.select2-container')).toBe(true); + }); + it('should not modify the model if there is no initial value', function(){ + //TODO + }); + }); + describe('when model is changed programmatically', function(){ + describe('for single select', function(){ + it('should set select2 to the value', function(){ + scope.foo = 'First'; + var element = compile(''); + expect(element.select2('val')).toBe('First'); + scope.$apply('foo = "Second"'); + expect(element.select2('val')).toBe('Second'); + }); + it('should handle falsey values', function(){ + scope.foo = 'First'; + var element = compile(''); + expect(element.select2('val')).toBe('First'); + scope.$apply('foo = false'); + expect(element.select2('val')).toBe(null); + scope.$apply('foo = "Second"'); + scope.$apply('foo = null'); + expect(element.select2('val')).toBe(null); + scope.$apply('foo = "Second"'); + scope.$apply('foo = undefined'); + expect(element.select2('val')).toBe(null); + }); + }); + describe('for multiple select', function(){ + it('should set select2 to multiple value', function(){ + scope.foo = ['First']; + var element = compile(''); + expect(element.select2('val')).toEqual(['First']); + scope.$apply('foo = ["Second"]'); + expect(element.select2('val')).toEqual(['Second']); + scope.$apply('foo = ["Second","Third"]'); + expect(element.select2('val')).toEqual(['Second','Third']); + }); + it('should handle falsey values', function(){ + scope.foo = ['First']; + var element = compile(''); + expect(element.val()).toEqual(['First']); + scope.$apply('foo = ["Second"]'); + scope.$apply('foo = false'); + expect(element.select2('val')).toEqual([]); + scope.$apply('foo = ["Second"]'); + scope.$apply('foo = null'); + expect(element.select2('val')).toEqual([]); + scope.$apply('foo = ["Second"]'); + scope.$apply('foo = undefined'); + expect(element.select2('val')).toEqual([]); + }); + }); + }); + it('should observe the disabled attribute', function () { + var element = compile(''); + expect(element.siblings().hasClass('select2-container-disabled')).toBe(false); + scope.$apply('disabled = true'); + expect(element.siblings().hasClass('select2-container-disabled')).toBe(true); + scope.$apply('disabled = false'); + expect(element.siblings().hasClass('select2-container-disabled')).toBe(false); + }); + it('should observe the multiple attribute', function () { + var element = $compile('')(scope); + + expect(element.siblings().hasClass('select2-container-multi')).toBe(false); + scope.$apply('multiple = true'); + expect(element.siblings().hasClass('select2-container-multi')).toBe(true); + scope.$apply('multiple = false'); + expect(element.siblings().hasClass('select2-container-multi')).toBe(false); + }); + it('should observe an option with ng-repeat for changes', function(){ + scope.items = ['first', 'second', 'third']; + scope.foo = 'fourth'; + var element = compile(''); + expect(element.select2('val')).toBe(null); + scope.$apply('foo="fourth";items=["fourth"]'); + $timeout.flush(); + expect(element.select2('val')).toBe('fourth'); + }); + }); + describe('with an element', function () { + describe('compiling this directive', function () { + it('should throw an error if we have no model defined', function () { + expect(function() { + compile(''); + }).toThrow(); + }); + it('should create proper DOM structure', function () { + var element = compile(''); + expect(element.siblings().is('div.select2-container')).toBe(true); + }); + it('should not modify the model if there is no initial value', function(){ + //TODO + }); + }); + describe('when model is changed programmatically', function(){ + describe('for single-select', function(){ + it('should call select2(data, ...) for objects', function(){ + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo={ id: 1, text: "first" }'); + expect(element.select2).toHaveBeenCalledWith('data', { id: 1, text: "first" }); + }); + it('should call select2(val, ...) for strings', function(){ + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo="first"'); + expect(element.select2).toHaveBeenCalledWith('val', 'first'); + }); + }); + describe('for multi-select', function(){ + it('should call select2(data, ...) for arrays', function(){ + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo=[{ id: 1, text: "first" },{ id: 2, text: "second" }]'); + expect(element.select2).toHaveBeenCalledWith('data', [{ id: 1, text: "first" },{ id: 2, text: "second" }]); + }); + it('should call select2(data, []) for falsey values', function(){ + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo=[]'); + expect(element.select2).toHaveBeenCalledWith('data', []); + }); + xit('should call select2(val, ...) for strings', function(){ + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo="first,second"'); + expect(element.select2).toHaveBeenCalledWith('val', 'first,second'); + }); + }); + }); + describe('consumers of ngModel should correctly use $viewValue', function() { + it('should use any formatters if present (select - single select)', function(){ + scope.foo = 'First'; + var element = compile(''); + expect(element.select2('val')).toBe('First - I\'ve been formatted'); + scope.$apply('foo = "Second"'); + expect(element.select2('val')).toBe('Second - I\'ve been formatted'); + }); + + // isMultiple && falsey + it('should use any formatters if present (input multi select - falsey value)', function() { + // need special function to hit this case + // old code checked modelValue... can't just pass undefined to model value because view value will be the same + scope.transformers.fromModel = function(modelValue) { + if (modelValue === "magic") { + return undefined; + } + + return modelValue; + }; + + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo="magic"'); + expect(element.select2).toHaveBeenCalledWith('data', []); + }); + // isMultiple && isArray + it('should use any formatters if present (input multi select)', function() { + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo=[{ id: 1, text: "first" },{ id: 2, text: "second" }]'); + expect(element.select2).toHaveBeenCalledWith('data', [{ id: 1, text: "first - I've been formatted" },{ id: 2, text: "second - I've been formatted" }]); + }); + // isMultiple... + xit('should use any formatters if present (input multi select - non array)', function() { + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo={ id: 1, text: "first" }'); + expect(element.select2).toHaveBeenCalledWith('val', { id: 1, text: "first - I've been formatted" }); + }); + + // !isMultiple + it('should use any formatters if present (input - single select - object)', function() { + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo={ id: 1, text: "first" }'); + expect(element.select2).toHaveBeenCalledWith('data', { id: 1, text: "first - I've been formatted" }); + }); + it('should use any formatters if present (input - single select - non object)', function() { + var element = compile(''); + spyOn($.fn, 'select2'); + scope.$apply('foo="first"'); + expect(element.select2).toHaveBeenCalledWith('val', "first - I've been formatted"); + }); + + it('should not set the default value using scope.$eval', function() { + // testing directive instantiation - change order of test + spyOn($.fn, 'select2'); + spyOn($.fn, 'val'); + scope.$apply('foo=[{ id: 1, text: "first" },{ id: 2, text: "second" }]'); + + var element = compile(''); + expect(element.val).not.toHaveBeenCalledWith([{ id: 1, text: "first" },{ id: 2, text: "second" }]); + }); + it('should expect a default value to be set with a call to the render method', function() { + // this should monitor the events after init, when the timeout callback executes + var opts = angular.copy(scope.options); + opts.multiple = true; + + scope.$apply('foo=[{ id: 1, text: "first" },{ id: 2, text: "second" }]'); + + spyOn($.fn, 'select2'); + var element = compile(''); + + // select 2 init + expect(element.select2).toHaveBeenCalledWith(opts); + + // callback setting + expect(element.select2).toHaveBeenCalledWith('data', [{ id: 1, text: "first - I've been formatted" },{ id: 2, text: "second - I've been formatted" }]); + + // retieve data + expect(element.select2).toHaveBeenCalledWith('data'); + }); + + }); + it('should set the model when the user selects an item', function(){ + var element = compile(''); + // TODO: programmactically select an option + // expect(scope.foo).toBe(/* selected val */) ; + }); + + it('updated the view when model changes with complex object', function(){ + scope.foo = [{'id': '0', 'text': '0'}]; + scope.options['multiple'] = true; + var element = compile(''); + scope.$digest(); + + scope.foo.push({'id': '1', 'text': '1'}); + scope.$digest(); + + expect(element.select2('data')).toEqual( + [{'id': '0', 'text': '0'}, {'id': '1', 'text': '1'}]); + }); + + + describe('simple_tags', function() { + + beforeEach(function() { + scope.options['multiple'] = true; + scope.options['simple_tags'] = true; + scope.options['tags'] = []; + }); + + it('Initialize the select2 view based on list of strings.', function() { + scope.foo = ['tag1', 'tag2']; + + var element = compile(''); + scope.$digest(); + + expect(element.select2('data')).toEqual([ + {'id': 'tag1', 'text': 'tag1'}, + {'id': 'tag2', 'text': 'tag2'} + ]); + }); + + it( + 'When list is empty select2 view model is also initialized as empty', + function() { + scope.foo = []; + + var element = compile(''); + scope.$digest(); + + expect(element.select2('data')).toEqual([]); + }); + + it( + 'Updating the model with a string will update the select2 view model.', + function() { + scope.foo = []; + var element = compile(''); + scope.$digest(); + + scope.foo.push('tag1'); + scope.$digest(); + + expect(element.select2('data')).toEqual([ + {'id': 'tag1', 'text': 'tag1'} + ]); + }); + + it( + 'Updating the select2 model will update AngularJS model with a string.', + function() { + scope.foo = []; + var element = compile(''); + scope.$digest(); + + element.select2('data', [ + {'id':'tag1', 'text': 'tag1'}, + {'id':'tag2', 'text': 'tag2'} + ]); + element.trigger('change'); + + expect(scope.foo).toEqual(['tag1', 'tag2']); + }); + + }); + + }); +}); \ No newline at end of file diff --git a/Apollo/index.html b/Apollo/index.html index e6a74cba..d1e01780 100755 --- a/Apollo/index.html +++ b/Apollo/index.html @@ -25,6 +25,8 @@ + + @@ -65,6 +67,9 @@ + + +