gumga-many-to-one-ng
Version:
Gumga Many To One
808 lines (715 loc) • 34.9 kB
JavaScript
(function () {
'use strict';
ManyToOne.$inject = ['$templateCache', '$uibModal', '$compile', '$timeout'];
function ManyToOne($templateCache, $uibModal, $compile, $timeout) {
controller.$inject = ['$scope', '$element', '$attrs', '$transclude'];
function controller($scope, $element, $attrs, $transclude) {
let manyToOneCtrl = this, ngModelCtrl, ngModelCtrlReset;
manyToOneCtrl.withStriped = $element.hasClass('striped');
manyToOneCtrl.page = 1;
$element.bind('keydown', function (evt) {
if (evt.which === 40 || evt.which === 38) {
const li = $element.find('ul.dropdown-menu li.active');
$element.find('ul.dropdown-menu')[0].scrollTop = (li.index()) * li.find('a').height();
}
});
$scope.$watch('manyToOneCtrl.lastParam', (value) => {
$scope.$value = value;
});
$scope.$watch('manyToOneCtrl.typeData', (value) => {
$scope.$list = value;
});
const infiniteScroll = () => {
manyToOneCtrl.infiniteDisabled = true;
manyToOneCtrl.page++;
manyToOneCtrl.proxySearch(manyToOneCtrl.lastParam, 10, manyToOneCtrl.page, true);
};
const startInfinityScroll = () => {
$element.ready(() => {
const elm = $element.find('ul[uib-typeahead-popup]');
angular.element(elm).scroll((evt) => {
let disabled = manyToOneCtrl.hasOwnProperty('infiniteDisabled') ? manyToOneCtrl.infiniteDisabled : false;
if (elm.scrollTop() + elm.innerHeight() >= elm[0].scrollHeight && !disabled) {
infiniteScroll();
}
});
})
}
manyToOneCtrl.$onInit = () => {
const ERR_MSGS = {
noValue: 'É necessário um atributo value no componente gumgaManyToOne',
noField: 'É necessário um atributo field no componente gumgaManyToOne',
noSearch: 'É necessário uma função de busca no componente gumgaManyToOne'
}
const possibleAttributes = ['loadingText', 'onSelect', 'value', 'list', 'searchMethod', 'field', 'onNewValueAdded', 'onValueSelected', 'onValueVisualizationOpened', 'onValueVisualizationClosed', 'tabindex']
let template = false;
let cache = getCookie(getKeyCookie());
if (cache) {
manyToOneCtrl.favoriteModel = JSON.parse(cache);
}
if ($attrs.debug && manyToOneCtrl.activeFavorite) {
console.log('Cookie: ', getCookie(getKeyCookie()));
}
if ($attrs.debug) {
console.log('ngModel: ', manyToOneCtrl.value);
console.log('activeFavorite: ', manyToOneCtrl.activeFavorite);
}
if (!manyToOneCtrl.value && manyToOneCtrl.favoriteModel && manyToOneCtrl.activeFavorite) {
manyToOneCtrl.value = angular.copy(manyToOneCtrl.favoriteModel);
}
if (!$attrs.value) console.error(ERR_MSGS.noValue)
if (!$attrs.field) console.error(ERR_MSGS.noField)
manyToOneCtrl.ev = {}
manyToOneCtrl.list = manyToOneCtrl.list || []
manyToOneCtrl.ev.onNewValueAdded = $attrs.onNewValueAdded ? manyToOneCtrl.onNewValueAdded : angular.noop
manyToOneCtrl.ev.onSelect = $attrs.onSelect ? manyToOneCtrl.onSelect : angular.noop
manyToOneCtrl.ev.onValueVisualizationOpened = $attrs.onValueVisualizationOpened ? $attrs.onValueVisualizationOpened : angular.noop
manyToOneCtrl.ev.onValueVisualizationClosed = $attrs.onValueVisualizationClosed ? $attrs.onValueVisualizationClosed : angular.noop
manyToOneCtrl.field = $attrs.field || ''
// manyToOneCtrl.description = $attrs.description || false
manyToOneCtrl.modalTitle = $attrs.modalTitle || 'Visualizador de Registro'
manyToOneCtrl.modalFields = $attrs.modalFields ? $attrs.modalFields.split(',') : [manyToOneCtrl.field]
manyToOneCtrl.postFields = $attrs.postFields ? $attrs.postFields.split(',') : [manyToOneCtrl.field]
manyToOneCtrl.displayClear = manyToOneCtrl.hasOwnProperty('displayClear') ? manyToOneCtrl.displayClear : true
manyToOneCtrl.displayInfo = manyToOneCtrl.hasOwnProperty('displayInfo') ? manyToOneCtrl.displayInfo : true
manyToOneCtrl.editable = manyToOneCtrl.hasOwnProperty('editable') ? manyToOneCtrl.editable : true
manyToOneCtrl.async = manyToOneCtrl.hasOwnProperty('async') ? manyToOneCtrl.async : true
// manyToOneCtrl.showDescripion = !!manyToOneCtrl.description
function mirrorAttributes() {
const isOneOfPossibles = attribute => possibleAttributes.filter(value => attribute == value).length > 0;
return Object.keys($attrs.$attr).filter((value) => !isOneOfPossibles(value)).reduce((prev, next) => prev += `${next}="${$attrs[next]}"`, '');
}
manyToOneCtrl.displayInfoButton = displayInfoButton
manyToOneCtrl.modelValueIsObject = modelValueIsObject
manyToOneCtrl.disabledDisplayInfo = disabledDisplayInfo
manyToOneCtrl.displayPlusButton = displayPlusButton
manyToOneCtrl.displayClearButton = displayClearButton
manyToOneCtrl.clearModel = clearModel
manyToOneCtrl.openInfo = openInfo
manyToOneCtrl.valueToAdd = ''
manyToOneCtrl.afterSelect = afterSelect
manyToOneCtrl.openTypehead = openTypehead
manyToOneCtrl.showTypeheadAndHideMatch = showTypeheadAndHideMatch
manyToOneCtrl.minLetter = manyToOneCtrl.minLetter || 0;
manyToOneCtrl.typeData = [];
manyToOneCtrl.proxySearch = (param = '', pageSize = 10, page = 1, byInfinity) => {
if (!byInfinity && manyToOneCtrl.lastParam == param) {
return;
}
if (manyToOneCtrl.value && typeof manyToOneCtrl.value === 'object') {
return;
}
if (!manyToOneCtrl.async) {
if (param) param = param.toLowerCase();
manyToOneCtrl.lastParam = param;
let data = manyToOneCtrl.list.filter(listItem => {
return listItem[manyToOneCtrl.field].toLowerCase().indexOf(param) != -1;
});
$timeout(() => {
manyToOneCtrl.typeData = data;
manyToOneCtrl.ngModelCtrl.$viewValue = "";
manyToOneCtrl.inputElm[0].dispatchEvent(new Event('focus'));
manyToOneCtrl.ngModelCtrl.$viewValue = param;
})
} else {
manyToOneCtrl.typeaheadLoading = true;
manyToOneCtrl.lastParam = param;
manyToOneCtrl.searchMethod({ param, pageSize, page }).then((resp) => {
let data = resp.data && resp.data.values && Array.isArray(resp.data.values) ? resp.data.values : resp;
if (manyToOneCtrl.infinityPagination) {
if (page > 1) {
data = manyToOneCtrl.lastArray.concat(data);
}
manyToOneCtrl.lastArray = angular.copy(data);
}
if (param && !manyToOneCtrl.infinityPagination && manyToOneCtrl.authorizeAdd) {
let objToAppend = {};
objToAppend[manyToOneCtrl.field] = manyToOneCtrl.valueToAdd;
data = data.concat(objToAppend)
}
$timeout(() => {
manyToOneCtrl.typeaheadLoading = false;
manyToOneCtrl.infiniteDisabled = false;
manyToOneCtrl.typeData = data;
manyToOneCtrl.ngModelCtrl.$viewValue = "";
manyToOneCtrl.inputElm[0].dispatchEvent(new Event('focus'));
manyToOneCtrl.ngModelCtrl.$viewValue = param;
})
})
}
}
manyToOneCtrl.proxySave = (val, abc) => {
if (!abc) return
manyToOneCtrl.isTypeaheadOpen = true;
const controllerAs = 'ctrl'
const resolve = { value: () => val }
controller.$inject = ['$scope', '$uibModalInstance', 'value']
function controller($scope, $uibModalInstance, value) {
let ctrl = this;
ctrl.object = value
ctrl.cancel = obj => $uibModalInstance.dismiss('cancel');
ctrl.save = obj => $uibModalInstance.close(obj);
}
function mountModalBody() {
let fields = manyToOneCtrl.postFields;
const labels = manyToOneCtrl.labelsModal || {}
return fields.reduce((prev, next) => {
let field = next.indexOf(':') != -1 ? next.trim().substring(0, next.indexOf(':')) : next.trim();
let required = next.indexOf(':') != -1 ? next.trim().substring(next.indexOf(':') + 1, next.length) : 'false';
return prev += `
<div class="form-group">
<label>${labels[field] ? labels[field] : field}</label>
<input type="text" class="form-control" ${required == 'required' ? required : ''} ng-model="ctrl.object.${field}" />
</div>`;
}, ' ');
}
let template = `
<div class="modal-header">
<h3 class="modal-title">${manyToOneCtrl.modalTitle}</h3>
</div>
<div class="modal-body">
<form name="formNew">
${mountModalBody()}
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="ctrl.cancel(ctrl.object)">Retornar</button>
<button type="button" class="btn btn-primary" ng-disabled="!formNew.$valid" ng-click="ctrl.save(ctrl.object)">Salvar</button>
</div>`;
$uibModal
.open({ controller, template, controllerAs, resolve })
.result
.then(value => {
manyToOneCtrl.postMethod({ value }).then(
dataFromPostMethod => {
manyToOneCtrl.value = dataFromPostMethod.data.data
ngModelCtrl.$viewValue = dataFromPostMethod.data.data
}
)
}, reject => {
delete manyToOneCtrl.value;
})
}
manyToOneCtrl.getRegisterStyle = () => {
if (manyToOneCtrl.inputElm) {
const height = manyToOneCtrl.inputElm.height() +
$element.find('ul.dropdown-menu[uib-typeahead-popup]').height();
return {
top: height + 18
};
}
return {
top: 0
};
}
manyToOneCtrl.isOpenTyp = () => {
const elm = $element.find('ul.dropdown-menu[uib-typeahead-popup] > *');
return elm && elm.scope && elm.scope() && elm.scope().isOpen && elm.scope().isOpen();
}
function displayClearButton() {
return manyToOneCtrl.displayClear
}
function displayInfoButton() {
return manyToOneCtrl.displayInfo
}
function getKeyCookie() {
let user = sessionStorage.getItem('user');
if (user) {
user = JSON.parse(user);
return (user.organizationHierarchyCode || '') + 'favorite-' + $attrs.name;
} else {
return 'favorite-' + $attrs.name;
}
}
function modelValueIsObject() {
if (manyToOneCtrl.disabled) return true
if (!manyToOneCtrl.value) return true;
return !(typeof manyToOneCtrl.value === 'object')
}
function disabledDisplayInfo() {
return !(typeof manyToOneCtrl.value === 'object')
}
function clearModel() {
manyToOneCtrl.visible = 'typeahead';
if (manyToOneCtrl.onDeselect) {
manyToOneCtrl.onDeselect({ value: angular.copy(manyToOneCtrl.value) });
}
delete manyToOneCtrl.value;
document.getElementById('typeahead-' + manyToOneCtrl.field + '-' + $attrs.value).focus();
}
function openTypehead() {
manyToOneCtrl.opened = true;
if (manyToOneCtrl.value) {
delete manyToOneCtrl.value;
showTypeheadAndHideMatch();
} else {
if (manyToOneCtrl.isTypeaheadOpen) return;
document.getElementById('typeahead-' + manyToOneCtrl.field + '-' + $attrs.value).focus();
}
delete manyToOneCtrl.lastParam;
manyToOneCtrl.page = 1;
manyToOneCtrl.proxySearch('');
}
function showTypeheadAndHideMatch() {
manyToOneCtrl.visible = 'typeahead';
$timeout(() => {
manyToOneCtrl.value = angular.copy(manyToOneCtrl.inputMatchValue);
openTypehead();
delete manyToOneCtrl.inputMatchValue;
})
}
manyToOneCtrl.isTypeaheadOpen = true;
function displayPlusButton() {
return manyToOneCtrl.postMethod
&& (typeof ngModelCtrl.$$rawModelValue === 'string' || ngModelCtrl.$$rawModelValue instanceof String)
&& ngModelCtrl.$$rawModelValue.length > 0
}
function handlingInputVisible() {
if (manyToOneCtrl.inputMatch) {
let span = document.getElementById('match-' + manyToOneCtrl.field + '-' + $attrs.value);
let inputMatch = manyToOneCtrl.inputMatch.replace(/{/g, '{{').replace(/}/g, '}}').replace(/item/g, 'manyToOneCtrl.value');
let update = '<span style="display: none;" id="match-' + manyToOneCtrl.field + '-' + $attrs.value + '">' + inputMatch + '</span>';
angular.element(span).replaceWith($compile(update)($scope))
$timeout(() => {
let content = document.getElementById('match-' + manyToOneCtrl.field + '-' + $attrs.value);
manyToOneCtrl.inputMatchValue = content.innerHTML;
manyToOneCtrl.visible = 'inputMatchValue';
});
} else {
manyToOneCtrl.visible = 'typeahead';
}
}
function afterSelect($item, $model, $label, $event, isBtn, match) {
delete manyToOneCtrl.opened;
handlingInputVisible();
if (!$model.id && manyToOneCtrl.authorizeAdd) {
manyToOneCtrl.proxySave($model, isBtn);
}
ngModelCtrl.$setValidity('manyToOne', true);
if (manyToOneCtrl.ev.onSelect) manyToOneCtrl.ev.onSelect({ value: $model });
$timeout(() => {
delete manyToOneCtrl.lastParam;
manyToOneCtrl.page = 1;
}, 1000)
}
function openInfo(object = {}, $event) {
manyToOneCtrl.isTypeaheadOpen = true;
$event.stopImmediatePropagation()
$event.preventDefault()
controller.$inject = ['$scope', '$uibModalInstance']
function controller($scope, $uibModalInstance) {
$scope.close = () => $uibModalInstance.close()
}
function mountModalBody() {
let fields = manyToOneCtrl.modalFields
return fields.reduce((prev, next) => {
return prev += `
<div class="form-group">
${ (typeof object[next] === 'string' || object[next] instanceof String) ? `<label>${next}</label>` : ' '}
${ (typeof object[next] === 'string' || object[next] instanceof String) ? `<input type="text" class="form-control" value="${object[next]}" disabled />` : ' '}
</div>`
}, ' ')
}
let template = `
<div class="modal-header">
<h3 class="modal-title">${manyToOneCtrl.modalTitle}</h3>
</div>
<div class="modal-body">
${mountModalBody()}
</div>
`
$uibModal.open({ controller, template })
}
const observeClickBtnRegister = () => {
$element.find('gmto-register-button').click((evt) => {
evt.stopPropagation();
manyToOneCtrl.onRegisterClick({ param: manyToOneCtrl.lastParam });
});
}
$transclude($scope, cloneEl => {
angular.forEach(cloneEl, cl => {
let element = angular.element(cl)[0];
if (element.nodeName && element.nodeName === 'MATCH') {
template = true
manyToOneCtrl.match = element.innerHTML
}
if (element.nodeName && element.nodeName === 'GMTO-REGISTER') {
manyToOneCtrl.templateRegister = element.innerHTML;
}
});
})
manyToOneCtrl.keyUp = ($event) => {
if (manyToOneCtrl.keyDebounce) {
$timeout.cancel(manyToOneCtrl.keyDebounce);
}
if ($event.target.value == '' && $event.keyCode != 40 && $event.keyCode != 38 && manyToOneCtrl.lastValue != $event.target.value) {
manyToOneCtrl.lastValue = $event.target.value;
angular.element($event.target).blur();
$timeout(() => angular.element($event.target).focus());
}
if (manyToOneCtrl.async) {
manyToOneCtrl.keyDebounce = $timeout(() => {
manyToOneCtrl.page = 1;
manyToOneCtrl.lastArray = [];
manyToOneCtrl.proxySearch($event.target.value);
}, (manyToOneCtrl.async ? (manyToOneCtrl.debounce || 1000) : 0));
} else {
manyToOneCtrl.proxySearch($event.target.value);
}
}
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function eraseCookie(name) {
document.cookie = name + '=; Max-Age=-99999999;';
}
manyToOneCtrl.favorite = ($event, model) => {
if ($event) $event.stopPropagation();
if (angular.equals(model, manyToOneCtrl.favoriteModel)) {
eraseCookie(getKeyCookie());
delete manyToOneCtrl.favoriteModel;
return;
}
setCookie(getKeyCookie(), JSON.stringify(model), 999999);
manyToOneCtrl.favoriteModel = model;
}
manyToOneCtrl.isFavorite = model => {
return angular.equals(model, manyToOneCtrl.favoriteModel);
}
manyToOneCtrl.inputBlur = (event) => {
$timeout(() => {
manyToOneCtrl.ngBlur ? manyToOneCtrl.ngBlur(event) : angular.noop()
delete manyToOneCtrl.opened;
delete manyToOneCtrl.noResults;
if (!manyToOneCtrl.value) {
ngModelCtrl.$viewValue = '';
ngModelCtrl.$render();
}
}, 200);
};
manyToOneCtrl.inputFocus = (event) => {
$timeout(() => {
if (manyToOneCtrl.handleOperation) {
manyToOneCtrl.ngFocus ? manyToOneCtrl.ngFocus(event) : angular.noop()
}
manyToOneCtrl.handleOperation = true
manyToOneCtrl.opened = true;
manyToOneCtrl.proxySearch(manyToOneCtrl.lastParam);
})
}
manyToOneCtrl.inputClick = () => {
if (manyToOneCtrl.typeaheadLoading || manyToOneCtrl.opened) return;
if (!manyToOneCtrl.value) {
$element.find('input').blur();
manyToOneCtrl.openTypehead();
$element.find('input').focus();
}
}
/* */
let baseTemplate = `
<style>
gumga-many-to-one [uib-typeahead-popup].dropdown-menu{
width: 100%;
max-height: 210px;
overflow: auto;
}
gumga-many-to-one .item-striped{
background-color: #f5f5f5;
}
gumga-many-to-one a.result {
display: flex;
height: 42px;
align-items: center;
}
gumga-many-to-one a.result > span.str{
display: flex;
}
gumga-many-to-one input{
color: #999 !important;
padding-right: 32px;
font-size: 1.6rem !important;
}
gumga-many-to-one button.left-button{
padding: 0; width: 32px; padding-top: 10px; padding-bottom: 3px;
}
gumga-many-to-one input.form-control.ng-valid-many-to-one{
color: #555 !important;
}
gumga-many-to-one i.favorite{
color: #ccc;
}
gumga-many-to-one i.favorite.full{
color: #d9d90d;
}
gumga-many-to-one i.favorite:hover{
cursor: pointer;
}
gumga-many-to-one .input-group button.btn[ng-click="manyToOneCtrl.openTypehead()"]{
z-index: 3;
}
gumga-many-to-one .progress {
max-width: 100%;
overflow: hidden;
background: #ddd;
left: 0;
width: 100%;
border-radius: 0;
height: 2px;
bottom: 0;
margin: 0;
padding: 0;
bottom: 0;
height: 3px;
z-index: 4;
}
gumga-many-to-one .indeterminate {
position: absolute;
width: 100%;
height: 2px;
transform: translateZ(0);
}
gumga-many-to-one .indeterminate:before, .indeterminate:after {
content: '';
position: absolute;
background-color: #001eff;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
gumga-many-to-one .indeterminate:before {
animation: indeterminate 3s cubic-bezier(0.195, 0.36, 0.945, 1.65) infinite;
}
gumga-many-to-one .indeterminate:after {
animation: indeterminate 3s cubic-bezier(0.9, -0.59, 0.715, 1.045) infinite;
}
@keyframes indeterminate {
0% {
width: 0%;
transform: translateX(-100%);
}
100% {
width: 100%;
transform: translateX(100%);
}
}
gumga-many-to-one input.form-control.gmd.size-55{
padding-right: 55px;
}
gumga-many-to-one input.form-control.gmd.size-25{
padding-right: 25px;
}
gumga-many-to-one.gmd .dropdown-menu > .active > a.item-not-striped, gumga-many-to-one.gmd .dropdown-menu > .active > a.item-not-striped:focus, gumga-many-to-one.gmd .dropdown-menu > .active > a.item-not-striped:hover{
background: #FFF;
}
gumga-many-to-one.gmd .dropdown-menu > .active > a, gumga-many-to-one.gmd .dropdown-menu > .active > a:focus, gumga-many-to-one.gmd .dropdown-menu > .active > a:hover{
cursor: pointer;
}
gumga-many-to-one .dropdown-menu>li>a{
padding: 3px 0px;
}
gumga-many-to-one .register-container{
position: absolute;
left: 0;
width: 100%;
background: #0C82C6;
border: none;
padding: 0 14px;
box-shadow: 0 2px 4px rgba(0,0,0,0.175);
z-index: 9999;
color: #FFF;
display: flex;
align-items: center;
height: 54px;
}
gumga-many-to-one .register-container * {
margin: 0;
}
gumga-many-to-one gmto-register-label{
flex: 1;
}
gumga-many-to-one gmto-register-button{
padding: 8px 16px 8px 16px;
border-radius: 3px;
float: right;
background: #0CCFB2;
cursor: pointer;
text-transform: uppercase;
}
</style>
<div style="position: relative;">
<div class="progress indeterminate" ng-show="manyToOneCtrl.typeaheadLoading"></div>
<div style="width: 100%;" ng-class="{'input-group': (manyToOneCtrl.displayInfoButton() && manyToOneCtrl.modelValueIsObject()) || manyToOneCtrl.displayClearButton()}">
<input type="text"
ng-init="manyToOneCtrl.visible = 'typeahead'"
ng-show="manyToOneCtrl.visible == 'typeahead'"
id="typeahead-${manyToOneCtrl.field}-${$attrs.value}"
class="form-control gmd inputahead"
tabindex="${manyToOneCtrl.tabSeq}"
ng-click="manyToOneCtrl.inputClick()"
ng-disabled="manyToOneCtrl.disabled"
ng-readonly="manyToOneCtrl.readonly"
ng-model="manyToOneCtrl.value"
ng-required="manyToOneCtrl.ngRequired"
ng-focus="manyToOneCtrl.inputFocus($event)"
ng-blur="manyToOneCtrl.inputBlur($event)"
onfocus="this.classList.add('focused')"
ng-class="{'size-25' : manyToOneCtrl.modelValueIsObject() && manyToOneCtrl.displayClearButton(), 'size-55' : !(manyToOneCtrl.modelValueIsObject() && manyToOneCtrl.displayClearButton())}"
ng-keyup="manyToOneCtrl.keyUp($event)"
onblur="this.classList.remove('focused')"
ng-model-options="{ debounce: ${manyToOneCtrl.debounce || 1000} }"
uib-typeahead="$value as $value[manyToOneCtrl.field] for $value in manyToOneCtrl.typeData"
${mirrorAttributes()}
typeahead-template-url="manyToOneTemplate${manyToOneCtrl.field}-${$attrs.value}.html"
typeahead-is-open="manyToOneCtrl.isTypeaheadOpen"
typeahead-editable="${manyToOneCtrl.editable}"
typeahead-show-hint="true"
typeahead-min-length="manyToOneCtrl.minLetter"
typeahead-on-select="manyToOneCtrl.afterSelect($item, $model, $label, $event, 'isNotButton', manyToOneCtrl.match)"
typeahead-no-results="manyToOneCtrl.noResults"
autocomplete="off"/>
<div ng-show="manyToOneCtrl.noResults && !manyToOneCtrl.typeaheadLoading" style="position: absolute; left: 0; width: 100%; top: 34px; background: #FFF; z-index: 999; padding: 15px; border-top: 1px solid #ccc; box-shadow: 0 2px 4px rgba(0,0,0,0.175);">
{{${manyToOneCtrl.messageNoResult} || 'Nenhum resultado foi encontrado.'}}
</div>
<input type="text" ng-keyup="manyToOneCtrl.showTypeheadAndHideMatch()" ng-model="manyToOneCtrl.inputMatchValue" class="form-control" ng-show="manyToOneCtrl.visible == 'inputMatchValue'"/>
<div ng-show="manyToOneCtrl.typeaheadLoading && manyToOneCtrl.loadingText" style="position: absolute; top: 40px;">
<i class="glyphicon glyphicon-refresh"></i>
{{manyToOneCtrl.loadingText}}
</div>
<span ng-hide="true" id="match-${manyToOneCtrl.field}-${$attrs.value}"></span>
<div class="input-group-btn input-group-btn-icon" style="position: absolute; right: {{manyToOneCtrl.modelValueIsObject() && manyToOneCtrl.displayClearButton() ? '25px;' : manyToOneCtrl.displayInfo ? '87px' : '55px'}};" ng-show="(manyToOneCtrl.displayInfoButton() && manyToOneCtrl.modelValueIsObject()) || manyToOneCtrl.displayClearButton()">
<button type="button" style="z-index: 3;" class="left-button btn btn-default gmd" ng-show="!manyToOneCtrl.modelValueIsObject() && manyToOneCtrl.displayClearButton()" ng-click="manyToOneCtrl.clearModel()">
<i ng-show="manyToOneCtrl.useGumgaLayout()" class="material-icons" style="font-size: 15px;">close</i>
<i ng-show="!manyToOneCtrl.useGumgaLayout()" class="glyphicon glyphicon-remove" style="font-size: 15px;"></i>
</button>
<button type="button" class="btn btn-default gmd"
style="padding-bottom: 7px;"
ng-click="manyToOneCtrl.openTypehead()">
<span class="caret"></span>
</button>
<button type="button" style="z-index: 3;" class="left-button btn btn-default gmd" ng-show="!manyToOneCtrl.modelValueIsObject() && manyToOneCtrl.displayInfoButton()" ng-disabled="manyToOneCtrl.disabledDisplayInfo()" ng-click="manyToOneCtrl.openInfo(manyToOneCtrl.value, $event)">
<i class="material-icons" style="font-size: 15px;">remove_red_eye</i>
</button>
</div>
</div>
<div ng-style="manyToOneCtrl.getRegisterStyle()" class="register-container" ng-show="manyToOneCtrl.templateRegister && !manyToOneCtrl.value && (manyToOneCtrl.opened || manyToOneCtrl.isOpenTyp()) && manyToOneCtrl.lastParam">
${ manyToOneCtrl.templateRegister}
</div>
</div>`
let templateForInnerMatch = (!template) ? `<span ng-bind-html="match.model.${manyToOneCtrl.field} | uibTypeaheadHighlight:query"></span>` : `<span>${manyToOneCtrl.match}</span>`
let templateForMatch = `
<a class="col-md-12 result gmd {{ $parent.$parent.$parent.$parent.manyToOneCtrl.withStriped ? ($parent.$index % 2 == 0 ? 'item-striped' : 'item-not-striped') : '' }}" style="white-space: normal;">
<span class="col-md-10 str" ng-click="manyToOneCtrl.select()">
${templateForInnerMatch}
<span ng-show="$parent.$parent.$parent.$parent.manyToOneCtrl.valueToAdd == match.label && $parent.$parent.$parent.$parent.manyToOneCtrl.valueToAdd.length > 0 && !match.model.id && !!$parent.$parent.$parent.$parent.manyToOneCtrl.authorizeAdd">(novo)</span><br>
</span>
<span class="col-md-2">
<span class="icon text-right" ng-if="${manyToOneCtrl.displayInfo}" ng-click="$parent.$parent.$parent.$parent.manyToOneCtrl.openInfo(match.model, $event)" ng-hide="$parent.$parent.$parent.$parent.manyToOneCtrl.valueToAdd == match.label && !match.label.id">
<i class="material-icons" style="font-size: 17px; vertical-align: middle; padding-top: 5px;">remove_red_eye</i>
</span>
<span style="float: right;" ng-show="$parent.$parent.$parent.$parent.manyToOneCtrl.activeFavorite">
<i ng-show="!$parent.$parent.$parent.$parent.manyToOneCtrl.isFavorite(match.model)"
title="Favoritar"
ng-click="$parent.$parent.$parent.$parent.manyToOneCtrl.favorite($event, match.model)"
class="material-icons favorite">star_border</i>
<i ng-show="$parent.$parent.$parent.$parent.manyToOneCtrl.isFavorite(match.model)"
title="Favoritar"
ng-click="$parent.$parent.$parent.$parent.manyToOneCtrl.favorite($event, match.model)"
class="material-icons favorite full">star</i>
</span>
</span>
<div class="clearfix"></div>
</a>
`
$templateCache.put(`manyToOneTemplate${manyToOneCtrl.field}-${$attrs.value}.html`, templateForMatch)
let element = angular.element(baseTemplate),
input = element.find('input'),
form = $element.parent()
while (form[0].nodeName != 'FORM') form = form.parent();
$element.append($compile(element)($scope))
ngModelCtrl = input.controller('ngModel')
ngModelCtrlReset = ngModelCtrl
manyToOneCtrl.ngModelCtrl = ngModelCtrl;
manyToOneCtrl.inputElm = input;
ngModelCtrl.$validators.manyToOne = (modelValue, viewValue) => {
return modelValue ? !(typeof modelValue === 'string' || modelValue instanceof String) : true
}
manyToOneCtrl.useGumgaLayout = () => {
try {
return !!angular.module('gumga.layout');
} catch (error) {
return false;
}
}
if (!modelValueIsObject()) {
handlingInputVisible();
}
$scope.$watch(() => ngModelCtrl.$$rawModelValue, (i) => {
if (ngModelCtrl.$$rawModelValue == '') {
delete ngModelCtrl.$$rawModelValue;
delete manyToOneCtrl.value;
} else {
manyToOneCtrl.valueToAdd = ngModelCtrl.$$rawModelValue;
}
})
if (manyToOneCtrl.infinityPagination) {
startInfinityScroll();
}
observeClickBtnRegister();
}
}
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
value: '=',
minLetter: '=?',
loadingText: '@?',
inputMatch: '@?',
searchMethod: '&',
postMethod: '&?',
onSelect: '&?',
labelsModal: '=?',
activeFavorite: '=?',
onDeselect: '&?',
onRegisterClick: '&?',
list: '=?',
authorizeAdd: '=?',
disabled: '=?',
readonly: '=?',
displayInfo: '=?',
displayClear: '=?',
editable: '=?',
tabSeq: '=?',
async: '=?',
infinityPagination: '=?',
debounce: '@?',
ngRequired: '=?',
ngFocus: '&?',
ngBlur: '&?'
},
controllerAs: 'manyToOneCtrl',
bindToController: true,
controller
}
}
angular.module('gumga.manytoone', ['ui.bootstrap'])
.directive('gumgaManyToOne', ManyToOne);
})();