Click here to Skip to main content
13,258,269 members (42,333 online)
Click here to Skip to main content
Add your own
alternative version

Stats

16.3K views
1.4K downloads
15 bookmarked
Posted 9 Aug 2017

Learn Angular in 10 days - Day 3

, 24 Oct 2017
Rate this:
Please Sign up or sign in to vote.
A 10 Days series on Latest version of Angular - Today we will look Templates, Events, Models, Directives etc.

You are into this article means you know following things.

  • Install NodeJs and get npm
  • Install TypeScript compiler and use it
  • Install lite-server and use it
  • Have fundamental knowledge on TypeScript
  • Know how to setup a basic Angular Project
  • How to create a simple "Hello World" application using Angular.

Today, we will take our Angular skill to the next level with more labs and demos. Let’s get started.

Pre-Setup

Before you continue with any demo, I want you to do two things.

  • Open Command prompt, navigate to "TypeScriptFiles" folder and write "tsc -w" command to start TypeScript compiler in watch mode.

    It will make sure that every time a TypeScript file get changed it automatically get recompiled. There is no need for manual recompilation after every change.

  • Open another Command prompt, navigate to "AngularProject" folder and write "lite-server" command to start the webserver.

    It will automatically launch the browser (Internet Explorer). Copy the URL from the address bar, open Chrome and paste the same URL in the address bar.

    (Note: Chrome is best when it comes to JavaScript debugging, if you want you can do the testing in your favorite browser.)

    Moving forward, anytime any of the files in the "AngularProject" folder get changed, the browser automatically gets refreshed. Automatic refresh is the power of "lite-server".

Complete Series

  1. Day 1 – Part 1
  2. Day 1 – Part 2
  3. Day 2
  4. Day 3
  5. Day 4 – Part 1
  6. Day 4 - Execution trick
  7. Day 4 – Part 2
  8. Day 4 – Part 3
  9. Day 5 (Coming soon)
  10. Day 6 (Coming soon)
  11. Day 7 (Coming soon)
  12. Day 8 (Coming soon)
  13. Day 9 (Coming soon)
  14. Day 10 (Coming soon)

Contents

Lab 2 – Introduction to Template URL

In the last demo we created "AppComponent". Anguar Component is combination of two things.

  1. A TypeScript class called AppComponent – It’s called ViewClass or Component class. We will talk about real use of it very soon.
  2. Template - Which is purely a HTML and represents our UI.

In the current demo both of the above things are written in the same TypeScript file. Many people (including me) prefer to write HTML in an independent HTML file and have clear separation of concerns.

It can be done using "templateUrl". Let’s see how.

Step 1 – Create component folder

Create a new folder called "AppComponent" inside the "AppModule" folder. (Just to recall "AppModule" is located inside "TypeScriptFiles\AppModule" folder.)

Step 2 – Move component

Move "app.component.ts", "app.component.js" and "app.component.js.map" files into the "AppComponent" folder.

Step 3 – Correct the references

Change the import statement in "AppModule" as follows.

import {AppComponent} from "./AppComponent/app.component"

Complete AppModule code look like below.

import {NgModule} from "@angular/core"
import {AppComponent} from "./AppComponent/app.component"
import {BrowserModule} from "@angular/platform-browser"
@NgModule({
    declarations:[AppComponent],
    bootstrap:[AppComponent],
    imports:[BrowserModule]
})
export class AppModule{
}

Step 4 – Compile and test the output

Just to make sure that everything is proper let’s do the testing once. Go to the browser.

You should able to see the following output.

Step 5 – Create Template file.

Create a new file called "app.component.html" in the "AppComponent" folder and put following content inside it.

<h1>Welcome to Learn Angular in 10 days series</h1>
<i>Here is the Day 3</i>

Step 6 – Attach Template to Component

Use "templateUrl" option instead of "template" option in the "Component" decorator attached to "AppComponent" class as follows.

import {Component} from "@angular/core"
@Component({
selector:'app-component',
templateUrl:'./app.component.html'
}
)
export class AppComponent{
}

Step 7 - Compile and test the output

Go to the browser.

Check the error. As you can see ‘app.component.html’ is searched in the root folder.

Step 8 – Change Template URL

"templateURL" is relative but relative to "index.html" not to its TypeScript file. Change "templateURL" to "./TypeScriptFiles/AppModule/AppComponent/app.component.html" as follows. The complete code will look like below:

