Flickering issue when drawing div in Angular - angularjs

In this plunk I have a div that needs to be drawn dragging the mouse. I'm using mouse up/move/down events. The problem that I have is that the div "flickers" when I drag down. How to fix this?
HTML
<style>
.frame {
width: 300px;
height: 300px;
background-color: orange;
position: relative;
}
.sel{
border:2px solid black;
background-color: #ffffff;
position:absolute;
}
</style>
<div class="frame" ng-mousedown="mouseDown($event)"
ng-mousemove="mouseMove($event)"
ng-mouseup="mouseUp()">
<div class="sel" ng-show="show"
ng-style="{top:selTop+'px', left:selLeft+'px', width:selWidth+'px', height:selHeight+'px'}"></div>
</div>
Javascript:
var app = angular.module('app', []);
app.controller('ctl', function ($scope) {
$scope.startPoint = {};
$scope.show = false;
$scope.mouseDown = function(event) {
$scope.startPoint = { x: event.offsetX, y: event.offsetY };
$scope.show = true;
};
$scope.mouseMove = function(event) {
if (!$scope.startPoint.x)
return;
$scope.selTop = $scope.startPoint.y;
$scope.selLeft = $scope.startPoint.x;
$scope.selHeight = event.offsetY - $scope.startPoint.y;
$scope.selWidth = event.offsetX - $scope.startPoint.x;
};
$scope.mouseUp = function() {
$scope.startPoint = {};
$scope.show = false;
};
});

just add these css properties
border: none;
color: transparent;
text-shadow: 0 0 0 gray;
text-align: center;
&:focus {
outline: none;
}
see the plunker http://embed.plnkr.co/9WntGyBLQxYSxkFjDAy2/

Related

Video Follow on Mouse Move in React

I have this javascript function that autoplays a Vimeo video and attaches to the cursor when hovering over an element. I'm trying to figure out how to do this in React but I'm not having any luck. Originally, I was using Froogaloop and Vimeo player api which seemed to work just fine, but not in react.
Here is the code below
Script
document.getElementById("div").addEventListener("mousemove", function() {
myFunction(event);
});
var mouse;
var cursor = document.getElementById("cursor");
function myFunction(e) {
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX - 55) + "px";
cursor.style.top = (mouseY - 55) + "px";
}
// play video on hover
const iframe = document.getElementById('video');
// $f == Froogaloop
const player = $f(iframe);
// bind events
var mouseEntering = document.getElementById("div");
mouseEntering.addEventListener("mouseenter", function() {
player.api("play");
});
var mouseLeaving = document.getElementById("div");
mouseLeaving.addEventListener("mouseleave", function() {
player.api("unload");
});
HTML
<div id="div" class="div">
<div id="cursor" class="cursor">
<iframe id="video" class="video" src="https://player.vimeo.com/video/649593940?api=1&loop=1&muted=1" width="400px"
height="300px" frameborder="0"></iframe>
</div>
</div>
CSS
.wrapper{
display:grid;
grid-template-columns: repeat(auto-fit, minmax(241px,1fr));
gap: 20px;
}
.div:hover{
cursor:pointer;
}
.div:hover .cursor{
visibility:visible;
}
.cursor {
visibility:hidden;
position: absolute;
transform:translate(80px,50px);
background:red;
backface-visibility: hidden;
z-index: 9999999;
pointer-events: none; /* pointer-events: none is needed */
cursor: none;
}
.div {
background: blue;
height:200px;
width:100%;
cursor: none;
}
Here is a full working example on codepen
Any help on how to do this in react would be awesome.

Can't get this simple ng-submit to work

