Popup
by namlth
HTML
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://github.com/SteveSanderson/knockout-projections/blob/master/dist/knockout-projections.js"></script>
<link rel="stylesheet" href="https://rawgit.com/daneden/animate.css/master/animate.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>
<div class="container main-container">
<div class="row mt-3">
<div class="col-12">
<div class="form-group">
<div class="input-group address-book-group">
<input type="text" class="form-control" data-bind="value: activeItem().name"/>
<a href="#" class="btn btn-address-book" data-bind="click: addressBookClick">
<i class="fa fa-address-book"></i>
</a>
<div class="address-book-popup animated"
data-bind="css: {
'active fadeIn': isActive,
'no-arrow': hasNoArrow,
'top-zero': hasTopZero,
'no-padding': hasNoPadding
}">
<div class="panel-top">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text input-group-text--mod"><i class="fa fa-search"></i></span>
</div>
<input type="text" class="form-control form-control--mod" placeholder="Search" data-bind="value: filter, valueUpdate: 'afterkeyup'"/>
<div class="input-group-append">
<span class="input-group-text...
SCSS
.main-container {
//min-height: 500px;
//overflow-y: auto;
}
.btn-address-book:focus {
//border: 1px solid blue;
outline: none;
box-shadow: none;
}
.btn-close {
color: lightgray;
}
.address-book-group {
position: relative;
}
.address-book-popup {
animation-duration: 2s;
display: none;
position: absolute;
z-index: 9999;
background: white;
left: 0;
top: 100%;
border: 1px solid black;
border-radius: 0.25rem;
-webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
width: 100%;
//min-height: 50vmin;
//max-height: 70vmin;
margin-top: 0.25rem;
//background: lightblue;
flex-direction: column;
justify-content: space-between;
padding: 0.5rem;
.input-group-prepend {
.input-group-text--mod {
background: none;
border: none;
position: absolute;
top: 50%;
z-index: 9999;
transform: translateY(-50%);
}
}
.form-control--mod {
padding-left: 40px;
border-radius: 0.25rem !important;
}
.input-group-append {
.input-group-text--mod {
background: none;
border: none;
}
}
.btn-main {
border: none;
border-radius: 0;
background: none;
width: 100%;
border-right: 1px solid blue;
color: green;
}
.btn-main:focus {
outline: none;
box-shadow: none;
}
.panel-top {}
.panel-bottom {
display: flex;
margin-bottom: -0.5rem;
margin-left: -0.5rem;
margin-right: -0.5rem;
border-top: 1px solid blue;
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
}
.panel-main {
//background: lightgreen;
//height: 100%;
//min-height: 30vh;
max-height: 60vh;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
position: relative;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
.list-group-item.active {
background: lightgray;
}
...
TypeScript
function myModel() {
var that = this;
/*
** Setup UI
*/
that.hasNoArrow = ko.observable(false);
that.hasTopZero = ko.observable(false);
that.hasNoPadding = ko.observable(false);
/* end */
that.items = ko.observableArray([
{ id: 1, name: 'Nam Le 1' },
{ id: 2, name: 'Nam Le 2' },
{ id: 3, name: 'Nam Le 3' },
{ id: 4, name: 'Nam Le 4' },
{ id: 5, name: 'Nam Le 5' },
{ id: 6, name: 'Nam Le 6' },
{ id: 7, name: 'Nam Le 7' },
{ id: 8, name: 'Nam Le 8' },
{ id: 9, name: 'Nam Le 9' },
{ id: 10, name: 'Abc 10' },
{ id: 11, name: 'Zye 11' },
{ id: 12, name: 'Eye 12' },
{ id: 13, name: 'Mouse 13' },
]);
that.filter = ko.observable("");
that.filteredItems = ko.dependentObservable(function() {
var filter = that.filter().toLowerCase();
if (!filter) {
return that.items();
} else {
return ko.utils.arrayFilter(that.items(), function(item) {
return item.name.toLowerCase().indexOf(filter) !== -1;
});
}
});
that.isActive = ko.observable(false);
that.activeItemId = ko.observable(0);
that.activeItem = ko.computed(() => {
if (that.activeItemId() === 0) return "";
var item = that.items().filter((x) => { return x.id === that.activeItemId() })[0];
var itemArray = ko.utils.arrayFilter(that.items(), (itemA) => {
return itemA.id === that.activeItemId();
});
alert(itemArray);
return item;
});
that.isItemActive = (itemId) => {
return itemId === that.activeItemId();
};
that.addressBookClick = () => {
that.isActive(!that.isActive());
};
that.addressItemClick = (itemId) => {
that.activeItemId(itemId);
};
};
ko.applyBindings(new myModel());