logo

Thông báo

Icon
Error

Chia sẻ
Tùy chọn
Xem
Xem bài viết cuối
Offline admin  
#1 Đã gửi : 16/03/2015 lúc 04:50:07(UTC)
admin

Danh hiệu: Administration

Chức danh:

Nhóm: Administrators
Gia nhập: 23-07-2013(UTC)
Bài viết: 6,102
Man
Viet Nam
Đến từ: Vietnam

Cảm ơn: 10 lần
Được cảm ơn: 2 lần trong 2 bài viết

Breaking the Ice with AngularUI Utils

The UI Utils library is a powerful utility package that makes a lot of custom extensions available to your project without needing to reinvent the wheel.

We’ll cover a few notable features that the ui-utils library gives us, including:

  • input masking
  • custom event handling
  • custom formatting
  • jQuery passthrough directives
  • string inflector
  • fragment inclusion based on selectors
  • text highlighting
  • more…

Installation

1
$ bower install --save angular-ui-utils

We’ll need to ensure that we include the library in our HTML template. Each component of the ui-utils library is built as an individual module, so we’ll need to include each one independently.

Mask

When we want to take a credit card or a phone number (or any other input that requires a specific format), we can present a clean UI that tells our users that they are giving us clean input.

We’ll need to ensure we include the mask.js library in our HTML:

1
<script type="text/javascript" src="app/bower_components/angular-ui-utils/modules/mask/mask.js"></script>

And set the ui-mask as a dependency for our app:

1
angular.module('myApp', ['ui.mask'])

Now, we can specify input masks using the ui-mask directive. The ui-mask directive takes a single format string that follows the formatting rules:

  • A - any letter
  • 9 - any number
  • * - any alphanumeric character

For instance, to format a credit card number in an input, we might set the ui-mask directive to the following:

1
<input name="ccnum" ui-mask="9999 9999 9999 9999" ng-model="user.cc" placeholder="Credit card number" />

Note that, similar to how Angular input works, the input will not be valid until it matches the mask.

See it

Try a few credit card numbers out, like:

Or type yours in (don’t worry, we’re not saving it).

Credit card:
Credit card type:

Note that this input only supports credit cards whose input mask matches 9999-9999-9999-9999. With a bit more work, we can support other card types.

In the same sense, we can format an input field with characters or any alphanumeric character.

ui-event

Just like the other modules, we’ll need to include the event.js library in our HTML:

1
<script type="text/javascript" src="app/bower_components/angular-ui-utils/modules/event/event.js"></script>

And we need to include the ui.event as a dependency for our app, as well:

1
angular.module('myApp', ['ui.event'])

When we want to handle events that are not natively supported by AngularJS (for instance, if we want the user to double click on an element or handle a blur event), we’d have to write a wrapper around the native browser events.

This ui-event module is simply a wrapper around native events; therefore, we can use it to respond to any event that the browser fires on any element.

For instance, let’s say we want to reveal an image after the user double clicks on another image. We simply set the ui-event directive to a key-value pair with the event name and the action to take when the element catches the event.

For instance, in our HTML, we can set a double click dblclick event to call a showImage() function on our controller:

1
2
<img src="/images/ui/ginger.png"

ui-event="{dblclick:'showImage()'}" />

And in our controller, we can write our the method on the scope like normal:

1
2
3
4
5
.controller('DemoController', ['$scope', function($scope) {

$scope.showImage = function() {

$scope.shouldshowImage = !$scope.shouldshowImage;

}

}]);

See it

Double click the image

Since the ui-event directive is simply a wrapper around native browser events, we can use it to mimic any browser event on any element.

For instance, if we want to capture a blur or focus event on an element, we can use the ui-event directive to capture these events for us.

Let’s say we want to provide some helpful tips for filling out a form. We can set actions on the focus event and theblur event to show and reveal these help tips.

For instance, if we have a form that includes the input fields of name and email, we can attach functions to our blur and focus events to show help events.

1
2
3
4
5
6
7
8
9
10
<form name="form">

<input type="text" name="name" placeholder="Your name"

ui-event="{focus: 'showNameHelp=true',

blur: 'showNameHelp=false'}"

/>

<input type="email" name="email" placeholder="Your email"

ui-event="{focus: 'showEmailHelp=true',

blur: 'showEmailHelp=false'}"

/>

</form>

With these events set on the input fields, we can show our help fields, depending on which field the user is focused on, in the Angular way (i.e., using ng-show and ng-hide).

See it

ui-format