import {Component} from "@angular/core"
@Component({
selector:'app-component',
templateUrl:'./TypeScriptFiles/AppModule/AppComponent/app.component.html'
}
)
export class AppComponent{

}

Step 9 - Compile and test the output

Go to the browser.

Lab 3 – Working with relative URLS

In last lab we simply took out the HTML from TypeScript file and placed it in an independent HTML (template) file. The only problem was "templateUrl" was relative to "index.html".

If you want to keep "templateUrl" relative to the corresponding ".ts" file then this lab is for you.

It can be achieved by using a SystemJs plugin called "systemjs-angular-loader.js". SystemJs has support for external plugins using which we can extend the existing behavior of SystemJs. "systemjs-angular-loader.js" dynamically converts "component-relative" paths in "templateUrl" to absolute paths.

Let’s do the demo.

Step 1 – Download the plugin

This plugin was created by Angular team and it will be available in the quick start setup given by Angular team. Here is the link for the same.

https://github.com/Angular/quickstart/archive/master.zip

Download the zip file from the above link and extract it. "systemjs-angular-loader.js" file is present inside "src" folder.

(We will have a detailed demo explaining this quick start project in future, for now let’s do everything manually and let’s understand the core of everything.)

Step 2 – Include Plugin

Copy the extracted plugin and paste it in the "AngularProject" folder. Now open "system.config.js" and add plugin support as follows.

