I'm calling two times the same list in my HTML5 view.
<div class="list" data-ng-repeat="item in model.items">
<div class=list-item">
{{ item.name }}
<a data-ng-click="addToList(item)">
<span data-ng-hide="item.checked">Add</span>
<span data-ng-show="item.checked">Remove</span>
</a>
</div>
</div>
<div class="checkbox-list" data-ng-repeat="item in model.items">
<div class=list-item">
<input type="checkbox" data-ng-checked="item.checked" data-ng-click="addToList(item)" />
{{ item.name }}
</div>
</div>
In my controller, I'm having the method defined in the scope:
function addToList(item) {
item.checked = !item.checked;
for (var i = 0; i < this.$scope.items.length; i++) {
if (this.$scope.items.id == item.id) {
this.$scope.items[i] = item;
break;
}
}
}
When I click the Addor Remove button, the list has an update, but the checkbox-list item doesn't get checked.
On the other hand, when checking a checkbox, the list doesn't get an update.
How can I make this happen?
Looks like you are using controller as syntax.
So in your js code add the model to the controller itself(assuming you yourController refers to the controller and you have your methods in the controller):
for (var i = 0; i < yourController.items.length; i++) {
if (yourController.items.id == item.id) {
yourController.items[i] = extension;
break;
}
}
Inside YourController declare:
var yourController = this;
Then in the HTML where you declare the controller, declare it as follows:
ng-controller = "YourController as yourController"
And then you can access the items in HTML as:
yourController.items
you are mixing the javascript function declaration syntax with angular
While working with angular you should always angular syntax to get the benefit of synchronization between the model and the view.
$scope.addToList = function(){}
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.model = {};
$scope.model.items = [{"name":"one"},{"name":"two"}]
$scope.addToList = function(item) {
item.checked = !item.checked;
}
});
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="list" data-ng-repeat="item in model.items">
<div class="list-item">
{{ item.name }}
<a data-ng-click="addToList(item)">
<span data-ng-hide="item.checked">Add</span>
<span data-ng-show="item.checked">Remove</span>
</a>
</div>
</div>
<div class="checkbox-list" data-ng-repeat="item in model.items">
<div class="list-item">
<input type="checkbox" data-ng-checked="item.checked" data-ng-click="addToList(item)" />
{{ item.name }}
</div>
</div>
</body>
</html>
You are not using function with $scope. This might help:
$scope.addToList = function (item) {
item.checked = !item.checked;
for (var i = 0; i < $scope.items.length; i++) {
if ($scope.items.id == item.id) {
$scope.items[i] = extension;
break;
}
}
}
Related
I am working on a small application that displays a "users" JSON in an HTML5 table. It uses Bootstrap 3 and AngularJS. I want to paginate this table.
I do not have an array to loop through, with ng-repeat. I have a number the number of pages.
With jQuery, I would do:
var pageMax = 10;
var paginationItems = [];
for(var i=0; i<pageMax; i++){
var paginationItem = '<li>' + (i + 1) + '</li>';
paginationItems.push(paginationItem);
}
var paginationSum = paginationItems.reduce((a, b) => a + b, '');
$('.pagination').html(paginationSum);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="text-center">
<ul class="pagination"></ul>
</div>
What is the equivalent of the above for loop in AngularJS?
In angular you would do something like this:
angular.module('app', [])
.controller('Controller', function($scope) {
$scope.pageMax = 10;
$scope.pages = new Array($scope.pageMax);
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<body ng-app="app">
<div ng-controller="Controller">
<div class="text-center">
<h3>Initialized in template:</h3>
<ul class="pagination">
<li ng-repeat="n in [].constructor(pageMax) track by $index">
{{$index+1}}
</li>
</ul>
<h3>Initialized in controller:</h3>
<ul class="pagination">
<li ng-repeat="n in pages track by $index">
{{$index+1}}
</li>
</ul>
</div>
</div>
</body>
You can use ng-repeat do to this.
Notice that when you want to render the HTML you have to use $sce.trustAsHtml for AngularJS to actually render the HTML. You can then use ng-bind-html in the HTML.
var app = angular.module("Dummy", []);
var DummyController = function($scope, $sce) {
var pageMax = 10;
$scope.paginationItems = [];
for (var i = 0; i < pageMax; i++) {
var item = $sce.trustAsHtml('' + (i + 1) + '');
$scope.paginationItems.push(item);
}
}
app.controller(DummyController, ["$scope, $sce", "DummyController"]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="Dummy">
<div class="text-center" ng-controller="DummyController">
<ul class="pagination">
<li ng-bind-html="item" ng-repeat='item in paginationItems'></li>
</ul>
</div>
</div>
I need to get the $index in a javascript function to implement prev/next buttons for a list of values. The method I found seems cumbersome, perhaps there is a more straightforward way.
Now I do this to get the $index in javascript, then put it in an observable:
<div data-bind="foreach: myarray">
<div data-bind="click: function(data, event){ onclick(data, event, $index()); }"
function onclick(idata, event, index) {
theAppViewModel.choiceindex(index);
On SO I found a small improvement by getting $index from the event:
<div data-bind="foreach: myarray">
<div data-bind="click: onclick"
function onclick(idata, event) {
var context = ko.contextFor(event.target);
theAppViewModel.choiceindex(context.$index());
From a commenter came the method to get the index by searching the array for the selected value, that usually has its own observable, e.g. choice:, like:
var i = TheArray.indexOf(theAppViewModel.choice());
Normally, the length of the array on the page isn't huge, and if it has big objects, you could just search over one of its fields with fun syntax like:
myarray.find(x => x.id === searchvalue);
But I wonder if it isn't possible to access the $index even more directly, without storing in my own observable choiceindex, as the Knockout docs say that $index is already an observable.
Here is a complete sample code to play with:
<!DOCTYPE html>
<html>
<head>
<title>Test Knockout Foreach</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js'></script>
<style>
.selected {background-color: #f0f0f0;}
</style>
</head>
<body>
<div data-bind="foreach: myarray" style="width: 10em;">
<div data-bind="click: function(data, event){ onclick(data, event, $index()); },
css: { selected: $data == $root.choice() }">
<span data-bind="text: $index"></span>
<span data-bind="text: $data"></span>
</div>
</div>
<input type="button" value="Prev" data-bind="click: onprev" />
<input type="button" value="Next" data-bind="click: onnext" />
<p>
Choice:
<span data-bind="text: choice"></span>
</p>
<p>
Index:
<span data-bind="text: choiceindex"></span>
</p>
<script>
var TheArray = ["apple", "pear", "banana", "coconut", "peanut"];
function onclick(idata, event, index) {
theAppViewModel.choice(idata);
theAppViewModel.choiceindex(index);
//var context = ko.contextFor(event.target);
//theAppViewModel.choiceindex(context.$index());
//theAppViewModel.choiceindex(index);
}
function onprev(idata, event) {
var i = theAppViewModel.choiceindex() - 1;
if (i >= 0) {
theAppViewModel.choice(TheArray[i]);
theAppViewModel.choiceindex(i);
}
}
function onnext(idata, event) {
//var i = theAppViewModel.choiceindex() + 1;
//var dummydata = theAppViewModel.choice();
//var dummy = TheArray.indexOf(dummydata);
var i = TheArray.indexOf(theAppViewModel.choice()) + 1;
if (i < TheArray.length) {
theAppViewModel.choice(TheArray[i]);
theAppViewModel.choiceindex(i);
}
}
function AppViewModel() {
var self = this;
self.myarray = ko.observableArray(TheArray);
self.choice = ko.observable();
self.choiceindex = ko.observable();
}
var theAppViewModel = new AppViewModel();
window.onload = function () {
ko.applyBindings(theAppViewModel);
}
</script>
</body>
</html>
There is no built-in binding to set a viewmodel value from a binding, but it's simple create one to do so:
ko.bindingHandlers.copyIndex = {
init: function (element, valueAccessor, allBindings, vm, bindingContext) {
vm.index = bindingContext.index;
}
};
The use it as follows:
<div data-bind="foreach: myarray">
<div data-bind="copyIndex"></div>
</div>
However, I'd still not recommend this approach, since it ties viewmodel behavior to the presence of specific bindings. Jason Spake's suggestion to use myarray.indexOf($data) (or ko.utils.arrayIndexOf(myarray, $data)) would be more robust.
write 'index' and not 'index()' in the html part.
Try this:
<div data-bind="foreach: myarray" style="width: 10em;">
<div data-bind="click: function(data, event){ onclick(data, event, $index},
css: { selected: $data == $root.choice() }">
<span data-bind="text: $index"></span>
<span data-bind="text: $data"></span>
</div>
</div>
I'm very new to Angular js and am testing a few functions with a simple data-parser project (Plunkr). Right now, I'm having trouble accessing $scope variable within a jQuery on click event. I would like to keep some elements hidden until an image is clicked. While I can set ng-hide to true within the controller, $scope does not appear to work inside an on click handler. Please help.
zodiac.html
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div id="container" ng-app="myApp" ng-controller="myCtrl">
<div>
<h1>What Animal Are You?</h1>
<div id="selectPicture"></div>
</div>
<div id="zodiac" ng-hide="disappear">
<h1>Your Zodiac</h1>
<div id="your-zodiac">
</div>
<br>
<h1>Avoid these Animals</h1>
<div id="hateDiv">
</div>
<br>
<h1>These Are Your Besties</h1>
<div id="loveDiv">
</div>
</div>
<script src="scripts.js"></script>
</div>
</body>
scripts.js
function d(c) {
console.log(c)
}
var app = angular.module('myApp', [])
app.controller('myCtrl', function($scope, $http) {
$http.get('zodiac.json').success(function(data) {
$scope.disappear = true //WORKS HERE
$scope.animalsData = data
angular.forEach($scope.animalsData, function(item) {
$('#selectPicture').prepend('<img src="' + item.picture + '" alt="' + item.animal + '">')
})
$('#selectPicture').on('click', 'img', function($scope) {
$scope.disappear = false //DOES NOT WORK HERE
$('#zodiac div').empty();
findZodiac(this.alt, "#your-zodiac", true);
})
function findZodiac(animal, e, test) {
angular.forEach($scope.animalsData, function(item) {
if (item.animal == animal) { //look for the right object 'item', when found, get the image
//item.picture
$(e).prepend('<img src="' + item.picture + '">')
if (test == true) {
loveHate(item.hate, "#hateDiv")
loveHate(item.love, "#loveDiv")
}
return
}
})
}
function loveHate(array, e) {
angular.forEach(array, function(value) { //loops through an array, get each animal
findZodiac(value, e, false)
})
}
});
})
In my opinion you should not do DOM manipulation directly when using AngularJS. Use the directives provided by AngularJS instead. Here are the template and controller code if you do so -
zodiac.html
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div id="container" ng-app="myApp" ng-controller="myCtrl">
<div>
<h1>What Animal Are You?</h1>
<div id="selectPicture">
<img ng-repeat="animal in animalsData"
ng-src="{{animal.picture}}"
alt="{{animal.animal}}"
ng-click="disappear=false; findZodiac(animal)" />
</div>
</div>
<div id="zodiac" ng-hide="disappear">
<h1>Your Zodiac</h1>
<div id="your-zodiac">
<img ng-src="{{selectedAnimal.picture}}" alt="{{selectedAnimal.animal}}" />
</div>
<br>
<h1>Avoid these Animals</h1>
<div id="hateDiv">
<img ng-repeat="animal in selectedAnimal.hate"
ng-src="{{animal.picture}}"
alt="{{animal.animal}}" />
</div>
<br>
<h1>These Are Your Besties</h1>
<div id="loveDiv">
<img ng-repeat="animal in selectedAnimal.love"
ng-src="{{animal.picture}}"
alt="{{animal.animal}}" />
</div>
</div>
<script src="scripts.js"></script>
</div>
</body>
scripts.js
var app = angular.module('myApp', [])
app.controller('myCtrl', function($scope, $http) {
$scope.animalsData = [];
$scope.selectedAnimal = {};
$scope.disappear = true;
$scope.findZodiac = function(animal) {
$scope.selectedAnimal = animal;
};
$http.get('zodiac.json').success(function(data) {
$scope.animalsData = data;
});
});
In AngularJS $scope is a global variable for your controller, You don't need to pass it like this. directly use it as
$('#selectPicture').on('click','img',function(){
$scope.disappear=false;//this will work
$('#zodiac div').empty();
findZodiac(this.alt,"#your-zodiac",true);
})
check this corrected version
scope object only available in angular world.
I using simple syntax to show, hide element in ng-repeat
<div ng-controller='MainController as vm'>
<ul>
<li ng-repeat="item in vm.items" ng-click="vm.showItem()">
{{item}}
<span ng-show="show">test</span>
</li>
</ul>
When i was using scope everythink worked fine
$scope.showItem = function(){
this.show=!this.show;
}
But same code with controllerAs doesn't work
vm = this;
vm.showItem = function(){
this.show=!this.show;
}
How can i access to show property of current item in ng-repeat?
Controller as http://plnkr.co/edit/Dbp5fO9OEpV6lFRySYUK?p=preview
$scope http://plnkr.co/edit/ptuySNRXSrA64K1IAng3?p=preview
Get the current this instance from the html like
<li ng-repeat="item in vm.items" ng-click="vm.showItem(this)">
And use it in your controller
vm.showItem = function(_this){
_this.show=!_this.show;
}
The problem you faced is the change of this context
Updated plunker http://plnkr.co/edit/pkxI68sGMXonDOA49EUq?p=preview
Proof of concept:
var app = angular.module('myApp', []);
app.controller('MainController', function() {
vm = this;
vm.items = [];
for (var i = 0; i < 10; i++) vm.items.push({
value: i,
show: false,
showItem: function() {
this.show = !this.show
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MainController as vm">
<ul>
<li ng-repeat="item in vm.items" ng-click="item.showItem()">
{{item.value}}
<span ng-show="item.show">test</span>
</li>
</ul>
</div>
</div>
Than we are going to improve it by extracting showItem method to the Item prototype
Second step - using prototype to less memory consume
var app = angular.module('myApp', []);
app.controller('MainController', function() {
vm = this;
vm.items = [];
for (var i = 0; i < 10; i++) vm.items.push(new Item(i));
function Item(value) {
this.value = value
this.show = false
}
Item.prototype.showItem = function() {
this.show = !this.show
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MainController as vm">
<ul>
<li ng-repeat="item in vm.items" ng-click="item.showItem()">
{{item.value}}
<span ng-show="item.show">test</span>
</li>
</ul>
</div>
</div>
Next step will be extracting Item to angular factory
You need to use vm.show = !vm.show;
vm = this;
vm.showItem = function(){
vm.show=!vm.show;
}
Replace the function definition with.
vm.show = !vm.show;
I have attached the sample code snippet.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="angular.js#1.5.5" data-semver="1.5.5" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script>
var app = angular.module('myApp', []);
app.controller('MainController', function () {
vm = this;
vm.items = [];
vm.start = 0;
vm.end = 20;
for (var i = 0; i < 10; i++) vm.items.push(i);
// return vm;
vm = this;
vm.show = true;
vm.showItem = function () {
vm.show = !vm.show;
}
});
</script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller='MainController as vm'>
<ul>
<li ng-repeat="item in vm.items" ng-click="vm.showItem()">
{{item}}
<span ng-show="vm.show">test</span>
</li>
</ul>
</div>
</div>
</body>
</html>
I am looking for a component like this to be included in my project:
http://geodan.github.io/duallistbox/sample-100.html
I want to install it with npm.
The problem is that I tested some of the examples which are over there, but without success (I get exceptions, or there is no npm, only bower)
These are the examples I tested.
https://github.com/alexklibisz/angular-dual-multiselect-directive
https://github.com/frapontillo/angular-bootstrap-duallistbox
http://www.bootply.com/mRcBel7RWm
Any recommendations about one with AngularJs, Bootstrap, and npm?
This might solve your requirement: Dual list Box
app.js
angular.module('plunker', [])
.controller('MainCtrl', function($scope, utils) {
$scope.list1 = [],
$scope.list2 = [];
utils.insertData($scope.list1, 5);
})
.factory('utils', function Utils() {
return {
insertData: function(list, numItems) {
for (var i = 0; i < numItems; i++) {
list.push({
id: i + 1,
title: 'item' + (i + 1)
});
}
},
getIndexesFromList: function(list) {
var newList = [];
for (var i in list) {
if (typeof list[i].id === "number" && newList.indexOf(list[i].id) === -1) newList.push(list[i].id)
}
return newList;
},
getAllSelectedItems: function(list) {
var newList = [];
newList = list.filter(function(el) {
return el.active === true;
});
return newList;
},
addListIfNoExists: function(list2, newListToAppend) {
var indexes = this.getIndexesFromList(list2);
var newList = [];
for (var i in newListToAppend) {
if (indexes.indexOf(newListToAppend[i].id) === -1) list2.push(newListToAppend[i])
}
return list2;
}
}
})
.directive('dualList', function(utils) {
function _controller($scope) {
$scope.selectAllItem = function(list, checked) {
list.map(function(item) {
item.active = checked
return item;
});
};
$scope.getAllSelectedItems = function(list) {
return utils.getAllSelectedItems(list);
}
$scope.moveItemToRightList = function() {
var newListToAppend = $scope.list1.filter(function(el) {
if (el.active === true) {
el.active = false;
return el;
}
});
if (newListToAppend.length > 0) {
$scope.list1 = $scope.list1.filter(function(el) {
return utils.getIndexesFromList(newListToAppend).indexOf(el.id) === -1;
});
$scope.list2 = utils.addListIfNoExists($scope.list2, newListToAppend);
if ($scope.list1.length === 0) $scope.checked1 = false;
}
};
$scope.moveItemToLeftList = function() {
var newListToAppend = $scope.list2.filter(function(el) {
if (el.active === true) {
el.active = false;
return el;
}
});
if (newListToAppend.length > 0) {
$scope.list2 = $scope.list2.filter(function(el) {
return utils.getIndexesFromList(newListToAppend).indexOf(parseInt(el.id)) === -1;
});
$scope.list1 = utils.addListIfNoExists($scope.list1, newListToAppend);
if ($scope.list2.length === 0) $scope.checked2 = false;
}
};
}
return {
restrict: "E",
scope: true,
controller: _controller,
templateUrl: "dualList.html"
};
});
dualList.html
<div class="container">
<br />
<div class="row">
<div class="dual-list list-left col-md-5">
<div class="well text-right">
<div class="row">
<div class="col-md-3">
<div class="checkbox">
<label>
<input type="checkbox"
ng-model="checked1"
ng-click="selectAllItem(list1, checked1)">
Todo {{getAllSelectedItems(list1).length}}/{{list1.length}}
</label>
</div>
</div>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-addon glyphicon glyphicon-search"></span>
<input type="text"
name="SearchDualList"
ng-model="search1"
class="form-control"
placeholder="search" />
</div>
</div>
</div>
<ul class="list-group">
<a class="list-group-item"
href=""
data-id="{{item.id}}"
ng-click="item.active = !item.active"
ng-class="{active: item.active}"
ng-repeat="item in list1|filter: search1">{{item.title}}</a>
</ul>
<p ng-if="(list1 | filter:search1).length == 0">Sin Datos</p>
</div>
</div>
<div class="list-arrows col-md-1 text-center">
<button ng-click="moveItemToLeftList()"
class="btn btn-default btn-sm move-left">
<span class="glyphicon glyphicon-chevron-left"></span>
</button>
<button ng-click="moveItemToRightList()"
class="btn btn-default btn-sm move-right">
<span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
<div class="dual-list list-right col-md-5">
<div class="well">
<div class="row">
<div class="col-md-3">
<div class="checkbox">
<label>
<input type="checkbox"
ng-model="checked2"
ng-click="selectAllItem(list2, checked2)">
Todo {{getAllSelectedItems(list2).length}}/{{list2.length}}
</label>
</div>
</div>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-addon glyphicon glyphicon-search"></span>
<input type="text"
name="SearchDualList"
ng-model="search2"
class="form-control"
placeholder="search" />
</div>
</div>
</div>
<ul class="list-group">
<a class="list-group-item"
href=""
data-id="{{item.id}}"
ng-click="item.active = !item.active"
ng-class="{active: item.active}"
ng-repeat="item in list2|filter: search2">{{item.title}}</a>
</ul>
<p ng-if="(list2 | filter:search2).length == 0">Sin Datos</p>
</div>
</div>
</div>
</div>
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="jquery#*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://code.angularjs.org/1.3.0/angular.js"></script>
<link data-require="bootstrap#*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<link data-require="bootstrap#*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" />
<link data-require="font-awesome#*" data-semver="4.3.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<dual-list data-list1="list1" data-list2="list2"></dual-list>
</body>
</html>
style.css
.dual-list .list-group {
margin-top: 8px;
}
.list-arrows {
padding-top: 100px;
}
.list-arrows button {
margin-bottom: 20px;
}
.list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus {
border-color: white;
}
.input-group-addon {
top: 0;
}
I think this link will help you.
Try this npm for angular 2/4 just you need to install with npm
https://www.npmjs.com/package/ng2-dual-list-box