I'm learning AngularJS by working through this on YouTube tutorial and I've hit a block on the 14th video with the ng-submit directive.
See code snipit below, when you fill in the form at the bottom and click submit it's supposed to add a new Ninja, but it's not working. There are no errors showing in the console. I placed a debugger breakpoint within the addNinja() function definition and it doesn't go into it when I click submit.
Any idea what I'm doing wrong?
var myNinjaApp = angular.module('myNinjaApp',[]);
myNinjaApp.controller('NinjaController', ['$scope',function($scope){
$scope.removeNinja = function(ninja){
var removeNinja = $scope.ninjas.indexOf(ninja);
$scope.ninjas.splice(removeNinja, 1);
};
$scope.addNinja = function(){
$scope.ninjas.push({
name: $scope.newninja.name,
belt: $scope.newninja.belt,
rate: parseInt($scope.newninja.rate),
available: true
});
};
// $scope.addNinja = function() {
// $scope.ninjas.push(this.newninja);
// $scope.newninja = '';
// };
$scope.ninjas = [
{
name: "Yoshi",
belt: "green",
rate: 50,
available: true
},
{
name: "Crystal",
belt: "yellow",
rate: 30,
available: true
},
{
name: "Ryu",
belt: "orange",
rate: 10,
available: false
},
{
name: "Shaun",
belt: "black",
rate: 1000,
available: true
}
];
}]);
body{
font-family: Helvetica;
margin: 0;
}
h1,h2,h3{
margin: 0;
}
.belt{
padding: 5px 10px;
border-radius: 10px;
margin-left: 5px;
color: #fff;
font-size: 15px;
text-transform: uppercase;
}
#menu-bar{
background: crimson;
color: #fff;
padding: 10px;
}
#menu-bar h1{
font-size: 24px;
font-weight: normal;
display: inline-block;
}
#menu-bar ul{
float: right;
list-style-type: none;
padding: 0;
margin: 6px 0;
}
#menu-bar li{
float: right;
margin-left: 20px;
}
#menu-bar a{
color: #fff
}
main{
background: #eee;
width: 80%;
margin: 30px auto;
border-radius: 10px;
}
.content{
padding: 20px;
}
.content button,
.content input[type="submit"]{
background: #fff;
padding: 10px;
border-radius: 10px;
cursor: pointer;
color: #777;
border: 0;
box-shadow: 2px 2px 2px rgba(20,20,20,0.1);
font-size: 16px;
}
.content button:nth-child(2){
float: right;
}
.content ul{
padding: 0;
list-style-type: none;
margin: 30px 0;
}
.content li{
padding: 15px 0;
border-top: 1px solid #e2e2e2;
color: #444;
}
.content li span{
float: right;
}
.content li h3{
display: inline-block;
font-weight: normal;
font-size: 22px;
}
.content input{
width: 90%;
padding: 10px 5%;
border-radius: 10px;
border: 2px solid #ddd;
margin: 10px 0;
}
.content input[type="submit"]:last-child{
width: 150px;
display: block;
margin: 15px auto;
}
.remove{
float: right;
padding: 5px;
background: #fff;
width: 18px;
text-align: center;
border-radius: 20px;
color: crimson;
cursor: pointer;
margin-left: 10px;
}
<!DOCTYPE html>
<html lang="en" ng-app="myNinjaApp">
<head>
<title>TheNetNinja Angular Playlist</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div class="content">
<div ng-controller="NinjaController">
<button ng-click="order = 'name'">Order by Name</button>
<button ng-click="order = 'belt'">Order by Belt</button>
<input type="text" ng-model="search" placeholder="Search for a ninja">
<ul>
<li ng-repeat="ninja in ninjas | orderBy: order | filter: search" ng-show="ninja.available">
<h3>{{ninja.name}} - {{ninja.rate | currency: '£'}}</h3>
<div class="remove" ng-click="removeNinja(ninja)">x</div>
<span class="belt" style="background: {{ninja.belt}}">{{ninja.belt}} belt</span>
</li>
</ul>
</div>
<form ng-submit="addNinja()">
<input type="text" placeholder="name" ng-model="newninja.name" />
<input type="text" placeholder="belt" ng-model="newninja.belt" />
<input type="text" placeholder="rate" ng-model="newninja.rate" />
<input type="submit" value="Add new ninja">
</form>
<p>{{newninja}}</p>
</div>
</body>
</html>
You have a div in the wrong place - move </div> above <form ng-submit="addNinja()"> to after <p>{{newninja}}</p>
bascially the ng-submit is not within the ninjacontroller div
see - https://plnkr.co/edit/pPucxMw0Yjr9OZoxl0vy?p=preview for a working version
myNinjaApp.controller('NinjaController', ['$scope', '$http', '$log', function ($scope, $http, $log) {
$http({
url: "data/ninjas.json",
method: "GET"
}).then(function (resp) {
//$log.log(resp.data);
$scope.ninjas = resp;
}, function (resp) {
$log.error("ERROR Occurred");
//debugger;
});
$scope.removeNinja = function (ninja) {
var removeNinja = $scope.ninjas.indexOf(ninja);
$scope.ninjas.splice(removeNinja, 1);
}
$scope.addNinja = function () {
$scope.ninjas.push({
name: $scope.newninja.name,
belt: $scope.newninja.belt,
rate: parseInt($scope.newninja.rate),
available: true
});
$scope.newninja.name = "";
$scope.newninja.belt = "";
$scope.newninja.rate = "";
};
$scope.removeAll = function () {
$scope.ninjas = [];
};
$scope.sort = function (keyname) {
$scope.sortKey = keyname;
$scope.reverse = !$scope.reverse;
}
}]);

Working example od Angular google maps search address

I have problem with adding search by address option to my angular google maps code...
http://jsfiddle.net/lukasz9999/bmp62fan/
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(30.0000, -98.0000),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
I suppose that I have to add a geocoder somehow but I don't know how.
If someone has a working example of Angular Google Map set position by address it would be great
Thank You
I would suggest to utilize Autocomplete feature for that purpose, below is provided the modified example:
Note: since Autocomplete is a feature of the Places library, be sure
to include it, e.g. libraries=places
angular.module('mapsApp', [])
.controller('MapCtrl', function ($scope) {
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(-33.8688, 151.2195),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
//init autocomplete
var input = document.getElementById('pac-input');
$scope.map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var autocomplete = new google.maps.places.Autocomplete(input);
//autocomplete.bindTo('bounds', $scope.map);
autocomplete.addListener('place_changed', function () {
setPlace();
});
var setPlace = function () {
//infoWindow.close();
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
$scope.map.fitBounds(place.geometry.viewport);
} else {
$scope.map.setCenter(place.geometry.location);
}
createMarker({ lat: place.geometry.location.lat(), lng: place.geometry.location.lng(), address: place.formatted_address });
}
var createMarker = function (info) {
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.lng),
title: info.address
});
marker.content = '<div class="infoWindowContent">' + info.address + '</div>';
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent('<h2>' + marker.title + '</h2>' + marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
$scope.openInfoWindow = function (e, selectedMarker) {
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
});
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 600px;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
<script src="http://code.angularjs.org/1.2.10/angular.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<div ng-app="mapsApp" ng-controller="MapCtrl">
<input id="pac-input" class="controls" type="text" placeholder="Enter a location">
<div id="map"></div>
</div>
JSFiddle

How does one create an accordion dropdown menu in Angular Material?

If you go to the https://material.angularjs.org website,
you will notice a very nice Accordion dropdown menu in the sidenav.
I'm trying to find a simplified version of this feature.
I've looked into many examples it appears many of them are no longer working.
I don't need it complicated. So no need of repetative items. I can do all that. I need the basic functionality.
From what I've researched they have an expando feature being developed, but until then is there a work around?
Updated:
I wasn't able to find a good angular material design, but I was able to find an angular method.
https://github.com/sherwaniusman/angular-accordion
The following fiddle really helped me:
Accordion example
I have also added functionality which allows expanding only 1 menu at a time, if others opened, it will automatically close them.
Code in Controller:
function controller($scope) {
$scope.accordianData = [
{ "heading" : "About Us", "content" : "" },
{ "heading" : "Terms of Use", "content" : "" },
{ "heading" : "Privacy Policy", "content" : "" },
{ "heading" : "Help", "content" : "" },
];
);
// To expand or collapse the current view
//This functionality automatically closes the other expanded lists
$scope.toggleView = function(ary, data, index){
for(var i=0; i<ary.length; i++){
if(i!=index) { ary[i].expanded=false; }
else { data.expanded=!data.expanded; }
}
}
}
And the view/html Code is:
Just tweaked a bit of functionality as per my requirements:
<md-content id="dynamic-content" class="f-clear-padding">
<div class="md-accordion" ng-repeat="data in accordianData">
<!-- <md-toolbar ng-init="data.expanded = false" ng-click="data.expanded = !data.expanded"> this was the code in demo-->
<md-toolbar ng-init="data.expanded = false" ng-click="toggleView(accordianData, data, $index)">
<div class="md-toolbar-tools">
<!-- <h2> -->
<div ng-bind="data.heading"></div>
<!-- </h2> -->
<div flex=""></div>
<div ng-class="{expandCollapse:true, active:data.expanded}"></div>
</div>
</md-toolbar>
<div style="overflow:scroll" ng-class="{dataContent:true, activeContent:data.expanded}">
<div style="padding:10px" ng-bind-html="data.content"></div>
</div>
<div>
</md-content>
And the css part:
.md-accordion .expandCollapse { width:30px; height:30px; position:relative; font-size:20px; font-weight:bold; cursor:pointer; color:#fff; display:block; margin-top: -2px; margin-left: -2px; overflow:hidden; }
.md-accordion .expandCollapse:active { border:0px; }
.md-accordion .expandCollapse:before, .md-accordion .expandCollapse:after { width:30px; height:30px; display:block; position:absolute; top:0; left:0; line-height:32px; text-align:center; -webkit-transition: .3s all ease-out; transition: .3s all ease-out; }
.md-accordion .expandCollapse:before { opacity:1 -webkit-transform: rotate(0deg); transform: rotate(0deg); content: "|"; margin-top:-3px; }
.md-accordion .expandCollapse:after { opacity:1; -webkit-transform: rotate(-90deg); transform: rotate(-90deg); content: "|"; margin-left:-3px; }
.md-accordion .active:before { opacity:1; -webkit-transform: rotate(90deg); transform: rotate(90deg); margin-left:3px; margin-top:0px; }
.md-accordion .dataContent { background: #F2F2F2; height:0px; overflow:hidden; -webkit-transition: .3s all ease-out; transition: .3s all ease-out; }
.md-accordion .activeContent { height:60vh; padding:0; display:block; }
.md-accordion md-toolbar{ cursor:pointer; border-bottom:1px solid rgb(63,107,181) }
Here we have fixed the height of the expandable list in order to keep the list items still visible, else once you expand a div having a huge content the user may feel that it's the only list item available and may not be able to see the other items if any of the div is expanded, the overflow:scroll allows the view to be scroll through, else it will be stiff and the user won't be ablt to view the entire content.
Hope this is helpful... :)
So this is what I ended up using
Directive HTML Code
need a right and down arrow img
<ang-accordion one-at-a-time="true" icon-position="right" close-icon-url="<?php echo URL; ?>/img/icons/right-icon.png" open-icon-url="<?php echo URL; ?>/img/icons/down-icon.png">
<collapsible-item ng-repeat="item in items" item-title="" initially-open="">
<div>Text</div>
</collapsible-item>
</ang-accordion>
Script to include
<script type="text/javascript" src="<?php echo URL; ?>/js/angular/controllers/accordion.js"></script>
JS: accordion.js
app.controller('angAccordionController', ['$scope', function($scope){
var collapsibleItems = [];
this.openCollapsibleItem = function(collapsibleItemToOpen) {
if( $scope.oneAtATime ) {
angular.forEach(collapsibleItems, function(collapsibleItem) {
collapsibleItem.isOpenned = false;
collapsibleItem.icon = collapsibleItem.closeIcon;
});
}
collapsibleItemToOpen.isOpenned = true;
};
this.addCollapsibleItem = function(collapsibleItem) {
collapsibleItems.push(collapsibleItem);
if ( $scope.closeIconClass !== undefined || $scope.openIconClass !== undefined ) {
collapsibleItem.iconsType = 'class';
collapsibleItem.closeIcon = $scope.closeIconClass;
collapsibleItem.openIcon = $scope.openIconClass;
}
else if ( $scope.closeIconUrl !== undefined || $scope.openIconUrl !== undefined ) {
collapsibleItem.iconsType = 'url';
collapsibleItem.closeIcon = $scope.closeIconUrl;
collapsibleItem.openIcon = $scope.openIconUrl;
}
collapsibleItem.iconIsOnLeft = $scope.iconPosition == 'left' ? true: false;
};
}])
.directive('angAccordion', function() {
return {
restrict: 'EA',
transclude: true,
replace: true,
scope: {
oneAtATime: '#',
closeIconUrl: '#',
openIconUrl: '#',
closeIconClass: '#',
openIconClass: '#',
iconPosition: '#'
},
controller: 'angAccordionController',
template: '<div class="accordion" ng-transclude></div>'
};
});
angular.module('collapsibleItem', []).directive('collapsibleItem', function() {
return {
require: '^angAccordion',
restrict: 'EA',
transclude: true,
replace: true,
scope: {
itemTitle: '#',
itemDisabled: '=',
initiallyOpen: '#'
},
link: function(scope, element, attrs, accordionController) {
scope.isOpenned = (scope.initiallyOpen == "true") ? true : false;
accordionController.addCollapsibleItem(scope);
if(scope.isOpenned)
scope.icon = scope.openIcon;
else
scope.icon = scope.closeIcon;
scope.toggleCollapsibleItem = function () {
if(scope.itemDisabled)
return;
if(!scope.isOpenned) {
accordionController.openCollapsibleItem(this);
scope.icon = scope.openIcon;
}
else {
scope.isOpenned = false;
scope.icon = scope.closeIcon;
}
};
scope.getIconUrl = function ( type ) {
return type == 'url' ? scope.icon : null;
};
},
template: '<div class="collapsible-item" ng-class="{open: isOpenned}"><div class="title" ng-class="{disabled: itemDisabled}" ng-click="toggleCollapsibleItem()">{{itemTitle | limitTo:28 }}<i ng-show="iconsType == \'class\'" class="{{icon}} icon" ng-class="{iconleft: iconIsOnLeft}"></i><img ng-show="iconsType == \'url\'" class="icon" ng-class="{iconleft: iconIsOnLeft}" ng-src="{{getIconUrl(iconsType)}}" /></div><div class="body"><div class="content" ng-transclude></div></div></div>'
};
});
CSS
.collapsible-item {
margin-bottom: 0px;
}
.collapsible-item .title {
padding: 10px;
background-color: #dfdfdf;
border: 0px solid #ccc;
cursor: pointer;
}
.collapsible-item .title .icon {
float: right;
height: 20px;
width: 20px;
font-size: 19px !important;
padding-right: 1px;
}
.collapsible-item .title .iconleft {
float: left !important;
}
.collapsible-item .title.disabled {
background: #eee;
color: #999;
cursor: text;
}
.collapsible-item .body {
position: relative;
top: -4px;
max-height: 0;
overflow: hidden;
border: 1px solid #ccc;
border-top: 0;
z-index: -1;
-webkit-transition: max-height 0.5s ease;
-moz-transition: max-height 0.5s ease;
-o-transition: max-height 0.5s ease;
transition: max-height 0.5s ease;
}
.collapsible-item .body .content {
padding: 5px 15px 5px 15px;
}
.collapsible-item.open .body {
max-height: 1000px;
z-index: 1;
}

Angular Select Options with image

I want select drop down option with respective images ,can anyone help me in this ,
here is my code
<select class="form-control demo-htmlselect"
ng-model="spList"
ng-options="spList.name for spList in spDTOList"
required>
<option disabled selected>Select Option</option>
</select>
Here I want get the options with images, I want to use pure angularjs,
can anyone help me to use select2 with angular js
Select2
Take a look at this guy. He seems to have built something similair to what you want
http://yairnevet.blogspot.dk/2013/02/multiple-select-drop-down-list-using.html
EDIT: It was pointed out to me (and i can see now when i see the code) that he indeed uses jquery to achieve what he easily could have done with angular alone. I still think the example serveres as a demonstration. The trick here is not use the default SELECT tag of html but instead style an UL with LI's to get the desired result.
Try this, i've used github iconselect project built on pure javascript, so you can add it to your project and invoke it from the angular controller. Check here for seeing it working. http://jsfiddle.net/Vsgyf/1/
HTML:
<script type="text/javascript" ng:autobind
src="http://code.angularjs.org/0.10.4/angular-0.10.4.js"></script>
<script type="text/javascript" src="http://bug7a.github.io/iconselect.js/sample/lib/iscroll.js"></script>
<div ng:controller="Ctrl">
<div id="my-icon-select"></div>
</div>
JS:
function Ctrl() {
this.list = [
{ name:'SWISS', img:'http://s9.postimage.org/d9t33we17/Swiss.png'},
{name:'UNITED', img:'http://s9.postimage.org/ykqn85w5n/United.png'},
{name:'KLM', img:'http://s9.postimage.org/p7unhshsb/Klm.png'},
{name:'EL AL', img:'http://s18.postimage.org/oi8ndntud/image.gif'},
{name:'Ethiopian', img:'http://s9.postimage.org/hqlg2ks97/image.gif'}
];
iconSelect = new IconSelect("my-icon-select");
var icons = [];
for(var i = 0; i< this.list.length; i++){
icons.push({'iconFilePath': this.list[i].img, 'iconValue':this.list[i].name});
}
iconSelect.refresh(icons);
};
IconSelect.DEFAULT = {};
IconSelect.DEFAULT.SELECTED_ICON_WIDTH = 48;
IconSelect.DEFAULT.SELECTED_ICON_HEIGHT = 48;
IconSelect.DEFAULT.SELECTED_BOX_PADDING = 1;
IconSelect.DEFAULT.SELECTED_BOX_PADDING_RIGHT = 12;
IconSelect.DEFAULT.ICONS_WIDTH = 32;
IconSelect.DEFAULT.ICONS_HEIGHT = 32;
IconSelect.DEFAULT.BOX_ICON_SPACE = 1;
IconSelect.DEFAULT.HORIZONTAL_ICON_NUMBER = 3;
IconSelect.DEFAULT.VECTORAL_ICON_NUMBER = 3;
IconSelect.COMPONENT_ICON_FILE_PATH = "http://bug7a.github.io/iconselect.js/sample/images/control/icon-select/arrow.png";
function IconSelect($$elementID, $$parameters) {
var _icons = [];
var _selectedIndex = -1;
var _boxScroll;
var _default = IconSelect.DEFAULT;
function _init() {
//parametreler boÅŸ gelirse
if(!$$parameters) $$parameters = {};
if(_View.setIconSelectElement($$elementID)){
//set parameters
$$parameters = _Model.checkParameters($$parameters);
//create UI
var ui = _View.createUI($$parameters, $$elementID);
_View.iconSelectElement.onclick = function(){
_View.showBox();
};
_View.showBox(false);
_View.iconSelectElement.addEventListener('click', function($event){
$event.stopPropagation();
});
window.addEventListener('click', function(){
_View.showBox(false);
});
}else{
alert("Element not found.");
}
}
this.refresh = function($icons){
_icons = [];
var setSelectedIndex = this.setSelectedIndex;
for(var i = 0; i < $icons.length; i++){
$icons[i].element = _View.createIcon($icons[i].iconFilePath, $icons[i].iconValue, i, $$parameters);
$icons[i].element.onclick = function(){
setSelectedIndex(this.childNodes[0].getAttribute('icon-index'));
};
_icons.push($icons[i]);
}
var horizontalIconNumber = Math.round(($icons.length) / $$parameters.vectoralIconNumber);
_View.boxElement.style.height = (($$parameters.iconsHeight + 2) * horizontalIconNumber) +
((horizontalIconNumber + 1) * $$parameters.boxIconSpace);
this.setSelectedIndex(0);
};
//icon listesini al.
this.getIcons = function(){ return _icons; };
//iconu seçili hale gelir.
this.setSelectedIndex = function($index){
var icon;
if(_icons.length > $index)
icon = _icons[$index];
if(icon){
if(_selectedIndex != -1) _icons[_selectedIndex].element.setAttribute('class','icon');
_selectedIndex = $index;
_View.selectedIconImgElement.setAttribute('src', icon.iconFilePath);
if(_selectedIndex != -1) _icons[_selectedIndex].element.setAttribute('class','icon selected');
}
_View.iconSelectElement.dispatchEvent(new Event('changed'));
};
this.getSelectedIndex = function(){ return _selectedIndex; };
this.getSelectedValue = function(){ return _icons[_selectedIndex].iconValue };
this.getSelectedFilePath = function(){ return _icons[_selectedIndex].iconFilePath };
//### VIEW CLASS ###
function _View(){}
_View.iconSelectElement;
_View.boxElement;
_View.boxScrollElement;
_View.selectedIconImgElement;
_View.selectedIconElement;
_View.showBox = function($isShown){
if($isShown == null) {
$isShown = (_View.boxElement.style.display == "none") ? true : false;
}
if($isShown) {
_View.boxElement.style.display = "block";
_View.boxScrollElement.style.display = "block";
_boxScroll = (_boxScroll) ? _boxScroll : new iScroll($$elementID + "-box-scroll");
}else{
_View.boxElement.style.display = "none";
_View.boxScrollElement.style.display = "none";
}
_View.boxElement.style.display = ($isShown) ? "block" : "none";
};
_View.setIconSelectElement = function($elementID){
_View.iconSelectElement = document.getElementById($elementID);
return _View.iconSelectElement;
};
_View.clearUI = function(){
_View.iconSelectElement.innerHTML = "";
};
_View.clearIcons = function(){
_View.boxElement.innerHTML = "";
};
_View.createUI = function($parameters){
/* HTML MODEL
<div id="my-icon-select" class="icon-select">
<div class="selected-box">
<div class="selected-icon"><img src="images/icons/i2.png"></div>
<div class="component-icon"><img src="images/control/icon-select/arrow.png"></div>
<div class="box">
<div class="icon"><img src="images/icons/i1.png"></div>
<div class="icon selected"><img src="images/icons/i2.png"></div>
<div class="icon"><img src="images/icons/i3.png"></div>
<div class="icon"><img src="images/icons/i4.png"></div>
<div class="icon"><img src="images/icons/i3.png"></div>
<div class="icon"><img src="images/icons/i4.png"></div>
<div class="icon"><img src="images/icons/i5.png"></div>
<div class="icon"><img src="images/icons/i6.png"></div>
<div class="icon"><img src="images/icons/i7.png"></div>
<div class="icon"><img src="images/icons/i8.png"></div>
</div>
</div>
</div>
*/
_View.clearUI();
_View.iconSelectElement.setAttribute('class', 'icon-select');
var selectedBoxElement = document.createElement('div');
selectedBoxElement.setAttribute('class' ,'selected-box');
var selectedIconElement = document.createElement('div');
selectedIconElement.setAttribute('class' ,'selected-icon');
_View.selectedIconImgElement = document.createElement('img');
_View.selectedIconImgElement.setAttribute('src', '');
selectedIconElement.appendChild(_View.selectedIconImgElement);
var componentIconElement = document.createElement('div');
componentIconElement.setAttribute('class', 'component-icon');
var componentIconImgElement = document.createElement('img');
componentIconImgElement.setAttribute('src', IconSelect.COMPONENT_ICON_FILE_PATH );
componentIconElement.appendChild(componentIconImgElement);
_View.boxScrollElement = document.createElement('div');
_View.boxScrollElement.setAttribute('id',$$elementID + "-box-scroll");
_View.boxScrollElement.setAttribute('class', 'box');
_View.boxElement = document.createElement('div');
_View.boxScrollElement.appendChild(_View.boxElement);
_View.selectedIconImgElement.setAttribute('width', $parameters.selectedIconWidth);
_View.selectedIconImgElement.setAttribute('height', $parameters.selectedIconHeight);
selectedIconElement.style.width = $parameters.selectedIconWidth;
selectedIconElement.style.height = $parameters.selectedIconHeight;
selectedBoxElement.style.width = $parameters.selectedIconWidth + $parameters.selectedBoxPadding + $parameters.selectedBoxPaddingRight;
selectedBoxElement.style.height = $parameters.selectedIconHeight + ($parameters.selectedBoxPadding * 2);
selectedIconElement.style.top = $parameters.selectedBoxPadding;
selectedIconElement.style.left = $parameters.selectedBoxPadding;
componentIconElement.style.bottom = 4 + $parameters.selectedBoxPadding;
_View.boxScrollElement.style.left = parseInt(selectedBoxElement.style.width) + 1;
_View.boxScrollElement.style.width = (($parameters.iconsWidth + 2) * $parameters.vectoralIconNumber) +
(($parameters.vectoralIconNumber + 1) * $parameters.boxIconSpace);
_View.boxScrollElement.style.height = (($parameters.iconsHeight + 2) * $parameters.horizontalIconNumber) +
(($parameters.horizontalIconNumber + 1) * $parameters.boxIconSpace);
_View.boxElement.style.left = _View.boxScrollElement.style.left;
_View.boxElement.style.width = _View.boxScrollElement.style.width;
_View.iconSelectElement.appendChild(selectedBoxElement);
selectedBoxElement.appendChild(selectedIconElement);
selectedBoxElement.appendChild(componentIconElement);
selectedBoxElement.appendChild(_View.boxScrollElement);
var results = {};
results['iconSelectElement'] = _View.iconSelectElement;
results['selectedBoxElement'] = selectedBoxElement;
results['selectedIconElement'] = selectedIconElement;
results['selectedIconImgElement'] = _View.selectedIconImgElement;
results['componentIconElement'] = componentIconElement;
results['componentIconImgElement'] = componentIconImgElement;
return results;
};
_View.createIcon = function($iconFilePath, $iconValue, $index, $parameters){
var iconElement = document.createElement('div');
iconElement.setAttribute('class', 'icon');
iconElement.style.width = $parameters.iconsWidth;
iconElement.style.height = $parameters.iconsHeight;
iconElement.style.marginLeft = $parameters.boxIconSpace;
iconElement.style.marginTop = $parameters.boxIconSpace;
var iconImgElement = document.createElement('img');
iconImgElement.setAttribute('src', $iconFilePath);
iconImgElement.setAttribute('icon-value', $iconValue);
iconImgElement.setAttribute('icon-index', $index);
iconImgElement.setAttribute('width', $parameters.iconsWidth);
iconImgElement.setAttribute('height', $parameters.iconsHeight);
iconElement.appendChild(iconImgElement);
_View.boxElement.appendChild(iconElement);
return iconElement;
};
//### MODEL CLASS ###
function _Model(){}
//TODO: params değişkenini kaldır yeni oluştursun.
_Model.checkParameters = function($parameters){
$parameters.selectedIconWidth = ($parameters.selectedIconWidth) ? $parameters.selectedIconWidth : _default.SELECTED_ICON_WIDTH;
$parameters.selectedIconHeight = ($parameters.selectedIconHeight) ? $parameters.selectedIconHeight : _default.SELECTED_ICON_HEIGHT;
$parameters.selectedBoxPadding = ($parameters.selectedBoxPadding) ? $parameters.selectedBoxPadding : _default.SELECTED_BOX_PADDING;
$parameters.selectedBoxPaddingRight = ($parameters.selectedBoxPaddingRight) ? $parameters.selectedBoxPaddingRight : _default.SELECTED_BOX_PADDING_RIGHT;
$parameters.iconsWidth = ($parameters.iconsWidth) ? $parameters.iconsWidth : _default.ICONS_WIDTH;
$parameters.iconsHeight = ($parameters.iconsHeight) ? $parameters.iconsHeight : _default.ICONS_HEIGHT;
$parameters.boxIconSpace = ($parameters.boxIconSpace) ? $parameters.boxIconSpace : _default.BOX_ICON_SPACE;
$parameters.vectoralIconNumber = ($parameters.vectoralIconNumber) ? $parameters.vectoralIconNumber : _default.VECTORAL_ICON_NUMBER;
$parameters.horizontalIconNumber = ($parameters.horizontalIconNumber) ? $parameters.horizontalIconNumber : _default.HORIZONTAL_ICON_NUMBER;
return $parameters;
};
_init();
}
CSS:
.icon-select{
width:0px;
}
.icon-select .selected-box {
position: relative;
margin: 0px;
padding: 0px;
width: 70px; /* sil */
height: 60px; /* sil */
border: 1px solid #999999;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.icon-select .selected-box:hover {
position: relative;
margin: 0px;
padding: 0px;
width: 70px; /* sil */
height: 60px; /* sil */
border: 1px solid #000000;
background-color: #FFFFFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.icon-select .selected-icon {
position: absolute;
margin: 0px;
padding: 0px;
top:5px;
left:5px;
width: 48px; /* sil */
height: 48px; /* sil */
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.icon-select .component-icon{
position: absolute;
bottom:5px;
right:4px;
}
.icon-select .box {
position: absolute;
top:0px;
left:71px;
margin: 0px;
padding: 0px;
width: 170px; /* sil */
height: 170px; /* sil */
border: 1px solid #EEEEEE;
background-color: #EEEEEE;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
overflow:auto;
/*
-webkit-overflow-scrolling: touch;
*/
}
.icon-select .icon {
position: relative;
margin: 5px 0px 0px 5px;
padding: 0px;
width: 48px; /* sil */
height: 48px; /* sil */
border: 1px solid #CCCCCC;
background-color: #FFFFFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
overflow:hidden;
float: left;
}
.icon-select .icon:hover {
border: 1px solid #000000;
}
.icon-select .icon.selected {
position: relative;
margin: 5px 0px 0px 5px;
padding: 0px;
width: 48px; /* sil */
height: 48px; /* sil */
border: 1px solid #EEEEEE;
background-color: #EEEEEE;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
overflow:hidden;
float: left;
}
You could use angular-strap select.I believe thats better than going through the confusing documentation of select2
http://mgcrea.github.io/angular-strap/##selects
We Can achieve this using select2 templating with angular, select2-ui for angular helps to design select2-angular
Checkout a example at angularjs select option with custom format value
Having style inside select boxes is very restricted. You can infact not use images, or webfonts inside select boxes. It is restricted from the browser. Imagine what would happen if a cell-phone or tablet which usually have the OS's custom dropdown, that would screw up everything.
Your only option is to go with a custom directive for example angular-dropdowns.
https://github.com/jseppi/angular-dropdowns
I have used it in some projects and it is fairy easy to style and you can include both images and webfonts.

Resources