...
packages: {
      'TypeScriptFiles': {
        defaultExtension: 'js',
        meta: {
          './*.js': {
            loader: 'systemjs-angular-loader.js'
          }
        }
      },
      rxjs: {//New line
        defaultExtension: 'js'

Check the new "meta" option added.

Complete "system.config.js"

(function (global) {
  System.config({
    map: {
      '@angular/core': '/node_modules/@angular/core/bundles/core.umd.js',
      '@angular/common': '/node_modules/@angular/common/bundles/common.umd.js',
      '@angular/compiler': '/node_modules/@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': '/node_modules/@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': '/node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': '/node_modules/@angular/http/bundles/http.umd.js',
      '@angular/router': '/node_modules/@angular/router/bundles/router.umd.js',
      '@angular/forms': '/node_modules/@angular/forms/bundles/forms.umd.js',

      'rxjs':'/node_modules/rxjs',//New line
    },
     packages: {
      'TypeScriptFiles': {
        defaultExtension: 'js',
        meta: {
          './*.js': {
            loader: 'systemjs-angular-loader.js'
          }
        }
      },
      rxjs: {//New line
        defaultExtension: 'js'
      }
    }
  });
})(this);

Step 3 – Change Component

Change "templateUrl" value to relative path as follows.

import {Component} from "@angular/core"
@Component({
selector:'app-component',
templateUrl:'./app.component.html'
}
)
export class AppComponent{

}

Step 4 - Compile and test the output

Go to the browser.

As you can see, now the demo is working with a relative URL too.

Note:

It’s not compulsory to use SystemJs as Module Loader for your Angular project. You can even go with "requireJs" or something else too. In the case of other Module Loaders you have to either go with earlier "Lab 2" approach for specifying URL or have to check your new Module loader documentation for such support.

I recommend you not to go too in-depth about SystemJs right now and concentrate on Angular learning. You can learn "SystemJs" in detail some time later using some other learning resources.

Later in the series we will have one demo where we will make our project better by removing SystemJs and getting our work done with WebPack. As of now, simply continue with it.

Lab 4 – Interpolation

In this demo, we will explore an Angular feature called Interpolation.

As I said before, Angular Component is a combination of two things.

  1. Template – (also called as view) which represents the UI part of component.
  2. View class/component class – a custom class decorated with "Component" decorator. It encapsulates the UI data required and UI logic.

"Interpolation is a way to display dynamic data in component templates". It will be written using double-curly braces ({{...}}).

Let’s understand with demo.

Step 1 – Initialize Component Data

Open ‘app.component.ts’ file, create two variables in the AppComponent class and simply assign a dummy values to in the "Constructor".

import {Component} from "@angular/core"
@Component({
selector:'app-component',
templateUrl:'./app.component.html'
}
)
export class AppComponent{
    CompnayUrl:string;
    CompanyName:string;
    constructor(){
        this.CompanyName="Train IT";
        this.CompnayUrl="http://JustCompile.com";
    }
}

Step 2 – Display Component Data

Now, change the template file "app.component.html" as follows.

<h1>Welcome to Learn Angular in 10 days series - Day 3</h1>
Company Name: <b>{{CompanyName}}</b>
<br>
Click <a href="{{CompanyUrl}}">here</a> to visit.

You can see, two places where interpolation is used. One in between bold tags and second as a "href" value.

Step 4 - Compile and test the output

Go to browser.

Very simple but useful example.

Lab 5 – Property Binding

Property binding means, binding a variable in component class to a property of some HTML element in the template. Such properties are called "Input properties".

Are you confused? Let’s do a very quick demo.

Step 1 – Implement property binding in AppComponent template

Change the hyperlink in the "app.component.html" as follows.

<a [href]="CompanyUrl">here</a>

Have you noticed the difference? This time there is no interpolation plus "href" is wrapped between "[" and "]".

This is called "Property binding" – "CompanyUrl" variable of AppComponent class is bound to "href" property of "anchor (a)" element and "href" is termed as "input property" in this example.

Step 2 - Compile and test the output

You will get the exact same output like before. It proves that interpolation and property binding does the same thing. But the truth is, property binding is more than just displaying value. Let’s understand with the demo.

Step 3 – Change Compnent Class

Add a new variable called "IsChecked" of type Boolean in AppComponent class.

...
export class AppComponent{
    CompnayUrl:string;
    CompanyName:string;
    IsChecked:boolean;
    constructor(){
        this.CompanyName="Train IT";
        this.CompnayUrl="http://www.JustCompile.com";
        this.IsChecked=true;
    }
}

Step 4 - Change Template

Create a checkbox control in template and use "IsChecked" property with "checked" attribute of HTML element.

<h1>Welcome to Learn Angular in 10 days series - Day 3</h1>
Company Name: <b>{{CompanyName}}</b>
<br>
Is Active: <input type="checkbox" checked={{IsChecked}}>
<br>
Click <a href="{{CompnayUrl}}">here</a> to visit.

Step 5 - Compile and test the output

Check the output in the browser.

As you can see, Checkbox is checked.

Step 6 – Change IsChecked

In AppComponent constructor, change "IsChecked" to false.

...
constructor(){
        this.CompanyName="Train IT";
        this.CompnayUrl="http://www.JustCompile.com";
        this.IsChecked=false;
 }
...

Step 7 - Compile and test the output

Check the output in the browser.

Checkbox is still checked.

Step 8 – Implement property binding in template

...
Is Active: <input type="checkbox" [checked]="IsChecked">
...

Step 9 - Compile and test the output

Check the output in the browser.

Wow :) Checkbox is unchecked now.

Step 10 – Change IsChecked

In AppComponent constructor, change "IsChecked" to true.

...
constructor(){
        this.CompanyName="Train IT";
        this.CompnayUrl="http://www.JustCompile.com";
        this.IsChecked=true;
 }
...

Step 11 - Compile and test the output

Check the output in the browser.

Checkbox is backed to checked state now.

Interpolation vs Property binding

Interpolation call the "toString" function of variable and then set the value. So value will always be string where as in the case property binding datatype will be retained.

So, in simple terms – when variables are string type, interpolation is a good option but for other datatypes property binding is preferred.

For string values, interpolation is preferred because in interpolation concatenation is easier.

Check the bellow example

<p>{{FirstName}} – {{LastName}}</p>

It will simply display "FirstName" and "LastName" concatenated along with hyphen (-).

Example – When FirstName is "Sukesh" and LastName is "Marla" it will display following output.

Sukesh – Marla

Lab 6 – Working with Events in Angular

In this demo we will see Event Binding (also known as Output properties) in action.

Step 1 – Change Template

Add a simple button in the ‘app.component.html’.

<h1>Welcome to Learn Angular in 10 days series - Day 3</h1>
Company Name: <b>{{CompanyName}}</b>
<br>
Is Active: <input type="checkbox" [checked]="IsChecked">
<br>
Click <a href="{{CompnayUrl}}">here</a> to visit.
<br>
<input type="button" value="ChangeValue" (click)="UpdateValue()">

In the above HTML, the "input" tag has a special attribute called "click" written between "(" and ")". It is the "output property". It is a way to handle events in Angular application.

Step 2 – Define Event handler

Open ‘app.component.ts’. Inside AppComponent class create a new method "UpdateValue" as follows.

...
    IsChecked:boolean;
    constructor(){
        this.CompanyName="Train IT";
        this.CompnayUrl="http://www.JustCompile.com";
        this.IsChecked=false;
    }
    UpdateValue():void{
        this.CompanyName="Just Compile";
        this.CompnayUrl="http://www.sukesh-Marla.com";
        this.IsChecked=true;
    }
}

