Why haven't I been using Type Script?

by Anthony 24. May 2014 10:13

In this line of work things come and go.  I like the change, but sometimes it can be a pain in the rear (who remembers Silverlight RIA services?).  So I usually let things bake for a bit before I start working with them.  Recently we have been exploring LESS and TypeScript as a way to make our CSS and JavaScript more manageable in my group.  I think LESS is awesome, but I haven't done a deep dive into it as of yet.  However, TypeScript is what JavaScript has been missing in my opinion.  A while back I wrote the article Please stop pushing JavaScript down my throat several of the items mentioned in that article are addressed by TypeScript:

  • Polymorphism
  • Encapsulation
  • Interfaces
  • Inheritance

Is all expanded upon in TypeScript.  While it is true several of these concepts do exist in JavaScript they are a bit obfuscated.  Type script brings them to the forefront. For example Interfaces do not exist in JavaScript (you can say they can be achieved but they still don't exist.) Interfaces are a simple matter in TypeScript with the  "implements" keyword classA implements InterfaceA.

Polymorphism does exist in JavaScript, I would say otherwise, but again it's implementation is not {classX implements classY}.  TypeScript handles this exactly nicely with the "extends" keyword  {classX extends classY}.

I could continue to site language references but I prefer to show rather than pontificate. So to start learning type script I set out to recreate the fractal Koch's Snowflake.  The project is using MVC, but I also created a plain vanilla HTML page that performs the same functionality as the MVC View. So the first core item of a 2D vector graphics is the point:

In java script it could be implemented like this:

var Point = (function () {
	function Point(x, y) {
		this.x = x;
		this.y = y;
	}
	Point.prototype.draw = function (htmlcanvas) {
		var drawcontext = htmlcanvas.getContext("2d");
		drawcontext.strokeStyle = lineColor;
		drawcontext.fillRect(this.x, this.y, 10, 10);

		drawcontext.stroke();
	};
	return Point;
})();

But with TypeScript we have much more type control:

interface IPoint {
	x: number;
	y: number;
	draw(htmlcanvas: HTMLCanvasElement);
}

class Point implements IPoint {
	constructor(public x, public y) {
	}
	draw(htmlcanvas: HTMLCanvasElement) {
		var drawcontext:CanvasRenderingContext2D = htmlcanvas.getContext("2d");
		drawcontext.strokeStyle = lineColor;
		drawcontext.fillRect(this.x, this.y, 10, 10);
	   
		drawcontext.stroke();
	}
}

Two points to make:

  1. I didn't save a ton of typing (in some cases it is more)
  2. I did however increase the maintainability of this code.

All of my variables are typed and I created a loosely coupled Point object.  If I need to create a special point that does something else down the line I can.  An example of this is Line to Curve.  Now this is a pretty lame example, because it isn't really something you would do in the real world.  BUT THIS ISN'T THE REAL WORLD THIS IS MY WORLD KNEEL BEFORE ZOD!!!  Ok Sorry about that back to our program already in progress.  So lets take a look at the implementation of line and curve:

interface ILine {
	start: IPoint;
	end: IPoint;
	draw(htmlcanvas: HTMLCanvasElement);
}

class Line implements ILine {
	constructor(public start: Point, public end: Point) { }
	draw(htmlcanvas: HTMLCanvasElement) {
		var drawcontext: CanvasRenderingContext2D = htmlcanvas.getContext("2d");
		this.drawByContext(drawcontext);
		drawcontext.stroke();
	}

	drawByContext(drawcontext: CanvasRenderingContext2D) {
		drawcontext.moveTo(this.start.x, this.start.y);
		drawcontext.lineTo(this.end.x, this.end.y);

		drawcontext.strokeStyle = lineColor;
		
	}

	drawpoints(htmlcanvas: HTMLCanvasElement) {
		this.start.draw(htmlcanvas);
		this.end.draw(htmlcanvas);
	}
}

class Curve extends Line {
	draw(htmlcanvas: HTMLCanvasElement) {
		var drawcontext: CanvasRenderingContext2D = htmlcanvas.getContext("2d");
		drawcontext.beginPath();  
		drawcontext.moveTo(this.start.x+10, this.start.y+10);
		drawcontext.arcTo(this.start.x+100, this.start.y+10, this.end.x, this.end.y+400,60);

		drawcontext.strokeStyle = lineColor;
		drawcontext.stroke();
	}
}

Pretty straight forward.  Now lets look at the JavaScript version:

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Line = (function () {
	function Line(start, end) {
		this.start = start;
		this.end = end;
	}
	Line.prototype.draw = function (htmlcanvas) {
		var drawcontext = htmlcanvas.getContext("2d");
		this.drawByContext(drawcontext);
		drawcontext.stroke();
	};

	Line.prototype.drawByContext = function (drawcontext) {
		drawcontext.moveTo(this.start.x, this.start.y);
		drawcontext.lineTo(this.end.x, this.end.y);

		drawcontext.strokeStyle = lineColor;
	};

	Line.prototype.drawpoints = function (htmlcanvas) {
		this.start.draw(htmlcanvas);
		this.end.draw(htmlcanvas);
	};
	return Line;
})();

var Curve = (function (_super) {
	__extends(Curve, _super);
	function Curve() {
		_super.apply(this, arguments);
	}
	Curve.prototype.draw = function (htmlcanvas) {
		var drawcontext = htmlcanvas.getContext("2d");
		drawcontext.beginPath();
		drawcontext.moveTo(this.start.x + 10, this.start.y + 10);
		drawcontext.arcTo(this.start.x + 100, this.start.y + 10, this.end.x, this.end.y + 400, 60);

		drawcontext.strokeStyle = lineColor;
		drawcontext.stroke();
	};
	return Curve;
})(Line);

Again not a ton of typing saved, but the TypeScript method is much easier to follow.

Finally what I wanted to accomplish was a fractal called Koch's Snowflake with the canvas object.  Putting Point, and Line together I was able to accomplish this fairly easily with some internet help on the algorithm.  Thank you Nathan Bronecke for your Java Applet code.  The result looks like this and was created completely with TypeScript.

 

You can download the full project here: KochSnowflake GitHub

You can read more about TypeScript here

Tags: , , , , ,

Please stop pushing JavaScript down my throat.

by Admin 2. September 2012 09:45

I am primarily a web applications software engineer.  This has been my career path for last 12 of the 17 years I have been working.  That being said, I never overlook the merits of client applications in certain situations (graphically intense, constant connection or the need to integrate with other applications).  I have always found that any code that you have complete control over should keep in mind the following paradigms:

Standard OO principals:

  • Polymorphism: IAnimal -> Mammal -> Dog -> Basset Hound
  • Inheritance: Dog::Eats(){ return “Dog Food”}: Dog overrides Eat From Mammal where it is overridden from IAnimal.
  • Interfacing: IAnimal can be passed around regardless of the type of the inheriting animal.
  • Encapsulation: There is no reason to expose everything to everyone. Something’s should be exposed to the sub classes and (like in life) some things should just be private.

Other important constructs:

  • “Compiled” vs. “Interpreted”: This construct allows programming languages to be compiled down to a lower level language making them run as fast as possible on the target platform.
  • Type Safety (Strongly Typed): Increases performance and reduces runtime errors because the compiler catches issues and optimizes performance for the particular types. NOTE: I incorrectly stated performance is increased with type safety.  This is incorrect, it is a compile time construct and will not increase performance.

Now web applications by default are multiplatform targeted.  They should react the same way on one IE 9 running on Windows as on Chrome running on Mac (they don’t, but bear with me I am getting to the point).  This is where JavaScript excels. Since the actually code is pushed down to the compliant browsers the implementation of that code is left to the browser with guidance of ECMA standards.

I love JavaScript, I love JQuery, I think it is awesome.  But stop trying to make me run it on my servers or on my desktop FOR EVERYTHING.  .Net, Java, C++ all work great as compiled server side languages. Objective C and the previous also work awesome as compiled rich client applications (as long as you know the target system).  So why on earth would I want a language that breaks 3 of my core tenants of programming when I know the target system?

Yes for those that don’t know it let me reiterate JavaScript is not encapsulated, there is no way to mark a method as private. It is certainly not complied (sorry Closure you are an optimizer and calling yourself a compiler is an insult to anyone that has ever built a real compiler).  Finally it isn’t type safe.   I can do the following:

var something = 1; //something is an int
something =  "Ted"; //something is an string
something = function () { return "ted"; } //something is a method pointer
something = 1.34343; //something is a float
something = [1,2,3,4,5]; //something is an array

WOW, something can do anything, and I guarantee the above will run with no issues.  Yes I can do something similar with dynamic types, but there is a time and a place for dynamicity and all the time is not it.  

So when I read about Node.JS used in place of IIS/Apache and JSDB/TaffyDB used in place of Oracle/Sql Server or MySql I shudder a bit.  The only constant theme for why I should do this: is the same language is used client side and server side.  No performance gains (BTW scalability and performance are two completely different dynamics) and no additional features.  Sorry I just can't jump on the bandwagon.

I may sound like a bitter old programmer when I hear the terms "Bandwidth is cheap" or "Processors can handle a lot more these days" or "Just add some more memory/servers".  But why write less efficient code in the the first place.  Always weigh the benefits of performance vs. maintainability.  One should not completely override the other.

Learn PL/TSQL, learn an OO language, learn a server side scripting language(Perl, Python, Ruby), learn JavaScript and learn HTML.  But more importantly, learn when to use each and keep it where it belongs.  To quote my Grandfather, "Just because you can do something doesn’t mean you should."

Tags: , , ,

JavaScript | jquery | NodeJS | OOD | SQL Server

JQuery Tooltips with MVC3 and CSS 3.0 (Part 2)

by Admin 25. March 2012 02:56

So in my previous post I explained all of the steps required to create a simple but effective CSS 3 JQuery tooltip implementation.  This was a good start, I had all I needed to fulfill my requirement of a consistent tooltip in my application.  But I needed it to be a little easier to use throughout the application.  A custom Html Helper Extension to the rescue. Creating an HTML Helper is a pretty straight forward task this one, however, needed a bit of special sauce to make it work the way I wanted.

First I wanted to make sure I could bind it to my model, in case in the future I wanted to default it to the [Display] property on the model.  Second I wanted to be able to use the @<text></text> syntax for the contents of the tooltip.  It made sense to work backwards I wanted the control to work like this: 

@Html.InfoTooltipFor(model => model.ToolTipTitle,
	@<text>
	<h4>@Model.ToolTipTitle</h4>
	<ul>
   		<li>
			<b>Scott Guthrie</b> – 
			<a href="http://weblogs.asp.net/scottgu/">
				ScottGu's Blog
			</a> One of the best resources for all things Microsoft Web
                </li>
		<li>
			<b>Scott Hanselman</b> – 
				<a href="http://www.hanselman.com/blog/">
					Scott Hanselman's Computer Zen
				</a> Another great resource very current and very informative.
		</li>
		<li>
			<b>ASP.NET</b> – 
				<a href="http://www.asp.net/mvc">
					ASP.NET MVC
				</a> The mother of all things ASP.NET MVC
		</li>
     </ul>
</text>)

 

Seemed simple enough so at first I create the Helper as follows:

 

public static MvcHtmlString InfoTooltipFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression, 
    string tooltip)
{
...
}

 

