Check out our new training course on AngularJS for Flex Developers

Event Handlers - Building Angular Directives - Part 6

This is the sixth post in a series about building Angular Directives. The purpose is to create a directive which will loop over a list of items, and allow the user to delete one of the items. The result will look something like this:

This post will show you how to execute an external method based on actions inside the directive.

Be sure to check out part one, part two, part three, part four, and part five.

Create the Event

For this post, we are going to create a API element on the directive that responds to the deletion of an item in the directive. I compare it to event handling, because that is what I used in the ActionScript realm; but the implementation is simpler.

The first thing we need to do is tell the directive that it has an event handler. This is done in the directive's isolated scope:


scope : {
dataprovider : '=',
label : '=labelfield',
itemdeleted : '&'
}

The dataprovider and the label were covered earlier in this whitepaper. The itemdeleted property is new. You'll notice its value is an ampersand; not an equal sign. This is a way to tell Angular that a function is expected, not a variable. Similar to the label, the itemdeleted could also specify a different internal name, like this:


itemdeleted : '&onitemdelete'

For the purposes of this sample, I decided not to use a different name externally verse internally.

Next go to the onDeleteRequest() method inside the directive's link function. This method is executed when the X button in the view is clicked. It loops over the array; and uses the JavaScript splice method to remove the item from the array.


scope.onDeleteRequest = function(object){
for (var counter = 0; counter <= scope.dataprovider.length; counter++){
if(object === scope.dataprovider[counter]){
scope.dataprovider.splice(counter, 1);
scope.itemdeleted();
break;
}
}
}

After the splice is executed; the itemdeleted() event handler is called. This is done by referencing the scope value inside the link function, and executing the method on it. If no itemdeleted event handler is defined, this silently fails.

Create the Event Handler

We've modified the directive to execute the event handler, but now you need to know how to use it. Go back to the main HTML file and create a handler method inside the directiveTestController:


$scope.onItemDelete = function(){
$scope.itemDeletedMessage = 'item deleted';
}

This method creates a $scope variable named itemDeletedMessage and sets it value to itemDeleted. Let's default that $scope variable while we're in the controller:


$scope.itemDeletedMessage = '';

We have the directive all set, and a method to be executed by the directive. Let's put it all together.

In the HTML portion of this sample app, do this:


{{itemDeletedMessage}}
<dci-testdirective dataprovider="objectArray" itemdeleted="onItemDelete()">
</dci-testdirective>

The scope variable, itemDeletedMessage is shown above the directive. The itemdeleted event handler is created as an attribute on the dciTestdirective. It calls the controller's onItemDelete() scope value.

This is the app with an item deleted:

Play with this sample!

Pass an Argument to the Event Handler

Angular directives also allow us to pass arguments from inside the directive to the event handler method. We'll pass the object that had just been deleted. First, save the object in a variable:


var deletedObject = scope.dataprovider[counter];

Next, perform the deletion:


scope.dataprovider.splice(counter, 1);

And finally, perform the handler call:


scope.itemdeleted({deletedObject:deletedObject});

The value of the itemdeleted method call is an object. Each property on the object represents a parameter that can be passed into the external method. Angular does magic behind the scenes to sync the object of arguments with the actual arguments.

In the HTML directive, add deletedObject as an argument to the itemdeleted function call:


<dci-testdirective dataprovider="objectArray"
itemdeleted="onItemDelete(deletedObject)">

</dci-testdirective>

In the main app's controller, add the argument to the onItemDelete() function::


$scope.onItemDelete = function(deletedObject){
$scope.itemDeletedMessage = deletedObject.itemLabel + ' item deleted';
}

The code introspects the deletedObject's label to modify the item deleted message, so the user will know exactly which item has been deleted:

Play with this sample!

What's Next?

When I was doing Flex and ActionScript development, there was a clear definition for what an event handler was and how to use events in components. Angular has a similar event system, based off the RootScope service, but the implementation inside directives is different. It is more like a closure, or passing a method around as a variable, then executing it when needed. I'm not sure what to call this in Angular dev, but ended up going with my understood nomenclature of event handlers and event dispatching; even if that isn't 100% accurate.

