diff --git a/build/paths.js b/build/paths.js index 7e99344..63ce17d 100755 --- a/build/paths.js +++ b/build/paths.js @@ -7,6 +7,9 @@ module.exports = { source: appRoot + '**/*.js', html: appRoot + '**/*.html', style: 'styles/**/*.css', + sass: 'styles/styles.scss', + saasStyle: 'styles/**/*.sass', + styleFolder: './styles', output: 'dist/', doc:'./doc', e2eSpecsSrc: 'test/e2e/src/*.js', diff --git a/build/tasks/build.js b/build/tasks/build.js index 30b6ad9..06a47f6 100755 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -5,12 +5,17 @@ var paths = require('../paths'); var compilerOptions = require('../babel-options'); var assign = Object.assign || require('object.assign'); +gulp.task('build-styles-es6', function () { + return gulp.src(paths.style) + .pipe(gulp.dest(paths.output + 'es6')); +}); + gulp.task('build-html-es6', function () { return gulp.src(paths.html) .pipe(gulp.dest(paths.output + 'es6')); }); -gulp.task('build-es6', ['build-html-es6'], function () { +gulp.task('build-es6', ['build-html-es6','build-styles-es6'], function () { return gulp.src(paths.source) .pipe(gulp.dest(paths.output + 'es6')); }); @@ -20,7 +25,12 @@ gulp.task('build-html-commonjs', function () { .pipe(gulp.dest(paths.output + 'commonjs')); }); -gulp.task('build-commonjs', ['build-html-commonjs'], function () { +gulp.task('build-styles-commonjs', function () { + return gulp.src(paths.style) + .pipe(gulp.dest(paths.output + 'commonjs')); +}); + +gulp.task('build-commonjs', ['build-html-commonjs', 'build-styles-commonjs'], function () { return gulp.src(paths.source) .pipe(to5(assign({}, compilerOptions, {modules:'common'}))) .pipe(gulp.dest(paths.output + 'commonjs')); @@ -31,7 +41,12 @@ gulp.task('build-html-amd', function () { .pipe(gulp.dest(paths.output + 'amd')); }); -gulp.task('build-amd', ['build-html-amd'], function () { +gulp.task('build-styles-amd', function () { + return gulp.src(paths.style) + .pipe(gulp.dest(paths.output + 'amd')); +}); + +gulp.task('build-amd', ['build-html-amd','build-styles-amd'], function () { return gulp.src(paths.source) .pipe(to5(assign({}, compilerOptions, {modules:'amd'}))) .pipe(gulp.dest(paths.output + 'amd')); @@ -42,7 +57,12 @@ gulp.task('build-html-system', function () { .pipe(gulp.dest(paths.output + 'system')); }); -gulp.task('build-system', ['build-html-system'], function () { +gulp.task('build-styles-system', function () { + return gulp.src(paths.style) + .pipe(gulp.dest(paths.output + 'system')); +}); + +gulp.task('build-system', ['build-html-system','build-styles-system'], function () { return gulp.src(paths.source) .pipe(to5(assign({}, compilerOptions, {modules:'system'}))) .pipe(gulp.dest(paths.output + 'system')); diff --git a/build/tasks/sass.js b/build/tasks/sass.js new file mode 100644 index 0000000..4ecaa32 --- /dev/null +++ b/build/tasks/sass.js @@ -0,0 +1,34 @@ +var gulp = require('gulp'); +var minifyCSS = require('gulp-minify-css'); +var plumber = require('gulp-plumber'); +var sass = require('gulp-ruby-sass'); +var gulpFilter = require('gulp-filter'); +var sourcemaps = require('gulp-sourcemaps'); +var paths = require('../paths'); +var runSequence = require('run-sequence'); + + +/** + * Generate CSS from SCSS + * Build sourcemaps + */ +gulp.task('sass', function () { + + var sassConfig = { + noCache: true, + compass: true, + sourcemap: false, + force: false + }; + + // Don’t write sourcemaps of sourcemaps + var filter = gulpFilter(['*.css', '!*.map']); + + return sass(paths.sass, sassConfig) + .pipe(plumber()) + .pipe(sourcemaps.init()) + .pipe(filter) // Don’t write sourcemaps of sourcemaps + .pipe(sourcemaps.write()) + .pipe(filter.restore()) // Restore original files + .pipe(gulp.dest(paths.styleFolder)); +}); diff --git a/config.js b/config.js index b53dca4..7a6bca8 100644 --- a/config.js +++ b/config.js @@ -22,6 +22,7 @@ System.config({ "babel-runtime": "npm:babel-runtime@5.5.6", "core-js": "npm:core-js@0.9.15", "css": "github:systemjs/plugin-css@0.1.12", + "devbridge/jQuery-Autocomplete": "github:devbridge/jQuery-Autocomplete@1.2.21", "jquery": "github:components/jquery@2.1.4", "select2": "github:select2/select2@3.5.2", "github:aurelia/binding@0.7.1": { diff --git a/dist/amd/autocomplete-abstract.js b/dist/amd/autocomplete-abstract.js new file mode 100644 index 0000000..c866997 --- /dev/null +++ b/dist/amd/autocomplete-abstract.js @@ -0,0 +1,30 @@ +define(['exports'], function (exports) { + 'use strict'; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var AutoCompleteAbstract = (function () { + function AutoCompleteAbstract() { + _classCallCheck(this, AutoCompleteAbstract); + } + + _createClass(AutoCompleteAbstract, [{ + key: 'search', + value: function search(item) { + return new Promise(function (resolve) { + resolve({ suggestions: [{ value: 'Code and Description', data: '01234' }] }); + }); + } + }]); + + return AutoCompleteAbstract; + })(); + + exports.AutoCompleteAbstract = AutoCompleteAbstract; +}); \ No newline at end of file diff --git a/dist/amd/autocomplete-widget.html b/dist/amd/autocomplete-widget.html new file mode 100644 index 0000000..1b5b26e --- /dev/null +++ b/dist/amd/autocomplete-widget.html @@ -0,0 +1,4 @@ + diff --git a/dist/amd/autocomplete-widget.js b/dist/amd/autocomplete-widget.js new file mode 100644 index 0000000..34300e9 --- /dev/null +++ b/dist/amd/autocomplete-widget.js @@ -0,0 +1,77 @@ +define(['exports', 'aurelia-framework', 'jquery', 'devbridge/jQuery-Autocomplete'], function (exports, _aureliaFramework, _jquery, _devbridgeJQueryAutocomplete) { + 'use strict'; + + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj['default'] : obj; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + + var _createDecoratedClass = (function () { function defineProperties(target, descriptors, initializers) { for (var i = 0; i < descriptors.length; i++) { var descriptor = descriptors[i]; var decorators = descriptor.decorators; var key = descriptor.key; delete descriptor.key; delete descriptor.decorators; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor || descriptor.initializer) descriptor.writable = true; if (decorators) { for (var f = 0; f < decorators.length; f++) { var decorator = decorators[f]; if (typeof decorator === 'function') { descriptor = decorator(target, key, descriptor) || descriptor; } else { throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator); } } if (initializers) initializers[key] = descriptor.initializer; } Object.defineProperty(target, key, descriptor); } } return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) { if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers); if (staticProps) defineProperties(Constructor, staticProps, staticInitializers); return Constructor; }; })(); + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var _$ = _interopRequire(_jquery); + + var _autocomplete = _interopRequire(_devbridgeJQueryAutocomplete); + + var AutoCompleteWidget = (function () { + function AutoCompleteWidget(element) { + _classCallCheck(this, _AutoCompleteWidget); + + this.element = element; + } + + var _AutoCompleteWidget = AutoCompleteWidget; + + _createDecoratedClass(_AutoCompleteWidget, [{ + key: 'bind', + value: function bind() { + this.apply(); + } + }, { + key: 'isShowing', + decorators: [_aureliaFramework.computedFrom('title')], + get: function () { + return this.title != undefined && this.title.length > 0; + } + }, { + key: 'apply', + value: function apply() { + _$(this.element).find('input').autocomplete({ + lookup: this.lookup.bind(this), + onSelect: this.onSelect.bind(this) + }); + } + }, { + key: 'lookup', + value: function lookup(query, done) { + this.controller.search(query).then(function (results) { + done(results); + }); + } + }, { + key: 'onSelect', + value: function onSelect(suggestion) { + this.selectedItem = suggestion.data; + } + }]); + + AutoCompleteWidget = _aureliaFramework.bindable('title')(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _aureliaFramework.bindable({ + name: 'selectedItem', + attribute: 'selected-item', + defaultBindingMode: _aureliaFramework.bindingMode.twoWay + })(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _aureliaFramework.bindable({ + name: 'controller', + attribute: 'controller', + defaultBindingMode: _aureliaFramework.bindingMode.twoWay + })(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _aureliaFramework.customElement('autocomplete-widget')(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _aureliaFramework.inject(Element)(AutoCompleteWidget) || AutoCompleteWidget; + return AutoCompleteWidget; + })(); + + exports.AutoCompleteWidget = AutoCompleteWidget; +}); \ No newline at end of file diff --git a/dist/amd/index.js b/dist/amd/index.js index dd31f3f..80b1c6f 100644 --- a/dist/amd/index.js +++ b/dist/amd/index.js @@ -8,5 +8,6 @@ define(['exports'], function (exports) { function configure(aurelia) { aurelia.globalizeResources('./lookup-widget'); + aurelia.globalizeResources('./autocomplete-widget'); } }); \ No newline at end of file diff --git a/dist/amd/styles.css b/dist/amd/styles.css new file mode 100644 index 0000000..94561c4 --- /dev/null +++ b/dist/amd/styles.css @@ -0,0 +1,20 @@ +.autocomplete-selected { + background: #f5f5f5; + color: #262626; } + +.autocomplete-suggestion { + cursor: pointer; + overflow: hidden; + padding: 3px 20px; + white-space: nowrap; } + +.autocomplete-suggestions { + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + overflow: auto; + padding: 5px 0; } + +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJzdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5hdXRvY29tcGxldGUtc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjZjVmNWY1O1xuICBjb2xvcjogIzI2MjYyNjsgfVxuXG4uYXV0b2NvbXBsZXRlLXN1Z2dlc3Rpb24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHBhZGRpbmc6IDNweCAyMHB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG5cbi5hdXRvY29tcGxldGUtc3VnZ2VzdGlvbnMge1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIHBhZGRpbmc6IDVweCAwOyB9XG4iXSwiZmlsZSI6InN0eWxlcy5jc3MiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== */ \ No newline at end of file diff --git a/dist/commonjs/autocomplete-abstract.js b/dist/commonjs/autocomplete-abstract.js new file mode 100644 index 0000000..ca105ea --- /dev/null +++ b/dist/commonjs/autocomplete-abstract.js @@ -0,0 +1,28 @@ +'use strict'; + +var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var AutoCompleteAbstract = (function () { + function AutoCompleteAbstract() { + _classCallCheck(this, AutoCompleteAbstract); + } + + _createClass(AutoCompleteAbstract, [{ + key: 'search', + value: function search(item) { + return new Promise(function (resolve) { + resolve({ suggestions: [{ value: 'Code and Description', data: '01234' }] }); + }); + } + }]); + + return AutoCompleteAbstract; +})(); + +exports.AutoCompleteAbstract = AutoCompleteAbstract; \ No newline at end of file diff --git a/dist/commonjs/autocomplete-widget.html b/dist/commonjs/autocomplete-widget.html new file mode 100644 index 0000000..1b5b26e --- /dev/null +++ b/dist/commonjs/autocomplete-widget.html @@ -0,0 +1,4 @@ + diff --git a/dist/commonjs/autocomplete-widget.js b/dist/commonjs/autocomplete-widget.js new file mode 100644 index 0000000..275a8df --- /dev/null +++ b/dist/commonjs/autocomplete-widget.js @@ -0,0 +1,81 @@ +'use strict'; + +var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }; + +var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + +var _createDecoratedClass = (function () { function defineProperties(target, descriptors, initializers) { for (var i = 0; i < descriptors.length; i++) { var descriptor = descriptors[i]; var decorators = descriptor.decorators; var key = descriptor.key; delete descriptor.key; delete descriptor.decorators; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor || descriptor.initializer) descriptor.writable = true; if (decorators) { for (var f = 0; f < decorators.length; f++) { var decorator = decorators[f]; if (typeof decorator === 'function') { descriptor = decorator(target, key, descriptor) || descriptor; } else { throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator); } } if (initializers) initializers[key] = descriptor.initializer; } Object.defineProperty(target, key, descriptor); } } return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) { if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers); if (staticProps) defineProperties(Constructor, staticProps, staticInitializers); return Constructor; }; })(); + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _inject$bindable$customElement$bindingMode$computedFrom = require('aurelia-framework'); + +var _$ = require('jquery'); + +var _$2 = _interopRequireWildcard(_$); + +var _autocomplete = require('devbridge/jQuery-Autocomplete'); + +var _autocomplete2 = _interopRequireWildcard(_autocomplete); + +var AutoCompleteWidget = (function () { + function AutoCompleteWidget(element) { + _classCallCheck(this, _AutoCompleteWidget); + + this.element = element; + } + + var _AutoCompleteWidget = AutoCompleteWidget; + + _createDecoratedClass(_AutoCompleteWidget, [{ + key: 'bind', + value: function bind() { + this.apply(); + } + }, { + key: 'isShowing', + decorators: [_inject$bindable$customElement$bindingMode$computedFrom.computedFrom('title')], + get: function () { + return this.title != undefined && this.title.length > 0; + } + }, { + key: 'apply', + value: function apply() { + _$2['default'](this.element).find('input').autocomplete({ + lookup: this.lookup.bind(this), + onSelect: this.onSelect.bind(this) + }); + } + }, { + key: 'lookup', + value: function lookup(query, done) { + this.controller.search(query).then(function (results) { + done(results); + }); + } + }, { + key: 'onSelect', + value: function onSelect(suggestion) { + this.selectedItem = suggestion.data; + } + }]); + + AutoCompleteWidget = _inject$bindable$customElement$bindingMode$computedFrom.bindable('title')(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _inject$bindable$customElement$bindingMode$computedFrom.bindable({ + name: 'selectedItem', + attribute: 'selected-item', + defaultBindingMode: _inject$bindable$customElement$bindingMode$computedFrom.bindingMode.twoWay + })(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _inject$bindable$customElement$bindingMode$computedFrom.bindable({ + name: 'controller', + attribute: 'controller', + defaultBindingMode: _inject$bindable$customElement$bindingMode$computedFrom.bindingMode.twoWay + })(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _inject$bindable$customElement$bindingMode$computedFrom.customElement('autocomplete-widget')(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = _inject$bindable$customElement$bindingMode$computedFrom.inject(Element)(AutoCompleteWidget) || AutoCompleteWidget; + return AutoCompleteWidget; +})(); + +exports.AutoCompleteWidget = AutoCompleteWidget; \ No newline at end of file diff --git a/dist/commonjs/index.js b/dist/commonjs/index.js index 9845aca..d1ce272 100644 --- a/dist/commonjs/index.js +++ b/dist/commonjs/index.js @@ -7,4 +7,5 @@ exports.configure = configure; function configure(aurelia) { aurelia.globalizeResources('./lookup-widget'); + aurelia.globalizeResources('./autocomplete-widget'); } \ No newline at end of file diff --git a/dist/commonjs/styles.css b/dist/commonjs/styles.css new file mode 100644 index 0000000..94561c4 --- /dev/null +++ b/dist/commonjs/styles.css @@ -0,0 +1,20 @@ +.autocomplete-selected { + background: #f5f5f5; + color: #262626; } + +.autocomplete-suggestion { + cursor: pointer; + overflow: hidden; + padding: 3px 20px; + white-space: nowrap; } + +.autocomplete-suggestions { + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + overflow: auto; + padding: 5px 0; } + +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJzdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5hdXRvY29tcGxldGUtc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjZjVmNWY1O1xuICBjb2xvcjogIzI2MjYyNjsgfVxuXG4uYXV0b2NvbXBsZXRlLXN1Z2dlc3Rpb24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHBhZGRpbmc6IDNweCAyMHB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG5cbi5hdXRvY29tcGxldGUtc3VnZ2VzdGlvbnMge1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIHBhZGRpbmc6IDVweCAwOyB9XG4iXSwiZmlsZSI6InN0eWxlcy5jc3MiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== */ \ No newline at end of file diff --git a/dist/es6/autocomplete-abstract.js b/dist/es6/autocomplete-abstract.js new file mode 100644 index 0000000..1af3b60 --- /dev/null +++ b/dist/es6/autocomplete-abstract.js @@ -0,0 +1,11 @@ +export class AutoCompleteAbstract { + constructor() { + } + + search(item) { + //Override this class with your API to execute the query + return new Promise((resolve) => { + resolve({ suggestions: [ { value: 'Code and Description', data: '01234' } ] }); + }); + } +} diff --git a/dist/es6/autocomplete-widget.html b/dist/es6/autocomplete-widget.html new file mode 100644 index 0000000..1b5b26e --- /dev/null +++ b/dist/es6/autocomplete-widget.html @@ -0,0 +1,4 @@ + diff --git a/dist/es6/autocomplete-widget.js b/dist/es6/autocomplete-widget.js new file mode 100644 index 0000000..c03860b --- /dev/null +++ b/dist/es6/autocomplete-widget.js @@ -0,0 +1,48 @@ +import {inject, bindable, customElement, bindingMode, computedFrom} from 'aurelia-framework'; +import $ from 'jquery'; +import autocomplete from 'devbridge/jQuery-Autocomplete'; + +@inject(Element) +@customElement('autocomplete-widget') +@bindable({ + name:'controller', + attribute:'controller', + defaultBindingMode: bindingMode.twoWay +}) +@bindable({ + name:'selectedItem', + attribute:'selected-item', + defaultBindingMode: bindingMode.twoWay +}) +@bindable('title') +export class AutoCompleteWidget { + constructor(element) { + this.element = element; + } + + bind() { + this.apply(); + } + + @computedFrom('title') + get isShowing() { + return this.title != undefined && this.title.length > 0; + } + + apply() { + $(this.element).find('input').autocomplete({ + lookup: this.lookup.bind(this), + onSelect: this.onSelect.bind(this) + }); + } + + lookup(query,done) { + this.controller.search(query).then((results) => { + done(results); + }); + } + + onSelect(suggestion) { + this.selectedItem = suggestion.data; + } +} diff --git a/dist/es6/index.js b/dist/es6/index.js index 0ef3d92..2825783 100644 --- a/dist/es6/index.js +++ b/dist/es6/index.js @@ -1,3 +1,4 @@ export function configure(aurelia) { aurelia.globalizeResources('./lookup-widget'); + aurelia.globalizeResources('./autocomplete-widget'); } diff --git a/dist/es6/styles.css b/dist/es6/styles.css new file mode 100644 index 0000000..94561c4 --- /dev/null +++ b/dist/es6/styles.css @@ -0,0 +1,20 @@ +.autocomplete-selected { + background: #f5f5f5; + color: #262626; } + +.autocomplete-suggestion { + cursor: pointer; + overflow: hidden; + padding: 3px 20px; + white-space: nowrap; } + +.autocomplete-suggestions { + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + overflow: auto; + padding: 5px 0; } + +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJzdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5hdXRvY29tcGxldGUtc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjZjVmNWY1O1xuICBjb2xvcjogIzI2MjYyNjsgfVxuXG4uYXV0b2NvbXBsZXRlLXN1Z2dlc3Rpb24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHBhZGRpbmc6IDNweCAyMHB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG5cbi5hdXRvY29tcGxldGUtc3VnZ2VzdGlvbnMge1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIHBhZGRpbmc6IDVweCAwOyB9XG4iXSwiZmlsZSI6InN0eWxlcy5jc3MiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== */ \ No newline at end of file diff --git a/dist/system/autocomplete-abstract.js b/dist/system/autocomplete-abstract.js new file mode 100644 index 0000000..4cdfafe --- /dev/null +++ b/dist/system/autocomplete-abstract.js @@ -0,0 +1,33 @@ +System.register([], function (_export) { + var _classCallCheck, _createClass, AutoCompleteAbstract; + + return { + setters: [], + execute: function () { + 'use strict'; + + _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + + _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + AutoCompleteAbstract = (function () { + function AutoCompleteAbstract() { + _classCallCheck(this, AutoCompleteAbstract); + } + + _createClass(AutoCompleteAbstract, [{ + key: 'search', + value: function search(item) { + return new Promise(function (resolve) { + resolve({ suggestions: [{ value: 'Code and Description', data: '01234' }] }); + }); + } + }]); + + return AutoCompleteAbstract; + })(); + + _export('AutoCompleteAbstract', AutoCompleteAbstract); + } + }; +}); \ No newline at end of file diff --git a/dist/system/autocomplete-widget.html b/dist/system/autocomplete-widget.html new file mode 100644 index 0000000..1b5b26e --- /dev/null +++ b/dist/system/autocomplete-widget.html @@ -0,0 +1,4 @@ + diff --git a/dist/system/autocomplete-widget.js b/dist/system/autocomplete-widget.js new file mode 100644 index 0000000..d52fd35 --- /dev/null +++ b/dist/system/autocomplete-widget.js @@ -0,0 +1,84 @@ +System.register(['aurelia-framework', 'jquery', 'devbridge/jQuery-Autocomplete'], function (_export) { + var inject, bindable, customElement, bindingMode, computedFrom, $, autocomplete, _classCallCheck, _createDecoratedClass, AutoCompleteWidget; + + return { + setters: [function (_aureliaFramework) { + inject = _aureliaFramework.inject; + bindable = _aureliaFramework.bindable; + customElement = _aureliaFramework.customElement; + bindingMode = _aureliaFramework.bindingMode; + computedFrom = _aureliaFramework.computedFrom; + }, function (_jquery) { + $ = _jquery['default']; + }, function (_devbridgeJQueryAutocomplete) { + autocomplete = _devbridgeJQueryAutocomplete['default']; + }], + execute: function () { + 'use strict'; + + _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + + _createDecoratedClass = (function () { function defineProperties(target, descriptors, initializers) { for (var i = 0; i < descriptors.length; i++) { var descriptor = descriptors[i]; var decorators = descriptor.decorators; var key = descriptor.key; delete descriptor.key; delete descriptor.decorators; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor || descriptor.initializer) descriptor.writable = true; if (decorators) { for (var f = 0; f < decorators.length; f++) { var decorator = decorators[f]; if (typeof decorator === 'function') { descriptor = decorator(target, key, descriptor) || descriptor; } else { throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator); } } if (initializers) initializers[key] = descriptor.initializer; } Object.defineProperty(target, key, descriptor); } } return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) { if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers); if (staticProps) defineProperties(Constructor, staticProps, staticInitializers); return Constructor; }; })(); + + AutoCompleteWidget = (function () { + function AutoCompleteWidget(element) { + _classCallCheck(this, _AutoCompleteWidget); + + this.element = element; + } + + var _AutoCompleteWidget = AutoCompleteWidget; + + _createDecoratedClass(_AutoCompleteWidget, [{ + key: 'bind', + value: function bind() { + this.apply(); + } + }, { + key: 'isShowing', + decorators: [computedFrom('title')], + get: function () { + return this.title != undefined && this.title.length > 0; + } + }, { + key: 'apply', + value: function apply() { + $(this.element).find('input').autocomplete({ + lookup: this.lookup.bind(this), + onSelect: this.onSelect.bind(this) + }); + } + }, { + key: 'lookup', + value: function lookup(query, done) { + this.controller.search(query).then(function (results) { + done(results); + }); + } + }, { + key: 'onSelect', + value: function onSelect(suggestion) { + this.selectedItem = suggestion.data; + } + }]); + + AutoCompleteWidget = bindable('title')(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = bindable({ + name: 'selectedItem', + attribute: 'selected-item', + defaultBindingMode: bindingMode.twoWay + })(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = bindable({ + name: 'controller', + attribute: 'controller', + defaultBindingMode: bindingMode.twoWay + })(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = customElement('autocomplete-widget')(AutoCompleteWidget) || AutoCompleteWidget; + AutoCompleteWidget = inject(Element)(AutoCompleteWidget) || AutoCompleteWidget; + return AutoCompleteWidget; + })(); + + _export('AutoCompleteWidget', AutoCompleteWidget); + } + }; +}); \ No newline at end of file diff --git a/dist/system/index.js b/dist/system/index.js index dc9fe21..a9850f3 100644 --- a/dist/system/index.js +++ b/dist/system/index.js @@ -3,6 +3,7 @@ System.register([], function (_export) { function configure(aurelia) { aurelia.globalizeResources('./lookup-widget'); + aurelia.globalizeResources('./autocomplete-widget'); } return { diff --git a/dist/system/styles.css b/dist/system/styles.css new file mode 100644 index 0000000..94561c4 --- /dev/null +++ b/dist/system/styles.css @@ -0,0 +1,20 @@ +.autocomplete-selected { + background: #f5f5f5; + color: #262626; } + +.autocomplete-suggestion { + cursor: pointer; + overflow: hidden; + padding: 3px 20px; + white-space: nowrap; } + +.autocomplete-suggestions { + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + overflow: auto; + padding: 5px 0; } + +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJzdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5hdXRvY29tcGxldGUtc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjZjVmNWY1O1xuICBjb2xvcjogIzI2MjYyNjsgfVxuXG4uYXV0b2NvbXBsZXRlLXN1Z2dlc3Rpb24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHBhZGRpbmc6IDNweCAyMHB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG5cbi5hdXRvY29tcGxldGUtc3VnZ2VzdGlvbnMge1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIHBhZGRpbmc6IDVweCAwOyB9XG4iXSwiZmlsZSI6InN0eWxlcy5jc3MiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== */ \ No newline at end of file diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 029b620..05244fc --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aurelia-widgets", - "version": "0.1.17", + "version": "0.1.18", "description": "Collection of third party wrappers that get used in Aurelia applications", "homepage": "http://drivesoftware.co.nz", "main": "index", @@ -50,6 +50,7 @@ "aurelia-dependency-injection": "github:aurelia/dependency-injection@^0.8.1", "aurelia-framework": "github:aurelia/framework@^0.12.0", "css": "github:systemjs/plugin-css@^0.1.6", + "devbridge/jQuery-Autocomplete": "github:devbridge/jQuery-Autocomplete@^1.2.21", "jquery": "github:components/jquery@^2.1.3", "select2": "github:select2/select2@^3.5.2" }, @@ -58,5 +59,13 @@ "babel-runtime": "npm:babel-runtime@^5.1.13", "core-js": "npm:core-js@^0.9.4" } + }, + "dependencies": { + "bootstrap-sass": "^3.3.4", + "gulp-filter": "^2.0.2", + "gulp-minify-css": "^1.1.6", + "gulp-plumber": "^1.0.1", + "gulp-ruby-sass": "^1.0.5", + "gulp-sourcemaps": "^1.5.2" } } diff --git a/src/autocomplete-abstract.js b/src/autocomplete-abstract.js new file mode 100644 index 0000000..1af3b60 --- /dev/null +++ b/src/autocomplete-abstract.js @@ -0,0 +1,11 @@ +export class AutoCompleteAbstract { + constructor() { + } + + search(item) { + //Override this class with your API to execute the query + return new Promise((resolve) => { + resolve({ suggestions: [ { value: 'Code and Description', data: '01234' } ] }); + }); + } +} diff --git a/src/autocomplete-widget.html b/src/autocomplete-widget.html new file mode 100644 index 0000000..1b5b26e --- /dev/null +++ b/src/autocomplete-widget.html @@ -0,0 +1,4 @@ + diff --git a/src/autocomplete-widget.js b/src/autocomplete-widget.js new file mode 100644 index 0000000..c03860b --- /dev/null +++ b/src/autocomplete-widget.js @@ -0,0 +1,48 @@ +import {inject, bindable, customElement, bindingMode, computedFrom} from 'aurelia-framework'; +import $ from 'jquery'; +import autocomplete from 'devbridge/jQuery-Autocomplete'; + +@inject(Element) +@customElement('autocomplete-widget') +@bindable({ + name:'controller', + attribute:'controller', + defaultBindingMode: bindingMode.twoWay +}) +@bindable({ + name:'selectedItem', + attribute:'selected-item', + defaultBindingMode: bindingMode.twoWay +}) +@bindable('title') +export class AutoCompleteWidget { + constructor(element) { + this.element = element; + } + + bind() { + this.apply(); + } + + @computedFrom('title') + get isShowing() { + return this.title != undefined && this.title.length > 0; + } + + apply() { + $(this.element).find('input').autocomplete({ + lookup: this.lookup.bind(this), + onSelect: this.onSelect.bind(this) + }); + } + + lookup(query,done) { + this.controller.search(query).then((results) => { + done(results); + }); + } + + onSelect(suggestion) { + this.selectedItem = suggestion.data; + } +} diff --git a/src/index.js b/src/index.js index 0ef3d92..2825783 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ export function configure(aurelia) { aurelia.globalizeResources('./lookup-widget'); + aurelia.globalizeResources('./autocomplete-widget'); } diff --git a/styles/autocomplete.scss b/styles/autocomplete.scss new file mode 100644 index 0000000..9f0f873 --- /dev/null +++ b/styles/autocomplete.scss @@ -0,0 +1,20 @@ +.autocomplete-selected { + background: $dropdown-link-hover-bg; + color: $dropdown-link-hover-color; +} + +.autocomplete-suggestion { + cursor: pointer; + overflow: hidden; // From the jQuery Autocomplete README. + padding: 3px 20px; // Same as .dropdown-menu links. + white-space: nowrap; // From the jQuery Autocomplete README. +} + +.autocomplete-suggestions { + background: $dropdown-bg; + border: 1px solid $dropdown-border; + border-radius: $border-radius-base; + @include box-shadow(0 6px 12px rgba(0,0,0,.175)); + overflow: auto; // From the jQuery Autocomplete README. + padding: 5px 0; // From the .dropdown-menu rule. +} diff --git a/styles/styles.css b/styles/styles.css new file mode 100644 index 0000000..94561c4 --- /dev/null +++ b/styles/styles.css @@ -0,0 +1,20 @@ +.autocomplete-selected { + background: #f5f5f5; + color: #262626; } + +.autocomplete-suggestion { + cursor: pointer; + overflow: hidden; + padding: 3px 20px; + white-space: nowrap; } + +.autocomplete-suggestions { + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + overflow: auto; + padding: 5px 0; } + +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJzdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5hdXRvY29tcGxldGUtc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjZjVmNWY1O1xuICBjb2xvcjogIzI2MjYyNjsgfVxuXG4uYXV0b2NvbXBsZXRlLXN1Z2dlc3Rpb24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHBhZGRpbmc6IDNweCAyMHB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG5cbi5hdXRvY29tcGxldGUtc3VnZ2VzdGlvbnMge1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgYm94LXNoYWRvdzogMCA2cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTc1KTtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIHBhZGRpbmc6IDVweCAwOyB9XG4iXSwiZmlsZSI6InN0eWxlcy5jc3MiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== */ \ No newline at end of file diff --git a/styles/styles.scss b/styles/styles.scss new file mode 100644 index 0000000..a303d4c --- /dev/null +++ b/styles/styles.scss @@ -0,0 +1,3 @@ +@import "../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables"; +@import "../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins"; +@import "./autocomplete.scss";