Nope that won't work... 

 

And once I thought about it makes sense that a string won't work.  It isn't anything remotely like a string it contains functions, delegates and properties. I know this type of implementation exists I have seen it in other controls.  So how is it done?  After an exhaustive google search I found this article by Phil Haack.  It was close to what I needed, so, after some trial and error I came up with this:

public static MvcHtmlString InfoTooltipFor<TModel, TValue>(this HtmlHelper<TModel> html, 
		Expression<Func<TModel, TValue>> expression, 
		Func<object, HelperResult> tooltip)
{
	//Get the Model metadata
	ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
	string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
	string tooltipId = metadata.PropertyName ? ? htmlFieldName.Split('.').Last();

	if (String.IsNullOrEmpty(tooltipId))
	{
		return MvcHtmlString.Empty;
	}
	//creates the span tag for the image
	TagBuilder spanTag = new TagBuilder("span");
	spanTag.MergeAttribute("class", "tooltipItem");
	spanTag.MergeAttribute("id", tooltipId);
	spanTag.MergeAttribute("data-tooltip", "tt" + tooltipId);

	TagBuilder imgTag = new TagBuilder("img");
	imgTag.MergeAttributes(new RouteValueDictionary(
		new
		{
			@class = "infoimage",
			src = UrlHelper.GenerateContentUrl("~/Content/info.png", html.ViewContext.HttpContext),
			alt = "info"
		}
		));
	spanTag.InnerHtml = imgTag.ToString(TagRenderMode.Normal);

	//creates the tooltip contents
	TagBuilder tooltipTag = new TagBuilder("div");
	tooltipTag.MergeAttribute("class", "hidden");
	tooltipTag.MergeAttribute("id", "tt" + tooltipId);
	tooltipTag.MergeAttribute("name", "tt" + tooltipId);
	tooltipTag.MergeAttribute("data-tooltip", "tt" + tooltipId);
	tooltipTag.InnerHtml = tooltip(null).ToString();

	return MvcHtmlString.Create(spanTag.ToString(TagRenderMode.Normal) + tooltipTag.ToString(TagRenderMode.Normal));
}