So far this series has covered how to pass data into a directive, how to get data out of a directive, and how to have the directive execute methods outside of the directive. The next section I'll explain how to execute a method inside the directive.

Sign up for our 30 page white paper on Angular Directives

Connecting the View and Link Function - Building Angular Directives - Part 5

This is the fifth post in a series about building Angular Directives. The purpose is to create a directive which will loop over a list of items, and allow the user to delete one of the items. The result will look something like this:

This post will show you how the HTML view will integrate with a link function.

Be sure to check out part one, part two, part three, and part four.

Wire up the Delete Button

This post will add more functionality to the directive that has been created in this series. We will wire up the delete button to remove an item from the dataprovider array. If you've done Angular development, you are most likely familiar with the basic concepts we will cover here.

First, we're going to wire up the delete button. Open up the template and add an ngClick to the button:


<div class='dciTestdirective-width100' ng-repeat='object in dataprovider'>
<span class='dciTestdirective-horizontal-layout-94'>
{{object[label]}}
</span>
<span class='dciTestdirective-horizontal-layout-4' >
<button ng-click="onDeleteRequest(object)">X</button>
</span>
</div>

When the button is clicked it will execute the onDeleteRequest() function inside the directive's link function. The object passed as a parameter refers to the specific item of the dataProvider defined in the ngRepeat that creates the list.

Inside the link function of the component, create the onDeleteRequest() function:


scope.onDeleteRequest = function(object){
console.log('onDeleteRequest');
}

This is a placeholder function. At this moment, you can test code and you should see the onDeleteRequest text output to your browser's console.

Implement the Delete Function

The purpose of this delete button is to remove an item from the dataprovider array. To do this, we will loop over the dataprovider until we find the proper object. We can use the JavaScript splice() function to remove the item from the array.

First, create the loop:


for (var counter = 0; counter <= scope.dataprovider.length; counter++){
}

Inside the look compare the object parameter with the current element of the dataprovider:


if(object === scope.dataprovider[counter]){
scope.dataprovider.splice(counter, 1);
break;
}

If the passed object and the current dataprovider element are the same object; then use the JavaScript splice() method to remove the item from the dataprovider array. The splice() method takes two parameters. The first is the array index where the removal of items starts. The second value is the number of items to remove. In this case; we remove only a single item.

Play with this Sample!

What's Next

The way the directive template communicates with the link function is no different, conceptually, than how any HTML view communicates with its controller. You've probably used the ngClick directive on buttons, or other elements, plenty of times in your own Angular development adventures. The approach is the same.

The next section will show how to bind an external method to an interaction inside of a directive.

Sign up for our 30 page white paper on Angular Directives

Defaulting Directive Arguments - Building Angular Directives - Part 4

This is the fourth post in a series about building Angular Directives. The purpose is to create a directive which will loop over a list of items, and allow the user to delete one of the items. The result will look something like this:

This post will show you how to default the parameters passed into a directive.

Be sure to check out part one, part two, and part three.

Creating a link Function

In the previous entry, I showed how to use an isolated scope to pass arguments into a directive. This allowed for the same directive to be used multiple times, with different data, in a single view. So far, all the directive's arguments must be defined or else an error would be thrown. We did not include any way to default argument values. This article will show you how to use a link function to default argument values.

A link function is a way to associate JavaScript code with the directive. It is included as a property on the directive object. Here is a sample link function, defined as part of the directive object:


link : function(scope, element, attrs, controller, transcludeFn ){
}

There are five arguments to the link function:

  • scope: The scope variable is, for all intents and purposes, identical to the $scope service you use in most controllers. It is used to share variables and functions between the link function and the view.
  • element: The element value represents the HTML element that is the directive. It is a JQuery lite object. Primarily you would use this for manipulation of the JavaScript code.
  • attrs: The attrs is an object that contains name value pairs for each attribute passed into the directive. In the case of dciTestdirective it will include the labelfield and dataprovider.
  • controller: The controller argument refers to the directive's controller. If the directive has its own controller then this will refer to that controller. Otherwise, it will refer to the controller of the view that contains it. Using controllers in a directive is beyond the scope of this whitepaper.
  • transcludeFn: The transcludeFn argument refers to the transclude function. Transclusion is beyond the scope of this whitepaper.