Step 3 –Compile and test the output

Open the browser. You will get to see following output.

When "ChangeValue" button is clicked, "UpadateValue" function in the component class got invoked. This is called event binding and "click" is the output property in the example.

After button click, the entire UI gets re-rendered with new values. It happens, because Angular have something called Change Detection. Change Detection is a mechanism which keeps the UI in sync with the data. Every time data get changed, UI get re-rendered. We will have more detailed discussion on Change Detection later in the series.

Lab 7 – Working with Complex objects

In the next lab, we will understand how to deal with Complex Objects in Angular.

Step 1 – Create Model

In Programming world Model represents the data. Let’s use the same terminology in our project. Create a new folder called "Models" in the "AppModule" folder.

Then create a new TypeScript file "Employee.ts" inside "Models" folder as follows.

export class Employee{
    FName:string;
    LName:string;
    Salary:number;
}

Step 2 – Use Model in Component class

It’s time to redefine AppComponent Class.

Remove all the existing code from AppComponent and then create a new global variable of type Employee and initialize it with dummy values. Here is the complete code.

import {Component} from "@angular/core"
import {Employee} from "../Models/Employee"
@Component({
selector:'app-component',
templateUrl:'./app.component.html'
}
)
export class AppComponent{
    emp:Employee;

    constructor(){
        this.emp=new Employee();
        this.emp.FName="Sukesh";
        this.emp.LName="Marla";
        this.emp.Salary=10000;
    }
}

Step 3 – Display Model data in Template

Finally let’s redefine our template file "app.component.html". It can be done easily with the help of interpolation. Here is the code.

<h1>Welcome to Learn Angular in 10 days series - Day 3</h1>
Employee Name: {{emp.FName}} {{emp.LName}}
<br>
Salary: {{emp.Salary}}

Step 3 –Compile and test the output

Open the browser. You will get to see following output.

Simple example.

Understand the Project

As I Promised in Day 1, we will create one simple Angular Project at the end of the day. It’s time to start with it.

We will create our project step by step. Sometimes we will create something which is not good from a best practice point of view. But that’s fine, we will do it, discuss the issues in it and then get into the best practice.

When it comes to learning, "We should learn both best and bad practices of a technology".

Let’s start with the understanding what we are going to develop.

Above one is Employee UI. We will have some similar UI for Customer, Product, Customer and Supplier.

Let’s start developing it step by step.

Lab 8 – Working with Collections

Let’s start with displaying multiple Employees in a single UI.

In order to do it we have to use one very interesting feature of Angular that is "Attribute Directives".

Step 1 – Prepare the Component Class

Open "app.component.ts" file. Remove all the existing code from AppComponent and then create a new global variable of type Array<Employee> and initialize it with dummy values. Here is the complete code.

import {Component} from "@angular/core"
import {Employee} from "../Models/Employee"
@Component({
selector:'app-component',
templateUrl:'./app.component.html'
}
)
export class AppComponent{
    Employees:Array<Employee>;

    constructor(){
        this.Employees =new Array<Employee>();
        
        let e1=new Employee();;
        e1.FName="Sukesh";
        e1.LName="Marla";
        e1.Salary=10000;
        this.Employees.push(e1);

        let e2=new Employee();;
        e2.FName="Gabbar";
        e2.LName="Singh";
        e2.Salary=20000;
        this.Employees.push(e2);
        
        let e3=new Employee();;
        e3.FName="Dragon";
        e3.LName="Hunter";
        e3.Salary=30000;
        this.Employees.push(e3);
    }
}

Step 2 – Redefine the Template.

Now for displaying multiple Employees we have to use HTML "table" tag. Challenge will be, creating "tr" tag because it has to be created dynamically. For every single Employee in the list one "tr" should be created.