The key is Func<object, HelperResult> this allows templated items to be passed into helper method.  This was exactly what I needed and poof like magic it worked.  MVC is awesome, creating a control like that in standard ASP.NET would have been a major pain. 

The entire solution is in the attached zip...

EasyTooltips.zip (2.46 mb)

Tags: , , , ,

AJAX | css | jquery | MVC3

JQuery Tooltips with MVC3 and CSS 3.0 (Part 1)

by Admin 24. March 2012 17:58

I am a developer and no graphic artist by any strech of the imagination, but I am often thrown into that roll.   Seriously, how many small projects have the budget for a Graphic artist and a developer, not to mention the fact management rarely knows the difference.  

Regardless, I needed to create some tooltips to be used throughout an internal web application I was creating.  There are about 30 trillion jquery tooltip plugins on the internet, and most of them are good, I felt a little plugin overloaded, so I decide to roll my own.  The CSS 3.0 implementation was pretty simple (only 2 classes):

.tooltipwindow
{
   border-bottom-left-radius: 15px;
   border-top-left-radius: 0px;
   border-bottom-right-radius: 15px;
   border-top-right-radius: 15px;
   border: 1px solid #0099FF;
   position:absolute;
   padding:5px;
   background-color:#fff;
   z-index: 20000;
   box-shadow: 3px 3px 2px #808080;
   font-size:smaller;
}
 