Arguments are passed into the link function in a specific order. This is different than many other areas of Angular, such as controllers, that use dependency injection. This is the primary reason the scope argument is not called the $scope argument even though they are essentially the same thing. $scope is passed to a function using dependency injection based on the service name. In a link function, the scope is always passed as the first argument.

Populating the Link Function

The purpose of this link function is to set defaults for the label and dataProvider if they are not predefined. This can be done in JavaScript pretty easy:


if(!scope.label){
scope.label = 'itemLabel';
}
if(!scope.dataprovider){
scope.dataprovider = [];
}

Check if the variable exists and if it doesn't set it to some default value. The default value of the label value is the text itemLabel. The default value of the dataProvider attribute is an empty array.

We would leave that code as part of the link function's body and leave it as is. However, I am not a fan of 'random' code, so I'll often wrapup the initializing code in a function named onInit(), like this:


function onInit(){
if(!scope.label){
scope.label = 'itemLabel';
}
if(!scope.dataprovider){
scope.dataprovider = [];
}
};
onInit();

When the link function is initialized the onInit() method will be called, thus initializing the variables.

Using the Modified Directive

The modified directive can be used in three ways. The first is with no attributes set:


<dci-testdirective></dci-testdirective>

In this case the dataprovider defaults to an empty array and the labelfield property defaults to itemLabel. The result looks like this:

This is pretty boring because nothing is displayed at all.

The second approach is with the dataprovider set, but no labelfield set:


<dci-testdirective dataprovider="objectArray" ></dci-testdirective>

Here the dataprovider uses the value passed in while the labelfield is defaulted to itemlLabel. The result will look like this:

If the dataProvider did not include objects with the property itemLabel then this would have blank labels, but the X buttons would still be shown.

Finally, we can set all properties on the directive:


<dci-testdirective dataprovider="objectArray" labelfield="'itemLabel'">
</dci-testdirective>

The results here are same as the previous sample.

Play with this sample!

What Next?

Providing defaults for your directive's values is important because it provides flexibility to the directive's users.

Next week, this series will show how to implement the X button to remove items from the list. This will demonstrate how the link function and the template can interact.

Sign up for our 30 page white paper on Angular Directives

Passing Values into a Directive - Building Angular Directives - Part 3

This is the third post in a series about building Angular Directives. The purpose is to create a directive which will loop over a list of items, and allow the user to delete one of the items. The result will look something like this:

This post will focus on passing values into a directive.

Be sure to check out part one and part two.

Creating an Isolated Scope

An important aspect of building an encapsulated directive is to be able to pass data into it. This way, you can create multiple instances of a single directive, each using different data. Past entries of this series have relied on a local controller for data access. This entry will show you how to pass parameters into a directive by implementing a concept called isolated scope.

The first step to create an isolated scope is to add the scope variable to the directive object:


angular.module('directiveTestApp').directive('dciTestdirective',function(){
return {
scope : {
dataprovider : '=',
label : '=labelfield'
},
templateUrl : currentScriptPath + '04ExternalTemplate.html'
};
});

The scope variable is an object, which contains name values pairs. This directive contains two arguments:

  • dataprovider: The dataprovider argument will contain the array which is going to be looped over.
  • labelfield: The labelfield argument contains the property in the dataprovider's objects that will be used to display items.

I want to look at each scope value individually, and the syntax used to create it. Here is the label definition:


label : '=labelfield'

The variable name is label. This represents the name of the scope variable inside the directive. You will use the name label to reference this inside the template. The value of the variable is '=labelfield'. This refers to the attribute name that will be used when passing vales into the component. For the purpose of the label, I decided to use a different internal name than the external name.

Here is the dataprovider:


dataprovider : '='

The variable name is dataprovider. The value of the variable is just an equal sign, '='. This is a short hand way to tell Angular that the name of the variable inside the directive will be the same as the name of the attribute outside of the directive. In both cases, the name dataprovider is used.

I want to point out that the names of the properties are written all in lowercase. The attributes must be written in lowercase in order for Angular to properly sync the external attribute with the internal attribute. I have lost too many hours because I forget about the case sensitivity of scope variable names.

Referencing the Scope Variables in the template

Let's modify the template to reference the new scope variables. Previously the template was referencing variables in the scope of the controller, like this:


<div class='dciTestdirective-width100' ng-repeat='object in objectArray'>
<span class='dciTestdirective-horizontal-layout-94'>
{{object.itemLabel}}
</span>
<span class='dciTestdirective-horizontal-layout-4'>
<button >X</button>
</span>
</div>

We can change both the objectArray and the itemLabel values to reference our directive's scope variables:


<div class='dciTestdirective-width100' ng-repeat='object in dataprovider'>
<span class='dciTestdirective-horizontal-layout-94'>
{{object[label]}}
</span>
<span class='dciTestdirective-horizontal-layout-4'>
<button >X</button>
</span>
</div>

Changing the objectArray to the dataProvider is easy and a simple replacement. Since the item label is not a known value, object property notation cannot be used. In order to access the label, we use associative array notation. That completes the modifications to the template.

Passing Parameters into the Directive

The last step to get this working is to modify the directive to include the parameters in the main HTML page:


<dci-testdirective dataprovider="objectArray" labelfield="'itemLabel'">
</dci-testdirective>

The custom directive includes the two attributes we defined in the scope; the dataProvider and the labelfield. The dataProvider attribute references the objectArray; which is defined in the controller. The labelfield uses a hard coded string value which references the itemLabel property in the dataprovider's objects.

You can run the code now, and should see this:

Play with this now!

Even though the underlying architecture of the directive has changed; the actual UI has not.

Using the Directive with a Different Data

One of the benefits of creating the isolated scope is that you can use the directive multiples times with different data. Inside the controller of the main app, create a new array:


$scope.userArray = [
{fullName:'Jeffry Houser'},
{fullName:'Clark Kent'},
{fullName:'Oliver Queen'},
{fullName:'Barry Allen'},
];

This array, instead of being a generic objectArray is now a user array. It contains real fake user data which includes a user's full name.

You can easily add another instance of the dciTestdirective to the main HTML:


<dci-testdirective dataprovider="userArray" labelfield="'fullName'">
</dci-testdirective>

The directive usage is the same, but the userArray and labelfield attributes both reference the new properties.

Run this code!

What Next?

Giving the directive an isolated scope allows the directive to be easily reusable. I focused on how to get data into a directive; but the same approach is used to get data out of a directive. When the value inside the directive changes the variable outside the directive also changes.

In the next entry of this series, I'm going to show you how to set default values on the scope variables.

Sign up for our 30 page white paper on Angular Directives

Using External Templates - Building Angular Directives - Part 2

This is the second post in a series about building Angular Directives. The purpose is to create a directive which will loop over a list of items, and allow the user to delete one of the items. The result will look something like this:

This post will focus on moving the directive's template into an external file.

Be sure to check out part one of this series.

Create a Template

I find that inline templates are hard to modify. This becomes a problem as the template grows in complexity and size. No one wants to edit HTML as if it were a large string. Thankfully Angular supports the use of an external template.

First, let's revisit our existing directive:


angular.module('directiveTestApp').directive('dciTestdirective',function(){
return {
template: "<div ng-repeat='object in objectArray'>
<span>{{object.itemLabel}}</span>
<button>X</button>
</div>"
};
});

This directive loops over an array of objects and displays them. The directive object has one property, named template. Let's move the template contents to an external template.

Create a file named 02ExternalTemplate.html. The 02 in front of the name tells us that this file is part of the second sample for this article series. The text tells us what the file is used for. Populate the file with some cut and paste:


<div ng-repeat='object in objectArray'>
<span>{{object.itemLabel}}</span>
<button>X</button>
</div>

That is simple. Now let's tell the directive how to use the template.

Tell the Directive to use an External Template

The original directive uses the template property on the directive object. We are going to replace it with the templateUrl property. The templateUrl property tells Angular to look at an external file for the template:


angular.module('directiveTestApp').directive('dciTestdirective',function(){
return {
templateUrl : '02ExternalTemplate.html'
};
});

Run the code as is, and you'll see the same screen you saw before.

Changing the underlying architecture has not changed the HTML page.

Add Some Styles

While we're creating the external template, let's add some styles to make it look a bit nicer. For the sake of this sample, I'll add the styles directly to the external template file. First, I'll show you the styles to create and then we'll modify the HTML to use the styles.

First, I want the directive to expand the full width of the container it resides in. I can do this with a style like this:


<style>
.dciTestdirective-width100 { width:100% }
</style>

Next, I want the item label to spread as far as it needs; while the x button should take up a smaller portion of the available space. First, the style for the label:


.dciTestdirective-horizontal-layout-94{
display: inline-block;
vertical-align: top;
width:94%;
height:100%;
}

The style code can go in the same style block as the width100 style. The display property is set to inline-block so that the two elements reside next to each other.

This is the style for the button:


.dciTestdirective-horizontal-layout-4{
display: inline-block;
vertical-align: top;
width:4%;
height:100%;
}

The style for the button is almost identical to the style for the label. The big differentiator is that the width is set to a different percentage.

Now look at the modified HTML:


<div class='dciTestdirective-width100' ng-repeat='object in objectArray'>
<span class='dciTestdirective-horizontal-layout-94'>
{{object.itemLabel}}
</span>
<span class='dciTestdirective-horizontal-layout-4'>
<button >X</button>
</span>
</div>

The top level div uses the dciTestdirective-width100 style to stretch the box the full width of its container. The label is put in a span and uses dciTestdirective-horizontal-layout-94. The button is put in a different span with the style of dciTestdirective-horizontal-layout-4, giving it 4% of the allotted space.

The button was not previously wrapped in an HTML element. I did this because I wanted to change the size of the space the button was in; but not the actual button size.

The final result should look something like this:

Play with it here!

When creating styles for a directive, I like to explicitly put the directive name in the style name. The intent is to avoid conflicting style names when used in a bigger app, with multiple style sheets.

Find the External Template, Relative to the JavaScript File

When building for reuse I don't want to make assumptions on the location of the directive, relative to the web root. As such, I do not like hard coding the location of the template file. I found a great approach for dynamically finding the external template relative to the JavaScript file.

First, get a hook to the script tag:


var scripts = document.getElementsByTagName("script")

Then, pull the src attribute to the script tag:


var currentScript = scripts[scripts.length-1].src;

Now we have the location of the JavaScript file. Next, pull the file name off the currentScript to get the current path:


var currentScriptPath = currentScript.substring(0, currentScript.lastIndexOf('/') + 1)

Finally modify the templateUrl property of the directive:


return {
templateUrl : currentScriptPath + '02ExternalTemplate.html'
};

Rerun the directive and you should see the exact same screenshot as before. I like to put the script processing as part of the directive code before the return object.

Check out the live sample.

What Next?

This post covered two aspects of directive development: moving the HTML code to an external template and adding some simple styles to the directive. For the purposes of this sample, the CSS was kept inline as part of the template file. When building more complex systems, I'll put the styles in their own CSS file. To make use of the directive, the consumer must include the directive JavaScript and the CSS.

Next I'll show you how to pass values into the directive, thus removing the dependency on specific variables defined in the controller.

Get our 30 page white paper on Angular Directives

A Simple Directive - Building Angular Directives - Part 1

This is the first in a series of blog posts about building Angular Directives.

An AngularJS Directive combines HTML and JavaScript code into a single unit that can be easily reused within an Angular application. This series is intended to explore Angular directives, with a focus on optimizing the directive code for reuse.