As a best practice every DOM manipulation in Angular project must happen without accessing DOM directly in component class. We will explore various ways to achieve it throughout the series.

For our current requirement, we will use an Angular Directive called "*ngFor".

"Directives change the default behavior of HTML elements when attached."

For instance "*ngFor" directive repeats the host element based on expression provided.

Open "app.component.html", remove existing contents and put following contents in it.

<h1>Employee</h1>
<table border="1" >
    <tr>
        <th>Emp Name</th>
        <th>Salary </th>
    </tr>
    <tr *ngFor="let emp of Employees">
        <td>{{emp.FName}} {{emp.LName}}</td>
        <td>{{emp.Salary}}</td>
    </tr>
</table>

Check the second "tr" in the above table. You will notice "*ngFor" used with it.

Let’s examine the expression provided in this example, it is "let emp of Employees".

Angular iterate through "Employees", which is an array of "Employee" and then create one row ("tr") for each item in the list. "emp" will be set to individual Employee item in the current iteration.

Step 3 –Compile and test the output

Open the browser. You will get to see following output.

Later in the series we will display a real time data instead of hard coded one.

Lab 9 - Data Entry Screen

In this lab we will concentrate on Data Entry section of our project.

Step 1 – Create Data Entry section

Open ‘app.component.html’ and append the following HTML to it.

<br>
<div>
    FName: <input type="text"><br>
    LName: <input type="text"><br>
    Salary: <input type="text"><br>
    <input type="button" value="Save" (click)="SaveEmployee()">
</div>

Note: Please make sure that you have appended above HTML to existing HTML. (Don’t replace it)

Step 2 – Define SaveEmployee

Open app.component.ts and define SaveEmployee method as follows.

SaveEmployee():void{
   let e1=new Employee();
    e1.FName="F1";
    e1.LName="L1";
    e1.Salary=40000;
    this.Employees.push(e1);
}

Step 3 –Compile and test the output

Open the browser. You will get to see following output.

As you can see, we just have to add a new item to the collection and UI automatically got re-rendered. Its because of "Change Detection".

We have a very detailed lab on input controls where we will talk about various ways of getting input values in component class. Current example is inserting hard coded employees, let’s stick to that.

Lab 10 – Conditional Rendering

Current UI have both Employee list and data entry screen visible at the same time but according to our requirement only one thing should be visible at a time.

In this demo we will implement conditional rendering in our project.

Let’s start implementing the same.

Plan the Logic

To achieve our current requirement (conditional rendering) we will perform following steps.

In component class we will do following changes.

  • Create a Boolean variable "IsAddNew" which will represent the current condition in the UI.
  • Create "ShowAddNew" function which will set "IsAddNew" to true.
  • Create "HideAddNew" function which will set "IsAddNew" to false
  • In the existing "SaveEmployee" function set "IsAddNew" to false

In the template side, we will use "hidden" attribute of HTML element combined with Property binding in Angular.

Let’s do in reality and understand it better.

Step 1 – Redesign the template

Let’s start with redesigning AppComponent template that is "app.component.html". We need two more buttons, "Add New" and "Cancel".

Here is the complete HTML.

<h1>Employee</h1>
<div [hidden]="IsAddNew">
    <input type="button" value="Add New" (click)="ShowAddNew()">
    <table border="1">
        <tr>
            <th>Emp Name</th>
            <th>Salary </th>
        </tr>
        <tr *ngFor="let emp of Employees">
            <td>{{emp.FName}} {{emp.LName}}</td>
            <td>{{emp.Salary}}</td>
        </tr>
    </table>
</div>
<div [hidden]="!IsAddNew">
    FName: <input type="text"><br>
    LName: <input type="text"><br>
    Salary: <input type="text"><br>
    <input type="button" value="Save" (click)="SaveEmployee()">
    <input type="button" value="Cancel" (click)="HideAddNew()">
</div>

You can notice that "IsAddNew" variable is bound to "hidden" attribute via property binding.

Don’t miss the "!" symbol used with "IsAddNew" in second div. It means "hidden" will be bound to reverse value of "IsAddNew". In simple words, Second "div" will get hidden/invisible when "IsAddNew" is not true. If "IsAddNew" is true it will be displayed.

Step 2 – Implement logic in Component class

Implement following changes in "app.component.ts" file.