.hidden
{
   display:none;
}

Only a few CSS 3.0 items to mention box-shadow (for the drop shadow effect) and border-radius (for the rounded corners on all but the top right) other than that pretty standard.  The JavaScript was pretty simple as well:

A few global variables:

//A 1/2 Second fade-in/out
var toolTipHideDelay = 500;
//A 1/4 second before the tooltip begins to fade
var toolTipMouseoutDelay = 250;
//The timer to determine when the fade should start
var toolTipHideTimer = null;
//The variable containing the tool tip contents
var tooltipWindow = null;
//The current Id of the tool tip
var tooltipCurrentId = null;

Then the actual tool event handlers:

//standard doc ready event
$(document).ready(function () {
 
    initializeTooltips();
})
 
function initializeTooltips() {
    //there is only one window for all tooltips on the page.
    tooltipWindow = $("#tooltipWindow");
    //all tooltips implement the following class
    var tooltipItem = $(".tooltipItem");
 
    //tooltip mouse events (not using hover because I want the tooltip to follow the cursor
    tooltipItem.mousemove(function (e) {
        //check to see if the tooltip is already opened
        if (toolTipHideTimer) {
            //clear the timeout since the user is hovering over the item again
            clearTimeout(toolTipHideTimer);
            //retrieve the tooltip data item from the current element
            if (tooltipCurrentId != $(this).data("tooltip")) {
                setToolTipPosition(this, e);
                //set the tooltip inner content
                tooltipWindow.html($("#" + $(this).data("tooltip")).html());
            }
        } else {
            //show the tooltip
            setToolTipPosition(this, e);
            //the tooltip is hidden do fade it in
            tooltipWindow.fadeIn(toolTipHideDelay);
            //set the tooltip inner content
            tooltipWindow.html($("#" + $(this).data("tooltip")).html());
        }
    });
    tooltipItem.mouseout(function (e) {
        //get ready to hide the tooltip
        toolTipHideTimer = setTimeout(function () {
            toolTipHideTimer = null;
            tooltipWindow.fadeOut();
        }, toolTipMouseoutDelay);
    });
 
    //tooltip window mouse events
    tooltipWindow.mouseover(function () {
        //keep the tooltip open if the user is over the tooltip window
        if (toolTipHideTimer) {
            clearTimeout(toolTipHideTimer);
        }
    });
    tooltipWindow.mouseout(function () {
        //get ready to hide the tooltip
        toolTipHideTimer = setTimeout(function () {
            toolTipHideTimer = null;
            tooltipWindow.fadeOut();
        }, toolTipMouseoutDelay);
    });
}