We’ll need to ensure we include the format.js library in our HTML:

1
<script type="text/javascript" src="app/bower_components/angular-ui-utils/modules/format/format.js"></script>

And set ui.format as a dependency for our app:

1
angular.module('myApp', ['ui.format'])

The format library is a wrapper around different ways to work with string tokens. It enables us to work directly with variable tokens that we expect in our app.

Token replacement with the format library works with either an array or a key-value/JavaScript object. For instance:

1
{{ "Hello $0" | format: 'Ari' }}

See it

{{ "Hello $0" | format: 'Ari' }}
Hello Ari

Alternatively, we can bind the name to a variable on our scope and use the format library to present it in a clean format. Let’s say we have a controller that looks like:

1
2
3
4
angular.module('myApp', ['ui.format'])

.controller('FormatController', ['$scope', function($scope) {

$scope.name = 'Ari';

}]);

We can format the input against that bound variable on the $scope:

See it

{{ "Hello $0" | format: name }}
Hello Ari
Modify name

Although this example isn’t particularly interesting (and this functionality comes out of the box with Angular), it becomes interesting when we want to manipulate text on a key-value basis.

For instance, we can format a string based on the keys of an object we have. Let’s say we have an object with a nameand an email attribute:

1
2
3
4
5
6
.controller('FormatController', ['$scope', function($scope) {

$scope.person = {

name: 'Ari',

email: 'ari@fullstack.io'

}

}]);

We can change our markup to include the keys (i.e., name and email) as tokens such that our app replaces them with input values:

1
{{ "Hello :name. Your email is :email" | format: person }}

See it

{{ "Hello :name. Your email is :email" | format: person }}
Hello Ari. Your email is ari@fullstack.io

The format module is particularly useful when working with translations or i18n support (for more on translations, check out our post on i18n support).

CodeMirror

The CodeMirror web IDE is pretty fantastic. The community is wildly active, and the support for building plugins inside the IDE is stellar.

The AngularUI library supports embedding CodeMirror instances in our page.

To install the angular-ui-codemirror library, we can use Bower:

1
$ bower install angular-ui-codemirror

In our index.html file, we’ll need to reference the angular-ui-codemirror library as a dependency, as well as the codemirror library and any modes that we want to install.

1
2
<script type="text/javascript" src="app/bower_components/codemirror/lib/codemirror.js"></script>

<script type="text/javascript" src="app/bower_components/angular-ui-codemirror/ui-codemirror.js"></script>

Once we have completed that set up, we’ll need to set the injection of ui.codemirror as a dependency for our application:

1
angular.module('codemirrorApp', ['ui.codemirror']);

Now we can use the ui-codemirror directive on our textarea HTML object to create an editing environment:

1
<textarea ui-codemirror ng-model="code"></textarea>

See it

function(name) {
    alert("Hello " + name);
}

Now, just like using plain CodeMirror, we can set options on our instance. We pass options in the ui-codemirrordirective, like so:

1
<textarea ui-codemirror="editorOptions" ng-model="code"></textarea>

Now we can either pass editorOptions as an object that is on a controller (as we did above) or we can even pass those options as a string (that will be parsed):

1
<textarea ui-codemirror="{mode: 'javascript'}" ng-model="code"></textarea>

The CodeMirror plugin has many options that we can use to manipulate our CodeMirror instance, from helping us to handle code events to giving us direct access to the CodeMirror instance.

The ui-codemirror options can take any options that the CodeMirror instance requires. For instance, if we want to change the theme of the CodeMirror instance, we’ll need to change options on that instance.

We can get access to it by creating an onLoad event handler that stores the instance of the CodeMirror. Then, we can update the actual CodeMirror instance and do all sorts of fun magic.

To get started, let’s pass an onLoad event in our options:

1
2
3
4
5
6
7
<div class="editor" ng-controller="CodemirrorController">

<textarea ui-codemirror="{

lineNumbers: true,

mode: 'javascript',

onLoad: codemirrorLoaded

}" ng-model="code1"></textarea>

</div>

Now, in our CodemirrorController, we can add the function codemirrorLoaded, which simply stores the CodeMirror instance on our scope:

1
2
3
4
5
6
7
// ...

.controller('CodemirrorController', ['$scope', function($scope) {

$scope.editor;

$scope.codemirrorLoaded = function(_editor){

$scope.editor = _editor;

}

}]);

With that set, we can pretty much do anything we want to the CodeMirror instance, as we now have access to it on the scope.