...
…
export class AppComponent{
    Employees:Array<Employee>;
    IsAddNew:boolean;
    constructor(){
        this.IsAddNew=false;
        this.Employees =new Array<Employee>();
        ...
        ...
    }
    SaveEmployee():void{
        ...
        ...
        this.IsAddNew=false;
    }
    ShowAddNew():void{
        this.IsAddNew=true;
    }
    HideAddNew():void{
        this.IsAddNew=false;
    }
}

Step 3 –Compile and test the output

Open the browser. You will get to see following output.

Summary

Here we are done with our Day 3.

Currently our application is nothing but a big UI. We have one component and that’s it. Definitely we are not following Component oriented style. Next time we will break our application into multiple small, reusable, meaningful and composable web components.

In day 4, we will also learn how to create custom Input/output properties and how to deal with input controls in Angular. Til then happy coding and stay tuned.

I am in twitter, Facebook, linked in.

Want to know more about me.

www.sukesh-marla.com

www.justcompile.com

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marla Sukesh
Instructor / Trainer Train IT
India India
Learning is fun but teaching is awesome.

Code re-usability is my passion ,Teaching and learning is my hobby, Becoming an successful entrepreneur is my goal.

By profession I am a Corporate Trainer.
I do trainings on WCF, MVC, Business Intelligence, Design Patterns, HTML 5, jQuery, JSON and many more Microsoft and non-Micrsoft technologiees.

Find my profile here



My sites



@Twitter
@Facebook

You may also be interested in...

Comments and Discussions

 
PraiseNice tutorial Pin
Member 135096857-Nov-17 23:32
memberMember 135096857-Nov-17 23:32 
PraiseNice Article Pin
Member 1341935420-Sep-17 0:21
memberMember 1341935420-Sep-17 0:21 
QuestionMessage Closed Pin
19-Sep-17 23:13
memberMember 1341920819-Sep-17 23:13 
QuestionGood Article Pin
san2debug12-Sep-17 19:03
professionalsan2debug12-Sep-17 19:03 
QuestionLessons Completion Pin
Fouad A . Mehsen11-Sep-17 23:55
professionalFouad A . Mehsen11-Sep-17 23:55 
AnswerRe: Lessons Completion Pin
Marla Sukesh12-Sep-17 0:01
mvp Marla Sukesh12-Sep-17 0:01 
QuestionLearn Angular in 10 days??? Day 1 was almost a month ago and we're still in Day 3 Pin
Member 1242931224-Aug-17 19:32
memberMember 1242931224-Aug-17 19:32 
QuestionRe: Learn Angular in 10 days??? Day 1 was almost a month ago and we're still in Day 3 Pin
Member 124293121-Sep-17 11:31
memberMember 124293121-Sep-17 11:31 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun16-Aug-17 22:10
memberHumayun Kabir Mamun16-Aug-17 22:10 
GeneralRe: My vote of 5 Pin
Marla Sukesh17-Aug-17 23:59
mvp Marla Sukesh17-Aug-17 23:59 
QuestionExcellent article Pin
Hipolito Lopez14-Aug-17 5:37
memberHipolito Lopez14-Aug-17 5:37 
AnswerRe: Excellent article Pin
Marla Sukesh17-Aug-17 23:58
mvp Marla Sukesh17-Aug-17 23:58 
QuestionVery well done Pin
Member 976150111-Aug-17 6:39
memberMember 976150111-Aug-17 6:39 
AnswerRe: Very well done Pin
Marla Sukesh11-Aug-17 10:15
mvp Marla Sukesh11-Aug-17 10:15 
QuestionDay 3 - Lab 7 Pin
Member 1324083011-Aug-17 4:08
memberMember 1324083011-Aug-17 4:08 
AnswerRe: Day 3 - Lab 7 Pin
Marla Sukesh11-Aug-17 10:13
mvp Marla Sukesh11-Aug-17 10:13 
GeneralRe: Day 3 - Lab 7 Pin
Member 1324083013-Aug-17 22:48
memberMember 1324083013-Aug-17 22:48 
GeneralRe: Day 3 - Lab 7 Pin
Marla Sukesh19-Aug-17 5:57
mvp Marla Sukesh19-Aug-17 5:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171114.1 | Last Updated 25 Oct 2017
Article Copyright 2017 by Marla Sukesh
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid