diff --git a/src/AppMenu.vue b/src/AppMenu.vue index 8565ff775..f5f546110 100644 --- a/src/AppMenu.vue +++ b/src/AppMenu.vue @@ -9,6 +9,7 @@
● InputText + ● ListBox
diff --git a/src/assets/styles/primevue.css b/src/assets/styles/primevue.css index a87c431ef..3e62abf94 100644 --- a/src/assets/styles/primevue.css +++ b/src/assets/styles/primevue.css @@ -1,3 +1,4 @@ @import '../../components/common/Common.css'; @import '../../components/inputtext/InputText.css'; +@import '../../components/listbox/ListBox.css'; @import '../../components/button/Button.css'; \ No newline at end of file diff --git a/src/components/listbox/ListBox.css b/src/components/listbox/ListBox.css new file mode 100644 index 000000000..82bc81aa2 --- /dev/null +++ b/src/components/listbox/ListBox.css @@ -0,0 +1,68 @@ +.p-listbox { + padding: .25em; + width: 10em; +} + +.p-listbox .p-listbox-list-wrapper { + overflow:auto; +} + +.p-listbox .p-listbox-list { + list-style-type: none; + margin: 0; + padding: 0; +} + +.p-listbox .p-listbox-item { + padding: .25em; + border: 0 none; + cursor: pointer; + font-weight: normal; + margin-bottom: 1px; +} + +.p-listbox .p-listbox-item > span { + vertical-align: middle; +} + +.p-listbox .p-listbox-item:last-child { + margin-bottom: 0; +} + +.p-listbox.p-disabled .p-listbox-item { + cursor: default; +} + +.p-listbox-header { + margin-bottom: 0.3em; + padding: .125em .2em; + position: relative; +} + +.p-listbox-header .p-checkbox { + display: inline-block; + vertical-align: middle; + cursor: pointer; +} + +.p-listbox-header .p-listbox-filter-container { + display: inline-block; + vertical-align: middle; + position: relative; + width: 100%; +} + +.p-listbox-header.p-listbox-header-w-checkbox .p-listbox-filter-container { + width: calc(100% - 2em); +} + +.p-listbox-header .p-listbox-filter-container .p-listbox-filter-icon { + position: absolute; + top: .25em; + left: .25em; +} + +.p-listbox-header .p-inputtext { + padding: .125em .125em .125em 1.25em; + width: 100%; +} \ No newline at end of file diff --git a/src/components/listbox/ListBox.vue b/src/components/listbox/ListBox.vue new file mode 100644 index 000000000..1a4862b44 --- /dev/null +++ b/src/components/listbox/ListBox.vue @@ -0,0 +1,150 @@ + + + \ No newline at end of file diff --git a/src/components/utils/ObjectUtils.js b/src/components/utils/ObjectUtils.js new file mode 100644 index 000000000..f306637ab --- /dev/null +++ b/src/components/utils/ObjectUtils.js @@ -0,0 +1,201 @@ +export default class ObjectUtils { + + static equals(obj1, obj2, field) { + if(field) + return (this.resolveFieldData(obj1, field) === this.resolveFieldData(obj2, field)); + else + return this.equalsByValue(obj1, obj2); + } + + static equalsByValue(obj1, obj2) { + if (obj1 === null && obj2 === null) { + return true; + } + if (obj1 === null || obj2 === null) { + return false; + } + + if (obj1 === obj2) { + delete obj1._$visited; + return true; + } + + if (typeof obj1 === 'object' && typeof obj2 === 'object') { + obj1._$visited = true; + for (var p in obj1) { + if (p === "_$visited") continue; + if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) { + return false; + } + + switch (typeof (obj1[p])) { + case 'object': + if ((obj1[p] && obj1[p]._$visited) || !this.equals(obj1[p], obj2[p])) return false; + break; + + case 'function': + if (typeof (obj2[p]) === 'undefined' || (p !== 'compare' && obj1[p].toString() !== obj2[p].toString())) return false; + break; + + default: + if (obj1[p] !== obj2[p]) return false; + break; + } + } + + for (var pp in obj2) { + if (typeof (obj1[pp]) === 'undefined') return false; + } + + delete obj1._$visited; + return true; + } + + return false; + } + + static resolveFieldData(data, field) { + if(data && field) { + if(field.indexOf('.') === -1) { + return data[field]; + } + else { + let fields = field.split('.'); + let value = data; + for(var i = 0, len = fields.length; i < len; ++i) { + value = value[fields[i]]; + } + return value; + } + } + else { + return null; + } + } + static filter(value, fields, filterValue) { + var filteredItems=[]; + + if(value) { + for(let item of value) { + for(let field of fields) { + if(String(this.resolveFieldData(item, field)).toLowerCase().indexOf(filterValue.toLowerCase()) > -1) { + filteredItems.push(item); + break; + } + } + } + } + + return filteredItems; + } + + static reorderArray(value, from, to) { + let target; + if(value && (from !== to)) { + if(to >= value.length) { + target = to - value.length; + while((target--) + 1) { + value.push(undefined); + } + } + value.splice(to, 0, value.splice(from, 1)[0]); + } + } + + static findIndexInList(value, list) { + let index = -1; + + if(list) { + for(let i = 0; i < list.length; i++) { + if(list[i] === value) { + index = i; + break; + } + } + } + + return index; + } + + static filterConstraints = { + + startsWith(value, filter) { + if(filter === undefined || filter === null || filter.trim() === '') { + return true; + } + + if(value === undefined || value === null) { + return false; + } + + let filterValue = filter.toLowerCase(); + return value.toString().toLowerCase().slice(0, filterValue.length) === filterValue; + }, + + contains(value, filter) { + if(filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) { + return true; + } + + if(value === undefined || value === null) { + return false; + } + + return value.toString().toLowerCase().indexOf(filter.toLowerCase()) !== -1; + }, + + endsWith(value, filter) { + if(filter === undefined || filter === null || filter.trim() === '') { + return true; + } + + if(value === undefined || value === null) { + return false; + } + + let filterValue = filter.toString().toLowerCase(); + return value.toString().toLowerCase().indexOf(filterValue, value.toString().length - filterValue.length) !== -1; + }, + + equals(value, filter) { + if(filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) { + return true; + } + + if(value === undefined || value === null) { + return false; + } + + return value.toString().toLowerCase() === filter.toString().toLowerCase(); + }, + + notEquals(value, filter) { + if(filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) { + return false; + } + + if(value === undefined || value === null) { + return true; + } + + return value.toString().toLowerCase() !== filter.toString().toLowerCase(); + }, + + in(value, filter) { + if(filter === undefined || filter === null || filter.length === 0) { + return true; + } + + if(value === undefined || value === null) { + return false; + } + + for(let i = 0; i < filter.length; i++) { + if(filter[i] === value) + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/src/main.js b/src/main.js index fcea726f7..9243e1c89 100644 --- a/src/main.js +++ b/src/main.js @@ -2,6 +2,7 @@ import Vue from 'vue'; import App from './App.vue'; import router from './router'; import InputText from './components/inputtext/InputText'; +import ListBox from './components/listbox/ListBox'; import Button from './components/button/Button'; import './assets/styles/primevue.css'; @@ -12,6 +13,7 @@ Vue.config.productionTip = false; Vue.component('p-inputtext', InputText); Vue.component('p-button', Button); +Vue.component('p-listBox', ListBox); new Vue({ router, diff --git a/src/router.js b/src/router.js index bd32fc3c4..01419b6cd 100644 --- a/src/router.js +++ b/src/router.js @@ -21,6 +21,11 @@ export default new Router({ name: 'inputtext', component: () => import('./views/inputtext/InputTextDemo.vue') }, + { + path: '/listbox', + name: 'listbox', + component: () => import('./views/listbox/ListBoxDemo.vue') + }, { path: '/button', name: 'button', diff --git a/src/views/listbox/ListBoxDemo.vue b/src/views/listbox/ListBoxDemo.vue new file mode 100644 index 000000000..3e13ccab6 --- /dev/null +++ b/src/views/listbox/ListBoxDemo.vue @@ -0,0 +1,40 @@ + + + + +