I came across the following progress indicator for jquery and wanted to try to recreate it as an angular component.
<ol class="ProgressBar">
<li #lis class="ProgressBar-step" *ngFor="let step of steps; let i = index">
<svg class="ProgressBar-icon"><use attr.href="{{svgUrl}}"/></svg>
<span class="ProgressBar-stepLabel">{{step}}</span>
</li>
</ol>
The only modifications done to the HTML were adding a template variable #lis and iterating on the steps to be displayed.
xlink:href has been deprecated so it was replaced with attr.href and the svg was saved in a file and the path to the file is passed to the component. Styling is pretty much identical.
import { Component, OnInit } from '@angular/core';
import { ElementRef, QueryList, ViewChildren, Renderer2} from '@angular/core';
import { Input } from '@angular/core';
@Component({
selector: 'app-progress-indicator',
templateUrl: './progress-indicator.component.html',
styleUrls: ['./progress-indicator.component.scss'],
})
export class ProgressIndicatorComponent {
@Input() public steps: string[];
@Input() public svgUrl:string;
@ViewChildren('lis') lis: QueryList<ElementRef>;
private elems: ElementRef<any>[];
constructor(private renderer: Renderer2) {
}
advance() {
this.elems = this.lis.toArray();
var count = this.lis.filter(x => x.nativeElement.classList.contains('is-current')).length;
if (count > 0) {
let index = 0;
for (let i = 0; i < this.elems.length; i++) {
if (this.elems[i].nativeElement.classList.contains('is-current')) {
index = i;
break;
}
}
if (index < this.elems.length) {
if(index < this.elems.length-1){ // if last one done remove current
this.renderer.removeClass(this.elems[index].nativeElement, "is-current");
}
this.renderer.addClass(this.elems[index].nativeElement, "is-complete");
}
if (index +1 < this.elems.length) {
this.renderer.addClass(this.elems[++index].nativeElement, "is-current");
}
} else {
this.renderer.addClass(this.lis.first.nativeElement, "is-current");
}
}
previous(){
this.elems = this.lis.toArray();
var count = this.lis.filter(x => x.nativeElement.classList.contains('is-current')).length;
if (count > 0) {
let index = 0;
for (let i = 0; i < this.elems.length; i++) {
if (this.elems[i].nativeElement.classList.contains('is-current')) {
index = i;
break;
}
}
if (index >= 0) {
this.renderer.removeClass(this.elems[index].nativeElement, "is-current");
this.renderer.removeClass(this.elems[index].nativeElement, "is-complete");
}
if(index > 0){
this.renderer.addClass(this.elems[--index].nativeElement, "is-current");
this.renderer.removeClass(this.elems[index].nativeElement, "is-complete")
}
}
}
}
The component uses @ViewChildren to access the li tags and Renderer2 to do safe modifications to the classes of each element.
Usage is as above steps should be an array of strings.
public steps = ["Test","Review","Result","Mistakes"];
Note that QueryList is not accessible by index nor one could iterate on it for ES5 so toarray() was used to get things done. ES6 makes it possible to iterate directly.
At the time of writing the Stack is running on Ubuntu 14.04 which can be downloaded from here. Since it is 64Bit make sure that Visualization is enabled in the bios settings.
Import the VM in VMware Player or Virtual box, make sure that the network settings are configured correctly so that the VM gets an IP accessible from the host machine. I personally configured it to Bridged Adapter for this exercise and have a habit of Regenerating the MAC Address.
If the VM does not get assigned an IP the configuration is wrong and I wouldn’t bother trying to fix it from inside the VM (you could) but I rather fix it from the hyper-visor settings because the stack is pre-configured to work.
Login and change password
Visit the IP in the browser to check if it is working in my case http://192.168.101.12
Enabling Laravel
Bitnami LAMP Stack comes with several pre-configured frameworks of which all are disabled by default. One must enable the framework that is required. ( I am nto sure if you can enable more than one at the same time)
Steps:
cd /opt/bitnami/apache2/conf/bitnami
sudo vi bitnami-apps-prefix.conf
Remove the hash from laravel’s line and save and close :wq
Restart Apache
sudo /opt/bitnami/ctlscript.sh restart apache
The location where Laravel apps Live is
/opt/bitnami/frameworks/laravel/app/http
Browser URL
http://192.168.101.12/laravel/ where 192.168.101.12 is your VM’s IP
Configuring FTP
Enabling FTP for easy editing/upload of files ( Note this is a development machine for experimentation so I will not go on explaining issues with FTP and security, but you should consider reading about the risks. )
sudo vi /etc/vsftpd.conf
go to the bottom of the file and change
listen_address=127.0.0.1
to
listen_address=0.0.0.0
:wq
Allow connections to port 21 (FTP port)
sudo ufw allow 21
Restart FTP
sudo service vsftpd restart
Change bitnamiftp password
sudo passwd bitnamiftp
Configure Filezilla
Connected
Now you may play around with Laravel through FTP 🙂
Let external connections to MySQL
1)
cd /opt/bitnami/mysql
sudo vi my.cnf
Comment out
bind-address = 127.0.0.1
by putting a # infront of it and Esc :wq
2)
mysql -u root -p
grant all privileges on *.* to 'root'@'%' identified by 'password' with grant option
Being on the saga to master AngularJS I decided to post about a basic application with a module and controller that returns static data to the view. The view and controller are married by routing. This post will not go in detail on how things work.
line 2 defines data-ng-app=”app” which is an attribute Every angular application should have (could live in other elements)
Line 8-11 are the JavaScript inclusion for the application (in a real website one would minify and merge the files together for faster loading)
Line 14 is where the view will be loaded <div data-ng-view></div>
AngularJS is modular in such a way that one could separate functionality but one or more modules can be injected into another module for richer functionality.
Every module may have a configuration and this is the first thing that will execute from that module for initialization. In this case the main module has routing initialized.
$routeProvider is where routing is setup.
in a nut shell the above is configuring that when visiting root ‘/’ use controller postsController with vm alias and use posts.html as a view template else redirect to root.
Controllers can be written in different ways but the most elegant (opinionated) is Register/Inject/Function
Register the controller with a function name
Inject parameters
Function is the controller’s logic. The variable vm stands for ViewModel because that’s exactly what it represents. and Some JSON data is set to a property in that view model.
This is the view template that will be loaded instead of <div data-ng-view></div>
data-ng-repeat means repeat this element for as much items in the list
The vm here is the alias that was defined in the routing and has nothing to do with the controller vm variable ( but for logical sense it is the same )
{{}} mean execute the expression in between which in this case are the Name and Country
As the title indicate, this post is about installing IIS and Configuring ThinkTecture v2 up and running.
Search and run app.wiz.cpl
click “Turn windows features on or off” (1)
Tick “IIS Management Console” (2)
Tick ASP.NET 4.5 (3)
It is of utmost importance that ASP.NET 4.5 is ticked else when one would attempt to navigate to thinktecture v2 the following HTTP Error 500.19 will pop up.
Wait for features to be found and installed.
click close
Navigate to Localhost
IIS is up and running. Next is Downloading ThinkTecture V2 configuring IIS to serve ThinkTecture V2
Create new Project name it and select “ASP.NET Web application”
Set Authentication to “Individual User Accounts” and Click Ok
Build and run your project and copy the local URL go to Facebook Development in your browser where you left off
Paste the url in “Site URL” and “Mobile site URL” in this case localhost:61617 and click next
Refresh the page click Show button near App Secret
Enter your Facebook Password
Go to visual studio
Navigate in solution explorer to App_start/start.auth.cs
Scroll down Facebook boilerplate authentication code. Paste App Id and App Secret and uncomment the three lines
Rebuild the Project and run
Once it opens in the browser click Login
On the left of the page there should be a Facebook button click it
Click okay to authorize
Enter E-mail address to associate with that Facebook account on your application
The e-mail will show every time the user is logged in.
That is how to authenticate a user using Facebook as an Identity Provider. Out of the box.
What’s else can we do with Facebook?
There a lot of things one can do with Facebook by using Facebook SDK the user can authorize your Web Site to access several Scopes. At the least one could skip the last two steps by requesting access to the e-mail and use that programmatically without the user having to type it.
The following is how to incorporate Facebook SDK in your project.
HTTP Handlers
They are used to process individual endpoints.
Only one handler per request is used
Can be both asynchronous or synchronous
Earliest possible point where you have access to requests
HTTPHandlers are extension based. This means that for every extension .aspx .html etc there is a handler (some share handler).
The example used here is very simple and does nothing special except for displaying some static text. The reason is that ideally before attempting to do something elaborate one should check if it works by doing something simple especially while learning.
The examples here were created in ASP.MVC5 applications. The extension that is used is .kk
SynchronousHTTP Handler
The Solution name is HTTP_Handler
Step 1:
Ignore routing for .kk extension in App_Start/RouteConfig.cs (The reason is that we do not want MVC to try to interpret this file)
routes.IgnoreRoute("{file}.kk");
Step 2:
We create the class that will be our handler at the top level since this is an example and name it CustomHandler.cs
This can be achieved by inheriting IHttpHandler or by using IHttpHandlerFactory (The example uses IHttpHandler)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace HTTP_Handler
{
public class CustomHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
HttpRequest Request = context.Request;
HttpResponse Response = context.Response;
Response.Write("test");
}
public bool IsReusable
{
get { return true; }
}
}
}
Step 3:
We configure the application to use the handler (Integrated mode).
add hello.kk to the link and load it should print test on screen.
Asynchronous HTTP Handler
The Solution name is HTTP_Async_Handler
Step 1:
Ignore routing for .kk extension in App_Start/RouteConfig.cs (The reason is that we do not want MVC to try to interpret this file)
routes.IgnoreRoute("{file}.kk");
Step 2:
We create the class that will be our handler at the top level since this is an example and name it CustomHandler.cs
This can be achieved by inheriting IHttpAsyncHandler
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace HTTP_Async_Handler
{
public class CustomHandler:IHttpAsyncHandler
{
// Long Process
private static void generateNumbers(HttpContext context)
{
string s = "";
for (int i = 0; i < 1000; i++)
{
s = s + ' ' + i.ToString();
}
context.Response.Write(s);
}
public static Action<HttpContext> _Handle = generateNumbers;
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
context.Response.Write("BeginProcessRequest Executed");
return _Handle.BeginInvoke(context,cb,extraData);
}
public void EndProcessRequest(IAsyncResult result)
{
// Clean up code here
}
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("ProcessRequest Executed Will not execute");
}
}
}
Step 3:
We configure the application to use the handler (Integrated mode).