I currently have a free account in SmartyStreets (aka Smarty) and need to integrate the autocomplete functionality. But after integrating the API using static values, it shows a CORS issue. Also, i have already tried the Access-Control-Allow-Origin but that also not working.
So my question is how to resolve the CORS issue?
Also, I have another question I would like to implement two other features.
autocomplete addresses and populate values in the form.
the page allows the user to type the address, send the request to SmartStreets, get the response, and display the result along with the form, empty this time, to allow the user to enter another address.
For More Details, please have a look at the below code:
Note: The Frontend code I am using is AngularJs with Typescript.
API Integration:
import { Injectable } from "#angular/core";
import { Observable } from "rxjs";
import { HttpClient, HttpParams } from "#angular/common/http";
#Injectable()
export class commonservice
{
constructor(private httpclient:HttpClient){
}
getaddressauto(): Observable<any> {
let smartauth = new HttpParams().set('auth-id',"72018252-ad10-b627-1234-970404bfd187");
let smarttoken = new HttpParams().set('auth-token',"xuwSg95g4y8AObhEv3hx");
let smartsearch = new HttpParams().set('search',"Louis");
let smartcountry = new HttpParams().set('country',"FRA");
return this.httpclient.get('https://international-autocomplete.api.smartystreets.com/lookup?'+smartauth+'&'+smarttoken+'&'+smartsearch+'&'+smartcountry) ;
}
}
<html>
<head>
<title>SmartyStreets Address Verifier</title>
</head>
<body>
<div class="p-field p-col-4">
<label for="address">Address Line 1</label>
<p-autoComplete [(ngModel)]="addressautocomplete2" [suggestions]="filteredGroup" (completeMethod)="filteraddressautocomplete($event)" (onSelect)="onEndUserSelect($event)" (onClear)="onEndUserSelect(null)" field="name" [minLength]="1" formControlName="EndUserAddressLine1">
</p-autoComplete>
<div *ngFor="let addressauto of addressautocomplete">
<p>{{addressauto.name}}</p>
</div>
</div>
</body>
</html>
You shouldn't be sending your auth-id and auth-token over the web. Use your embedded key instead.
When you use your embedded key don't forget to set the referrer header.
Smarty also has a javascript sdk that could simplify a lot of this stuff
Here is a JSFiddle that may be helpful. It seems to be what you want to accomplish as far as a call to Smarty US Autocomplete Pro, followed by a call to Smarty US Street, then filling a form with a result.
https://jsfiddle.net/x8eLpgm1/1/
$(function() {
var menu = $(".us-autocomplete-pro-menu");
var input = $("#us-autocomplete-pro-address-input");
function getSuggestions(search, selected) {
$.ajax({
url: "https://us-autocomplete-pro.api.smartystreets.com/lookup?",
data: {
// Don't forget to replace the key value with your own embedded key
"key": "21102174564513388",
"search": search,
"selected": (selected ? selected : "")
},
success: function(data) {
if (data.suggestions) {
buildMenu(data.suggestions);
} else {
noSuggestions();
}
},
error: function(error) {
return error;
}
});
}
function getSingleAddressData(address) {
$.ajax({
url: "https://us-street.api.smartystreets.com/street-address?",
data: {
// Don't forget to replace the key value with your own embedded key
"key": "21102174564513388",
"street": address[0],
"city": address[1],
"state": address[2]
},
dataType: "jsonp",
success: function(data) {
$("#zip").val(data[0].components.zipcode);
$("#data-lat").html(data[0].metadata.latitude);
$("#data-lon").html(data[0].metadata.longitude);
$("#data-county").html(data[0].metadata.county_name);
$("#data-time-zone").html(data[0].metadata.time_zone);
},
error: function(error) {
return error;
}
});
}
function clearAddressData() {
$("#city").val("");
$("#state").val("");
$("#zip").val("");
$("#data-lat").empty();
$("#data-lon").empty();
$("#data-county").empty();
$("#data-time-zone").empty();
}
function noSuggestions() {
var menu = $(".us-autocomplete-pro-menu");
menu.empty();
menu.append("<li class='ui-state-disabled'><div>No Suggestions Found</div></li>");
menu.menu("refresh");
}
function buildAddress(suggestion) {
var whiteSpace = "";
if (suggestion.secondary || suggestion.entries > 1) {
if (suggestion.entries > 1) {
suggestion.secondary += " (" + suggestion.entries + " more entries)";
}
whiteSpace = " ";
}
var address = suggestion.street_line + whiteSpace + suggestion.secondary + " " + suggestion.city + ", " + suggestion.state + " " + suggestion.zipcode;
var inputAddress = $("#us-autocomplete-pro-address-input").val();
for (var i = 0; i < address.length; i++) {
var theLettersMatch = typeof inputAddress[i] == "undefined" || address[i].toLowerCase() !== inputAddress[i].toLowerCase();
if (theLettersMatch) {
address = [address.slice(0, i), "<b>", address.slice(i)].join("");
break;
}
}
return address;
}
function buildMenu(suggestions) {
var menu = $(".us-autocomplete-pro-menu");
menu.empty();
suggestions.map(function(suggestion) {
var caret = (suggestion.entries > 1 ? "<span class=\"ui-menu-icon ui-icon ui-icon-caret-1-e\"></span>" : "");
menu.append("<li><div data-address='" +
suggestion.street_line + (suggestion.secondary ? " " + suggestion.secondary : "") + ";" +
suggestion.city + ";" +
suggestion.state + "'>" +
caret +
buildAddress(suggestion) + "</b></div></li>");
});
menu.menu("refresh");
}
$(".us-autocomplete-pro-menu").menu({
select: function(event, ui) {
var text = ui.item[0].innerText;
var address = ui.item[0].childNodes[0].dataset.address.split(";");
var searchForMoreEntriesText = new RegExp(/(?:\ more\ entries\))/);
input.val(address[0]);
$("#city").val(address[1]);
$("#state").val(address[2]);
if (text.search(searchForMoreEntriesText) == "-1") {
$(".us-autocomplete-pro-menu").hide();
getSingleAddressData(address);
} else {
$("#us-autocomplete-pro-address-input").val(address[0] + " ");
var selected = text.replace(" more entries", "");
selected = selected.replace(",", "");
getSuggestions(address[0], selected);
}
}
});
$("#us-autocomplete-pro-address-input").keyup(function(event) {
if (input.val().length > 0 || input.val() === "") clearAddressData();
if (event.key === "ArrowDown") {
menu.focus();
menu.menu("focus", null, menu.menu().find(".ui-menu-item"));
} else {
var textInput = input.val();
if (textInput) {
menu.show();
getSuggestions(textInput);
} else {
menu.hide();
}
}
});
$(".us-autocomplete-pro-menu").css("width", ($("#us-autocomplete-pro-address-input").width() + 24) + "px")
});
.us-autocomplete-pro-example {
font-family: helvetica;
color: #0a0a0a;
text-align: center;
}
.us-autocomplete-pro-example .container {
background-color: #ddd;
padding: 2em;
}
.us-autocomplete-pro-example .container label {
color: #0a0a0a;
}
.us-autocomplete-pro-example .container input {
font-size: 16px;
padding: 0 .75em;
border: 1px solid #ccc;
color: #0a0a0a;
height: 3em;
box-sizing: border-box;
width: 100%;
margin-top: .5em;
}
.us-autocomplete-pro-example .container input:disabled {
background-color: #eee;
color: #999;
}
.us-autocomplete-pro-example .container .us-autocomplete-pro-input-container {
margin: 0 auto 2em;
width: 60%;
}
.us-autocomplete-pro-example .container .us-autocomplete-pro-menu {
overflow-y: scroll;
max-height: 13em;
box-shadow: 0 7px 7px rgba(0, 0, 0, 0.12);
color: #7d7d7d;
position: absolute;
text-align: left;
width: inherit;
z-index: 10;
}
.us-autocomplete-pro-example .container .us-autocomplete-pro-menu li div {
padding: .75em;
}
.us-autocomplete-pro-example .container .us-autocomplete-pro-menu b {
color: #0a0a0a;
}
.us-autocomplete-pro-example .container .us-autocomplete-pro-menu .ui-menu-item-wrapper {
padding-left: 1em;
}
.us-autocomplete-pro-example .container .labels {
display: inline-block;
font-weight: bold;
width: 40%;
}
.us-autocomplete-pro-example .container .data {
display: inline-block;
padding-left: 1em;
width: 50%;
}
.us-autocomplete-pro-example .docs-pricing-links {
font-weight: bold;
margin-top: 2em;
}
.inline {
display: inline-block;
vertical-align: top;
width: 40%;
}
.data-container {
text-align: center;
margin-bottom: 2em;
}
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.js"></script>
</head>
<body>
<div class="content-white us-autocomplete-pro-example">
<h2>US Autocomplete Pro</h2>
<div class="container">
<div class="us-autocomplete-pro-input-container">
<label for="us-autocomplete-pro-address-input">Start typing a street address and watch how fast we send you
verified suggestions</label><br>
<input id="us-autocomplete-pro-address-input" placeholder="Enter Address" autocomplete="smartystreets"/>
<ul class="us-autocomplete-pro-menu" style="display:none;"></ul>
<div class="disabled-inputs">
<input id="city" placeholder="City" disabled />
<div class="state-and-zip">
<input id="state" placeholder="State" disabled />
<input id="zip" placeholder="Zip*" disabled />
</div>
</div>
</div>
<div class="data-container">
<div>
<h3>*Additional Data</h3>
<div class="labels inline align-right">
<span>Latitude:</span><br>
<span>Longitude:</span><br>
<span>County:</span><br>
<span>Time Zone:</span>
</div>
<div class="data inline align-left">
<span id="data-lat"></span><br>
<span id="data-lon"></span><br>
<span id="data-county"></span><br>
<span id="data-time-zone"></span>
</div>
<div class="more-data">
... along with 32 other points of data.
</div>
</div>
</div>
<div class="disclaimer">*ZIP Code & Additional Data retrieved from <a href="https://smartystreets.com/products/apis/us-street-api">US
Street Address API</a></div>
</div>
<div class="docs-pricing-links">
Pretty cool huh? You should see the <a href="https://smartystreets.com/docs/cloud/us-autocomplete-api#autocomplete-professional">Autocomplete
Pro Docs</a> for more info
</div>
</div>
</body>
</html>
Related
My chat display correctly on my first react app instance but not on the second.
https://imgur.com/a/7FVCvjW
I could not figure out what is wrong. I dont find any reason why the right side ( of the image shared aove) would not show properly;
export const Message = ({ message, name }) => {
const style = (sender) => {
if (sender === "admin") {
return "admin";
} else if (sender === name) {
return "user";
} else {
return "other";
}
};
return (
<Fragment>
<div className="messageContainer">
<p className={`content ${style(message.user)}`}>{message.message}</p>
{name === message.user ? null : (
<p className="sender">{message.user}</p>
)}
</div>
</Fragment>
);
};
CSS
.content {
margin-right: 10px;
}
.admin {
color: rgb(156, 156, 156);
}
.user {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
margin-left: auto;
}
.other {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
}
.messageContainer {
display: flex;
align-items: center;
}
.sender {
color: rgb(156, 156, 156);
}
Just remove:
if (sender === "admin") {
return "admin";
} else
If you really need to handle this with a flag, instead of name use user = {name, isAdmin}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
<style type="text/css">
h3 {
color: white;
}
.content {
margin-right: 10px;
}
.admin {
color: rgb(156, 156, 156);
}
.user {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
margin-left: auto;
}
.other {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
}
.messageContainer {
display: flex;
align-items: center;
}
.sender {
color: rgb(156, 156, 156);
}
</style>
</head>
<body style="background: blue">
<div id="root"></div>
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin ></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin ></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script type="text/babel">
const {Fragment} = React;
const Message = ({ message, name }) => {
const style = (sender) => {
// if (sender === "admin") {
// return "admin";
// } else
if (sender === name) {
return "user";
} else {
return "other";
}
};
return (
<Fragment>
<div className="messageContainer">
<p className={`content ${style(message.user)}`}>{message.message}</p>
{name === message.user ? null : (
<p className="sender">{message.user}</p>
)}
</div>
</Fragment>
);
};
const App = () => {
return (
<Fragment>
<h3>From Jonh's point of view</h3>
<ul>
<Message message={{user: "john", message: "Hi"}} name="john"/>
<Message message={{user: "mary", message: "Hey from user"}} name="john"/>
</ul>
<h3>From Mary's point of view</h3>
<ul>
<Message message={{user: "john", message: "Hi"}} name="mary"/>
<Message message={{user: "mary", message: "Hey from user"}} name="mary"/>
</ul>
<h3>From an anonymous point of view</h3>
<ul>
<Message message={{user: "john", message: "Hi"}} name=""/>
<Message message={{user: "mary", message: "Hey from user"}} name=""/>
</ul>
</Fragment>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</body>
</html>
I'm building a multiple chatbox messaging like Facebook's popup messenger windows. At the moment, the user can call up a chatbox, close it, minimize it, etc.
When I click on multiple users, say 3, I'm supposed to have three chatboxes pop up corresponding to those three different users. Currently, only one chatbox appears.
This screenshot illustrates what I want to achieve. On each user's button click, it's own chatbox will popup.
Here is the demo and download link for a jQuery equivalent: link.
This is the full React code which shows just one chat box:
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
import './style.css';
class MessageBox extends Component {
constructor() {
super();
this.state = {
showBox: false,
shownToggle: true,
data: [
{ id: "1", name: "Tony" },
{ id: "2", name: "Mark" },
{ id: "3", name: "Joy" }
],
currentRec: undefined,
};
this.showBox = this.showBox.bind(this);
this.closeBox = this.closeBox.bind(this);
this.toggle = this.toggle.bind(this);
}
showBox = (i, pid, name) => {
this.setState({ currentRec: i });
console.log(`Selected record index: ${i}`);
alert(pid);
alert(name);
this.setState({ showBox: true }, () => {
document.addEventListener('click', this.closeBox);
});
}
closeBox(event) {
if (this.dropdownBox.contains(event.target)) {
this.setState({ showBox: false }, () => {
document.removeEventListener('click', this.closeBox);
});
}
}
toggle() {
this.setState({
shownToggle: !this.state.shownToggle
});
}
render() {
var hidden = {
display: this.state.shownToggle ? "block" : "none"
}
return (
<div>
<ul style={{ float: "right" }}>
{this.state.data.map((person, i) => (
<div className="chat-sidebar" key={i}>
<button onClick={() => this.showBox(i, person.id, person.name)}>Chat with {person.name}</button>
{this.state.showBox ? (
<div className="msg_box" style={{ right: '270px' }}>
<div onClick={this.toggle.bind(this)} class="msg_head">
(<b style={{ color: 'orange' }}>
{this.state.currentRec !== undefined &&
<div className="modal-body">
{this.state.data[this.state.currentRec].name}
({this.state.data[this.state.currentRec].id})
</div>
}
</b>)
Minimize
<div className="close" ref={(element) => { this.dropdownBox = element; }} style={{ color: 'white' }}>Close</div>
</div>
<div style={hidden} className="msg_wrap"><div className="msg_body">Message will appear here</div></div>
</div>) : (null)}
</div>
))}
</ul>
</div>
);
}
}
/****** Chat Popup Layout ******/
body{
background: #e5e5e5;
font-family: sans-serif;
}
.msg_box{
position: fixed;
bottom: -5px;
width: 250px;
background: white;
border-radius: 5px 5px 0px 0px;
}
.msg_head{
background: black;
color: white;
padding: 8px;
font-weight: bold;
cursor: pointer;
border-radius: 5px 5px 0px 0px;
}
.msg_body{
background: white;
height: 200px;
font-size: 12px;
padding: 15px;
overflow: auto;
overflow-x: hidden;
}
.close{
float: right;
cursor: pointer;
}
.minimize{
float: right;
cursor: pointer;
padding-right: 5px;
}
/****** Slider Layout Popup ******/
.chat-sidebar {
width: 250px;
height: 100%;
right: 0px;
top: 0px;
padding-top: 10px;
padding-bottom: 10px;
border: 1px solid #b2b2b2;
}
After series of efforts, the use of jquery and Reactjs is what solved my issue as per code below
const dataSet = this.state.data;
alert(dataSet);
if ($.inArray(pid, dataSet) != -1)
{
dataSet.splice($.inArray(pid, this.state.data), 1);
}
dataSet.unshift(pid);
var s = 270 ; // start position
var j = 260; //next position
$.each(dataSet, function( index, value ) {
if(index < 4){
$('[rel="'+value+'"]').css("right",s);
$('[rel="'+value+'"]').show();
s = s+j;
}
else{
$('[rel="'+value+'"]').hide();
}
I am using paper-swatch-picker for picking a color and a dom-repeat to iterate over an Array.
when I select color, it does not update in the Array.
Can somebody help me propagating swatch picker color change to Array.
I can add multiple rows, each row with 3 color picker (foreground, background and border).
What I want is to have my Array decoratorList updated when I pick a color.
Below is the codepen for reference.
http://codepen.io/khanshahid/pen/wzGrxk
<html>
<head>
<base href="https://polygit.org/polymer+1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="paper-input/paper-input.html">
<link rel="import" href="paper-tabs/paper-tabs.html">
<link rel="import" href="paper-tabs/paper-tab.html">
<link rel="import" href="iron-pages/iron-pages.html">
<link rel="import" href="iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="iron-input/iron-input.html">
<link rel="import" href="iron-collapse/iron-collapse.html">
<link rel="import" href="paper-material/paper-material.html">
<link rel="import" href="paper-item/paper-item.html">
<link rel="import" href="paper-input/paper-input-container.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="paper-toast/paper-toast.html">
<link rel="import" href="paper-fab/paper-fab.html">
<link rel="import" href="paper-swatch-picker/paper-swatch-picker.html">
</head>
<body>
<div style="width:1200px;">
<msk-decorator
tag-id= 1
color-list='["#65a5f2", "#83be54", "#f0d551", "#e5943c", "#a96ddb","#aabbcc","#aaa","#ccc","#eee","#333", "transparent", "none"]'
data-type="Enum">
</msk-decorator>
</div>
<dom-module id="msk-decorator">
<template>
<style is="custom-style">
:host{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important;
};
.flex-horizontal-with-ratios {
#apply(--layout-horizontal);
}
.flexchild {
#apply(--layout-flex);
}
.flex2child {
#apply(--layout-flex-2);
}
.flex-equal-justified {
#apply(--layout-horizontal);
#apply(--layout-justified);
}
.decorator-container{
margin: 15px 5px 15px 5px;
min-height: 160px;
max-height: 240px;
}
.decorator-main{
padding-top: 10px;
min-height: 120px;
max-height: 240px;
overflow-x: hidden;
overflow-y: auto;
}
.decorator-heading-text{
font-size: 14px;
font-weight: 600;
padding-right: 5px;
}
.button-add-decorator{
color: #000;
background-color: #fff;
border: 1px solid #c5c5c5;
margin-left: 10px;
box-shadow: 0 0 7px rgba(0,0,0,0.2);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
}
.deco-buttons{
float: right;
margin: 0px 5px 0px 0px;
}
.deco-button{
color: #000;
background-color: #fff;
border: 1px solid #c5c5c5;
box-shadow: 0 0 7px rgba(0,0,0,0.2);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
}
button:hover{
box-shadow: 0 0 7px rgba(0,0,0,0.6);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.6);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.6);
}
input, select, textarea, .text, .password{
background: #fff;
}
input:hover, input:active, input:focus, select:hover, select:active, select:focus, textarea:hover,textarea:focus {
border-color: transparent;
box-shadow: 0 0 7px rgba(0,0,0,0.5);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.5);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.5);
}
input[disabled], select[disabled]{
color: #a2a2a2;
background-color: #e1e2e5;
}
.deco-dropdown{
padding-top: 8px;
padding-right: 10px;
padding-left: 10px;
}
.fa .fa-save {
padding-left: 5px;
padding-right: 5px;
}
.label-align{
padding-right: 3px;
}
.deco-row{
border-bottom: 0.5px solid #c3c3c3;
}
</style>
<div class="decorator-container">
<div class="flex-equal-justified decorator-heading-section">
<span class="decorator-heading-text">Decorators
<button class="button-add-decorator" on-tap="addNewDecorator" >+</button>
</span>
<template is="dom-if" if="{{saveFlag}}">
<div class="deco-buttons" style="color: #000;">
<button class="deco-button" on-tap="saveDecorators">Save</button>
</div>
</template>
</div>
<div class="decorator-main">
<form id="decoratorForm">
<template is="dom-repeat" items="{{decoratorList}}">
<div class="flex-horizontal-with-ratios deco-row">
<div class="flex2child" style="padding-left: 5px;">
<span>Text color </span>
<paper-swatch-picker id="textColor" column-count=5 color-list='[[colorList]]' color=[[item.textColor]] noink ></paper-swatch-picker>
</div>
<div class="flex2child">
<span>Cell color </span>
<paper-swatch-picker id="cellColor" column-count=5 color-list='[[colorList]]' color=[[item.cellColor]] noink ></paper-swatch-picker>
</div>
<div class="flex2child">
<span>Border color </span>
<paper-swatch-picker id="borderColor" color=[[item.borderColor]] noink ></paper-swatch-picker>
</div>
<div class="" style="padding-top: 8px; padding-right: 4px;">
<button class="button-add-decorator" on-tap="removeDecorator" id="[[index]]">X</button>
</div>
</div>
</template>
</form>
</div>
</template>
</div>
<script>
Polymer({
is: 'msk-decorator',
properties: {
selectedColor: {
type: String,
value: '#E91E63',
notify: true
},
decoratorList: {
type: Array,
notify: true,
value: []
},
decoratorObject: {
type: Object,
value: {
textColor: '',
cellColor: '',
borderColor: ''
}
},
dataType: {
type: String,
notify: true
},
tagId: {
type: String,
notify: true
},
requestObj: {
type: Object,
value: {
id: null,
addDecorator: [],
editDecorator: [],
deleteDecorator: []
}
},
saveFlag: {
type: Boolean,
notify: true
},
colorList: {
type: Array,
notify: true
},
dataURL:{
type: String,
value: function (){
var url = '/api/FindDecorators';
return url;
}
}
},
ready: function () {
this.init();
},
attached: function() {
},
typeChanged: function(e) {
console.log("typeChanged", e);
},
init: function(){
this.decoratorObject = {
textColor: '#000000',
cellColor: '#000000',
borderColor: '#000000'
};
this.format = [{
id: "9999",
label: "9999"
},
{
id: "9999.9",
label: "9999.9"
},
{
id: "9999.99",
label: "9999.99"
},
{
id: "9999.999",
label: "9999.999"
}];
this.type = [{
id: "NE",
label: "NOT EQUAL"
},
{
id: "E",
label: "EQUAL"
}];
this.value = [{
id: "1",
label: "Running"
},
{
id: "0",
label: "Stopped"
}];
},
addNewDecorator: function(e){
this.push('decoratorList', this.decoratorObject);
this.saveFlag = true;
},
removeDecorator: function(e){
if(e.target.decoratorId > 0){
this.push('deletedDecoratorList',e.target.decoratorId);
}
var i = Polymer.dom(e).rootTarget.id;
this.splice('decoratorList', i, 1);
this.saveFlag = true;
},
showFormat: function(dataTypeValue){
if(dataTypeValue.indexOf('Enum') > -1)
return true;
else
return false;
},
isIdExists: function(tagId){
if(tagId){
return true;
}else{
return false;
}
},
displaySave: function(){
if(this.saveFlag){
return true;
}else{
return false;
}
},
handleResponse: function(res, ele){
this.decoratorList = [];
if(this.decoratorList.length > 0){
this.saveFlag = true;
}else{
this.saveFlag = false;
}
},
saveDecorators: function(){
console.log('saveDecorators' + this.decoratorList);
for(var i=0; i < this.decoratorList.length; i++){
console.log(this.decoratorList[i]);
}
}
});
</script>
</dom-module>
</body>
</html>
I think you can use the value-changed event which will return a CustomEvent wich has the changed element in it:
attached: function() {
let pickers = this.$.decoratorForm.querySelectorAll('paper-swatch-picker');
pickers.forEeach(el => el.addEventListener('value-changed', event => {
// Do the Array manipulation here based on the event.detail.item
});
}
// also remove the event listener in detached(), but for that you need
// to define the function elsewhere and just passing it's reference to
// the addEventListener.
Then you can make the this.decoratorList manipulation, thats will be synchronized with the {{decoratorList}} data binding.
NOTE: The value-changed event is fired when a notify: true property changed, so it may fired multiple times if an internal event changing multiple properties in an element.
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;
}
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.