Our Directive

The directive we're going to create in this paper will generate a list of items. It will loop over an array of items, and display each item, along with a delete button. The final directive will look something like this:


In this series, you'll learn how to setup the directive, use external templates for HTML, send values into the directive, run functions when something in the directive happens, and how to call functions inside the directive. This first section will create a basic directive which we will iterate over throughout this series.

Create the App Infrastructure

The first thing we need to do in any AngularJS project is to import the framework:


<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js">
</script>

The Angular framework is imported using the HTML Script tag. Next, create the Angular module:


<script>
angular.module('directiveTestApp',[]);
</script>

The Angular module is named directiveTestApp and there are no arguments passed into the directive. The rest of our JavaScript code for this article will go inside this script tag.

Every Angular app needs a controller:


angular.module('directiveTestApp')
.controller('directiveTestController',
['$scope',
function($scope){
}
])

There is no content in the main controller yet, but we'll come back to that.

Next, create the HTML code for this application:


<body ng-app="directiveTestApp">
<div ng-controller="directiveTestController">
</div>
</body>

The HTML UI is empty for the moment; but the module name is added to the body tag with the ngApp directive. The directiveTestController is added to a div with the ngController tag. If you have experience with Angular applications, then this approach should be familiar.

One last thing I want to do in the controller is to create the array of items that the directive will loop over. Inside the controller, create a JavaScript array:


$scope.objectArray = [
{itemLabel:'item1'},
{itemLabel:'item2'},
{itemLabel:'item3'},
{itemLabel:'item4'},
{itemLabel:'item4'}
];

Now we are set to create our first directive.

Creating a Simple Directive

An Angular directive is created as part of an Angular Module. A directive function is used. It requires two arguments, similar to how services, controllers, and other Angular elements are created. The first argument is a string that specifies the name of the directive. The second is a function which defines the directive's functionality.


angular.module('directiveTestApp').directive('dciTestdirective',function(){
});

The directive is named dciTestdirective, and I'll talk more about naming in a second. Right now the directive doesn't do anything, and if you were to try to use it, Angular would return an error. The directive function must return an object that contains properties which define the directive. In this case, we are only going to specify a single parameter, the template:


return {
template: "<div ng-repeat='object in objectArray'>
<span>{{object.itemLabel}}</span>
<button >X</button>
</div>"
};

The template contains some in-line HTML. It loops over the objectArray; which was created in the app's controller; and displays the itemLabel along with an X button.

Now add the directive to the HTML, inside the controller:


<dci-Testdirective></dci-Testdirective>

Run the code and you'll see this:


Play with this sample here.

How do you name a Directive?

Naming of directives is a subject that should be approached with care. When I first started learning directives, this confused me. The key is to understand that there are two parts to each directive, the prefix and the directive name. When naming a directive with the directive function, the prefix should start in all lowercase. The name starts with a capital letter. So, in the case of our directive the prefix is dci--which is short for DotComIt, my company. The name is Testdirective.

When Angular parses the DOM, it looks for selectors, such as element names or arguments, using a specific formula that is called normalization. Our directive, named dciTestdirective could be written in any number of ways in the HTML template:

  • dci-testdirective
  • dci: testdirective
  • dci_testdirective
  • data-dci-testdirective
  • x-dci-testdirective

If Angular finds something in one of the above formats, it runs it through a process called normalization. Then this process occurs:

  1. The name is put into all lowercase.
  2. x- or data- are stripped from the front of the element or attribute.
  3. The delimiters are removed. The dellimiters are the colon (:), dash (-), or underscore (_).
  4. The first character after the delimiter is made into uppercase.

When creating a directive, you must name it properly or else Angular won't know how to match the use of the directive to the actual directive code.

For practical purposes, I always use the dash (-) as a separator between the directive prefix and the directive name. I never put use the prefix x- or data- with my directives.

What Next?

The current directive is lacking. Here are some problems:

  • The objectArray must be defined in the controller where you use the directive. This is not good use of encapsulation. The directive should have its required parameters passed to it using a defined API.
  • The template is created in-line as a single string, which makes it hard to change or edit.
  • The in-line template could be styled to improve its look.
  • The functionality is not yet complete. The 'x' button does nothing yet, and the directive offers no other way to interact with the data it displays.

We'll iterate over this directive throughout this series in order to flesh this out. Next week, I'll discuss using an external template.

Sign up to receive our 30 page white paper on Angular Directives

How do I stop my Displayport Monitor from Flickering?

I've had this annoying flickering on my monitor every time I open Thunderbird. The screen would sporadically blink in and out of existence. I've seen the same problem in other programs, but Thunderbird was the most prominent. It was usable, but annoying. I just accidentally found the fix and wanted to document it in case others are experiencing the same issue.

First,let me tell you a bit about my setup:

I'm using a desktop Windows computer with an AMD Radeon 7750 video card.

The DisplayPort out of the video card goes into an AdderviewPro Displayport KVM Switch.

From there, the KVM Switch connects to a Dell U3011 30 inch Monitor. The monitor resolution is set to 2560x1600.

When the blinking occurred, I always thought it was due to the KVM Switch. I've always had mixed luck with KVM Switches--but when you have multiple computers at your desk I think the benefit outweighs the problems. [Other computers connected to the KVM Switch do not exhibit the same blinking problems].

I was reading up on some completely unrelated problems with my Surfacebook's dock and decided to dig into the blinking issue. I was wondering if changing the refresh rate would have an affect. I poured over options in the Radeon Settings panel:

Nothing seemed to make sense. Then I clicked the "additional settings" button:

After that, I noticed the preferred color depth setting. It was set to 10. As an experiment I changed it back to 8. Immediately all the blinking problems were gone. I'm not sure what the affects are from setting the color depth from 10 to 8. As best I can tell; the computer appears to be working as expected. I'll keep an eye on it to see if I run into any problems.

I've been using this for a while now without any problems. I have to admit I'm pretty shocked. I'm not sure what is more frustrating; that I lived with this for so long and it had an easy fix or that the problem existed in the first place.

Hopefully this helps someone.

How do I Copy Specific Text to the Clipboard using in JavaScript?

In some previous blog posts, I wrote about copying text to the clipboard using a ClipboardJS library. I demonstrated how to copy text from an input text field, and how to cut text from an input text field. I wanted to follow up that article to show you how to copy predefined text that the user can't edit.

Using ClipboardJS to Copy Specific Text

The first step in using the library is to import the library:


<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.5/clipboard.min.js"></script>

Once the library is imported, we must initialize it:


<script>
new Clipboard('.btn');
</script>

The initialization process uses JavaScript's new keyword to create an instance of the Clipboard object. The argument refers to the item in which the Clipboard library will listen for copy events. In this, case we are telling the library to look for all elements where the class was named 'btn'. On said elements, the library will look for special attributes that tell the library how to operate.

Now, create a button to perform the copy:


<button class="btn" data-clipboard-text="Some Predetermined Text">Copy Predetermined Text</button>

This button uses the class btn; which is the name of the class we used when initializing the Clipboard object. The clipboard library looks for the data-clipboard-text attribute; which is uses to determine what text should be copied. We can specify any text in the data-clipboard-text argument.

That is all we need to copy the text; the library takes care of the rest.

Test this out.

Sign up for DotComIt's Monthly Technical Newsletter

The Future of Flex and the Flash Player

This question comes in from a reader, about the future of Adobe Flex and the Flash Player:

Hello Jeffry, I know you because some answers your in StackOverFlow.

But my contact is because in Brazil we company is totally based in Adobe Flex used Flash builder 4.6 and AIR for mobile, and I would know you suggestion about future of Flex and flash.

I believe that programming for long year ahead because all programmer in my company lover Flex but sometime I have fear Adobe finish Flash player and my apps canĀ“t running in my clients.

I wrote a lot about the future of Flex in the past.

But, all those posts are few years old. What do I think today?

First, I am not an Adobe employee and am no longer part of the Adobe Community Professional program. I cannot offer any personal insight into what Adobe may do with the Flash Platform.

I do think the Flash Platform will be around for a long time. However, I do not see Flash as a growth area.

It is very difficult for me to run a Flash Debug Player on my Surface Book

Most new browser based applications are written using HTML5-based technologies. I have had success with AngularJS in the HTML5 world. I even wrote a training course about AngularJS for Flex Developers.

AIR for mobile seems a lot more viable than the browser based Flash Player. I know a lot of gaming companies still use AIR for mobile deployment.

In terms of Flex, the Apache Flex team has done wonderful things with Flex. Since you're still on Adobe Flex; I recommend you consider upgrading to the latest version of Apache Flex.

If your clients do not have problems running your apps today; I'm sure they'll continue to run them throughout the next year without any problems.

For those out there who are considering re-writing your apps to use HTML5 tools; feel free to reach out. I am available for consulting, training, or mentoring.

How do I copy an object in AngularJS?

I was recently working on an AngularJS project for a client. Some data was shown on a screen, and the user would click an edit button to open the same data in a popup modal. The problem I ran into was that any items changed in the popup where automatically changed in the main screen. This was causing some undesirable side affects. What if the user decided to cancel their changes or close the popup? The main screen would be affected.

I Decided to get around this by creating a copy of the object in question. I sent that copy to the popup; then when the popup is closed I can check whether the data was saved and make changes in the main app. But, if the changes in the popup are cancelled, I can dismiss the popup without having to modify the main app.

The question is; how do I perform a deep copy of an object in AngularJS? Use the copy method.

Here is how you can set up an application.

First, import the Angular framework, create a sample module, and a controller:


<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script>
angular.module('copyTest',[]);
angular.module('copyTest').controller('copyController', ['$scope', function($scope){
}]);
</script>

For this demo, create two separate objects, the baseObject and the objectCopy. The baseObject will contain a mock user object, with an id property, a firstname property, and a last name property:


$scope.baseObject = {
id : 1,
firstName : 'Jeffry',
lastName : 'Houser'
}

The objectCopy will initialize as an empty object:


$scope.objectCopy = {};

I'll build out a UI For editing object properties; then come back to the script:


<body ng-app="copyTest">
<div ng-controller="copyController">
<h2>Base Object</h2>
ID: <input type="text" ng-model="baseObject.id"> <br/>
First Name: <input type="text" ng-model="baseObject.firstName"><br/>
Last Name: <input type="text" ng-model="baseObject.lastName"><br/>

<h2>Copied Object</h2>
ID: <input type="text" ng-model="objectCopy.id"> <br/>
First Name: <input type="text" ng-model="objectCopy.firstName"><br/>
Last Name: <input type="text" ng-model="objectCopy.lastName"><br/>


<br/><br/>
<button ng-click="onCopy()">Copy Object</button>
<button ng-click="onReset()">Reset Base Object</button>
</div>

This app adds the Angular module onto the ngApp tag and the ngController onto a div. The user properties on both the base object and the copied object are put into text inputs. I also add two buttons, one to perform a copy from the base object to the objectCopy; and a second to reset the base object to its default values.

Load the app and you should see something like this:

Now, let's implement the onCopy() and onReset() methods. onReset() sets the baseObject to it's default state:


$scope.onReset = function(){
$scope.baseObject = {
id : 1,
firstName : 'Jeffry',
lastName : 'Houser'
}
};

The objectCopy is untouched.

The onCopy() method copies the base object into the objectCopy object and the baseObject is untouched:


$scope.onCopy = function(){
$scope.objectCopy = angular.copy($scope.baseObject);
};

Load the app and play with the options. This demo shows that edits to one object are not going to have an affect on the other object.

Modify the base object and click the copy button. The objectCopy fields will be populated with data. Change the objectCopy fields and the baseObject fields are not affected. Reset the baseObject and you'll see the objectCopy is not affected.

Play with the code here.

Sign up for DotComIt's Monthly Technical Newsletter

More Entries

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.