Let’s provide an option for the user to change the theme of his CodeMirror instance. We’ll provide a dropdown select menu that will display all of the CSS files we have available. When the user selects a new theme, we’ll update the theme of the CodeMirror instance.

Inside of our CodemirrorController (ideally, inside of a directive), we can add the functionality to handle theming the instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// ...

.controller('CodemirrorController', ['$scope', function($scope) {

$scope.editor;

$scope.codemirrorLoaded = function(_editor){

$scope.editor = _editor;

}

$scope.theme = '3024-night';

$scope.themes = [

'3024-day',

'3024-night',

'eclipse',

'neat',

'monokai',

'elegant'

];

$scope.$watch('theme', function(newVal) {

if (newVal) { $scope.changeTheme(newVal); }

})

$scope.changeTheme = function(theme) {

if ($scope.editor) {

$scope.editor.setOption('theme', theme);

}

}

}]);

See it

1
function(name) {
2
    alert("Hello " + name);
3
}
Change the editor theme 3024-day3024-nighteclipseneatmonokaielegant

You can see that this UI element is very powerful. A little more work, and we can create a CodePen or JS Bin.

You can find more here.

Google Maps

People often ask us how they can best integrate Google Maps in Angular apps.

The AngularUI toolkit comes with a Google Maps directive that’s pretty darn good.

See it

To install the angular-ui-map library, we can use Bower:

1
$ bower install --save angular-ui-map

In our index.html file, we’ll need to reference this angular-ui-map library, the map library, and the events library as dependencies; we include this last library because map relies on the UI Utils event library.

1
2
<script type="text/javascript" src="app/bower_components/angular-ui-utils/modules/event/event.js"></script>

<script type="text/javascript" src="app/bower_components/angular-ui-map/src/map.js"></script>

Lastly, we’ll need to load the Google Maps API JavaScript.

For simplicity’s sake, we won’t walk through the best practices for loading Google Maps into our app. We’ll cover this topic in our upcoming book ng-book: The Complete Book on AngularJS

To include this JavaScript as a library in our app, Google requires us to have a callback function that alerts our page that the Google Maps object is ready to go. To handle this function, we’ll create a callback that the Google API will call on our page.

First, the inclusion:

1
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=onGoogleReady"></script>

With this callback set up, we’ll need to set the injection of ui.map as a dependency for our application:

1
angular.module('appMap', ['ui.map']);

Now we have to manually bootstrap our Angular app, as we’re dependent upon the Google Maps JavaScript library to load before we can run. Angular makes it easy.

Notice that when we included the Google Maps API JavaScript, we attached a callback with the name of a function (that we will define) called onGoogleReady. Google will call this function after the Maps API has loaded. Inside this function, we’ll tell our Angular app to bootstrap:

1
2
3
function onGoogleReady() {

angular.bootstrap(document.getElementById("mapApp"), ['appMap']);

}

Now we can guarantee that the Google Maps API has loaded for us before our app even boots up.

Next, we can attach our app module to the HTML and place controller (where we will attach our map options) inside of it:

1
2
3
4
5
<section id="mapApp" ng-controller="MapController">

<div ui-map="myMap"

ui-options="mapOptions"

class="map-canvas"></div>

</section>

Our section element houses our mapApp and ties the MapController to the DOM element. Inside the app element, we also have a div that holds onto the google.maps.Map object through the ui-map directive and a google.maps.MapOptions object through the ui-options directive created by the Google Maps API.

We now have access to the raw Google Maps objects on the scope of our MapController. From here, we can do all sorts of fun stuff, setting the options we want to manipulate.

Check out the demo below and click here for the full source.

See it

We’ve covered a small portion of the angular-ui library today; we hope that you’ll check out the angular-ui library for yourself for many more Angular options. There are plenty of libraries out there to help you build amazing projects.

Get in touch if you have any comments or concerns about this post or any of the others!

Ai đang xem chủ đề này?
OceanSpiders 2.0
Di chuyển  
Bạn không thể tạo chủ đề mới trong diễn đàn này.
Bạn không thể trả lời chủ đề trong diễn đàn này.
Bạn không thể xóa bài của bạn trong diễn đàn này.
Bạn không thể sửa bài của bạn trong diễn đàn này.
Bạn không thể tạo bình chọn trong diễn đàn này.
Bạn không thể bỏ phiếu bình chọn trong diễn đàn này.

| Cung cấp bởi YAF.NET 2.2.4.14 | YAF.NET © 2003-2019, Yet Another Forum.NET
Thời gian xử lý trang này hết 2.913 giây.