Then just a simple postion helper:

function setToolTipPosition(item, mouseevent) {
    var tooltipitem = $("#tooltipWindow");
    //set the tool tip to the current mouse position the 
    //2+ is so the user can still click the element under the 
    //tooltip
    tooltipitem.css({
        left: 2+(mouseevent.pageX) + "px",
        top: 2+(mouseevent.pageY) + "px"
    });
}

So now we have all of the client pieces we need, infact the following html will generate a tooltip:

<h3 style="display:inline-block">For More info hover over the icon</h3>
<span class="tooltipItem" data-tooltip="ttToolTipTitle" id="ToolTipTitle">
  <img alt="info" class="infoimage" src="/Content/info.png" />
</span>
 
<div class="hidden" data-tooltip="ttToolTipTitle" id="ttToolTipTitle" name="ttToolTipTitle">        
            <h4>Learn More from these sites</h4>
            <ul>
                <li><b>Scott Guthrie</b> – <a href="http://weblogs.asp.net/scottgu/">ScottGu's Blog</a> One of the best resources for all things Microsoft Web</li>
                <li><b>Scott Hanselman</b> – <a href="http://www.hanselman.com/blog/">Scott Hanselman's Computer Zen</a> Another great resource very current and very informative.</li>
                <li><b>ASP.NET</b> – <a href="http://www.asp.net/mvc">ASP.NET MVC</a> The mother of all things ASP.NET MVC</li>
            </ul>
        </div>
</div>
 
<div id="tooltipWindow" class="hidden tooltipwindow">
</div>

 

That looks like this:

 

So we are good to go, I just didnt want to have to copy all of this HTML for every tooltip I created in the system.  In Part 2 I will talk about how to integrate this with an MVC Html Helper.

 

Tags: , , ,

css | jquery

Calendar

<<  August 2014  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

View posts in large calendar

Page List

RecentComments

None