Javascript - weak on getting week

by DotNetNerd 23. December 2009 08:42

Well this is one of those posts that start out being as a reminder for myself, since I had to do a script that I don't want to waste my time having to write again later on. Basically I ran into a customer who wanted week numbers added to a calendar. This seemed basic enough, but apparently getting a weeknumber is not a native thing in javascript.

First I picked up a script to add a getWeek method to the Date prototype, and I was a happy man. Sadly not customer not quite as much. It turns out that we do not follow the ISO 8601 standard for defining weeknumbers here in Denmark. According to my projectmanager the rule of thumb is that the first thursday always falls in week 1. This made me add a little extention so I now have a getIsoWeek and a getWeek method on my Date objects and this is how it was done.

/**
* Get the ISO 8601 week date week number
*/
Date.prototype.getIsoWeek = function() {
    // Create a copy of this date object 
    var target = new Date(this.valueOf());

    // ISO week date weeks start on monday 
    // so correct the day number 
    var dayNr = (this.getDay() + 6) % 7;

    // Set the target to the thursday of this week so the 
    // target date is in the right year 
    target.setDate(target.getDate() - dayNr + 3);

    // ISO 8601 states that week 1 is the week 
    // with january 4th in it 
    var jan4 = new Date(target.getFullYear(), 0, 4);

    // Number of days between target date and january 4th 
    var dayDiff = (target - jan4) / 86400000;

    // Calculate week number: Week 1 (january 4th) plus the  
    // number of weeks between target date and january 4th  
    var weekNr = 1 + Math.ceil(dayDiff / 7);

    return weekNr;
}

/**
* Get danish weeknumber.
* According to danish weeknumbers the first thursday always falls in week 1
*/
Date.prototype.getWeek = function() {
    var weekNr = this.getIsoWeek();

    var firstThursday = new Date(this.getFullYear(), 0, 1)
    while (firstThursday.getDay() != 4) firstThursday.setDate(firstThursday.getDate() + 1);

    if (firstThursday.getIsoWeek() == 2) weekNr--;

    if (weekNr == 0) weekNr = 1;

    return weekNr;
}

Ajax Minifier - come and get your low hanging fruit

by DotNetNerd 21. December 2009 16:43

Not too long ago Microsoft released the Ajax Minifier, which can be downloaded from codeplex. It's basically just another javascript minifier, but the good thing about is it that the download includes both a commandline tool, an MS Build task and an assembly, so you can do your minification any way you like. Either way you wait to use it is very simple and it is explainted in the chm file which is included in the installation.

Today I finally got around to using it, for a HttpHandler that I wrote to serve some javascripts that I wanted to aggregate into one file and have them minified. It really took no time at all, and reduced my site from needing 13 files to 1 that was reduced in size by a little over 30%. All it required was about 10 lines of code in the HttpHandler (including handling caching). So basically what I am saying is that there is no excuse not to get this performance boost, since it is really low hanging fruit ripe for the plucking.

 

Flickr og billedwidgets

by DotNetNerd 29. December 2008 11:29

En af mine gamle lidenskaber der indimellem popper frem er at lege med billeder, og nu jeg har haft ferie gav det sig udslag i at jeg ville prøve at lave en billedvæg til mit site, hvor billederne skulle trækkes fra flickr. Jeg havde egentlig forventet lidt bøvl, men selve det at trække billeder kræver ikke andet end følgende.

Flickr flickr = new Flickr("apiKey", "sharedSecret");
PhotoSearchOptions options = new PhotoSearchOptions();
options.Tags = "Christian";
options.Extras |= PhotoSearchExtras.DateTaken | PhotoSearchExtras.OriginalFormat;
options.UserId = flickr.PeopleFindByEmail("dotnetnerd@yahoo.com").UserId;
options.TagMode = TagMode.AnyTag;
options.SortOrder = PhotoSearchSortOrder.DateTakenDesc;
options.PerPage = 6;
Photos photos = flickr.PhotosSearch(options);

Photos indeholder så en PhotoCollection som hver har urls til billederne i original, medium, lille og thumbnail størrelse.

Herfra manglede jeg så bare en eller anden smart måde at vise billederne på. Jeg faldt hurtigt over FancyBox, som er en JQuery plugin der også er rigtigt nem at bruge, og lader brugere trykke på en thumbnail og se hele billedet. Dagen efter poppede der tilfældigvis en blogpost ind omkring TinySlideShow, som lige som navnet antyder giver mulighed for at lave et slideshow. Det skulle naturligvis også prøves af, og da jeg i noget tid gerne have ville finde på noget nyt til hovedsiden på dotnetnerd.dk var det jo oplagt.

 

JQuery nu en del af .NET pakken!

by DotNetNerd 28. September 2008 20:29

Jeg er selv en af de mange der har forelsket mig i JQuery, da det er et fantastisk værktøj der gør livet meget lettere for webudviklere. Dagens gode nyhed som kan læses fra Scott Gu her og fra Hanselman her er at Microsoft fra nu af shipper JQuery sammen med .NET og der vil blive lavet kommentarer til javascript intellisence til det :)

JavaScript - fra skældsord til spændende mulighed

by DotNetNerd 26. June 2008 08:52

Ligesom for rigtigt mange andre udviklere har javascript altid været et skældsord for mig. Opgaver der på overfladen virker simple er altid overraskende besværlige fordi browserne opfører sig forskelligt, udviklingsmiljøerne har ikke haft god tool-support og det at manipulere DOM’en på en webside har altid krævet urimeligt meget kode.

Der er heldigvis sket en masse på den front det sidste stykke tid, hvor jeg tidligere har kigget på intellisence og debugging af javascript i VS2008 samt Microsofts ASP.NET Ajax framework. Nu jeg har ferie har jeg som opfølgning på dette givet mig til at lege lidt med nogle af de andre frameworks der findes, da det så småt er ved at være en lille jungle at finde rundt i. Heldigvis har det vist sig at være en jungle med mange forskellige blomster, og overraskende lidt ensartet vegetation – eller på almindelig dansk, de frameworks der er har en masse at tilbyde uden at der er en masse overlap i funktionalitet.

Jeg vil starte med lige kort at skrive lidt om javscript som sprog, da jeg har på fornemmelsen at der er mange der ligesom mig i lang tid aldrig rigtig fik taget mig tid til at finde ud af nogle af de grundlæggende ting omkring objekter og funktioner i javascript.

Lidt JavaScript basics, som du måske alligvel ikke ved

Ligesom mange andre har jeg i min karriere primært brugt javascript til simple ting, som validering og at vise alerts, popup vinduer osv. Jeg måtte derfor for lidt tid siden erkende at jeg egentlig vidste for lidt om hvordan sproget virkelig fungere, da min indlæring havde været meget drevet af tilfældighed ud fra hvad jeg lige havde haft af små problemer der skulle løses. Jeg brugte derfor lidt tid på at blive klogere og vil lige starte helt kort med nogle af de vigtigste ting jeg lærte dengang.
Som udvikler der er uddannet og hovedsageligt har arbejdet i et OO miljø, er javascript en underlig størrelse, da begreberne object og function forstås en del anderledes i javascript end i Java, C#, VB osv.

I OO sprog er en property på et object fast defineret i en klasse, og som kan tilgås via dot notation. I javascript er properties noget der tilknyttes dynamisk, og disse kan tilgås både via dot notation og via indexer syntaks. Det vil sige at i nedenstående kode vil de to nederste linier gøre præcis det samme. Den sidste måde at tilgå properties på dog giver mulighed for at bruge tegn der ellers er ugyldige i propertynavne som eksempelvis punktum og mellemrum.

var hund = new Object();
hund.Navn = "King";
hund['Navn'] = "King";

Det kan på overfladen virke smart at properties på den måde er dynamiske, men ”there is no such thing as a free lunch”. Problemet er selvfølgelig at en subtil stavefejl eller bare casingfejl vil bevirke at man tilknytter en ny property, og man derved ikke får sat værdien på den property man troede. Det er her prototyping kommer ind, da det giver os mulighed for at definere noget der minder om classes og properties samtidig med det giver mulighed for at bruge namespaces til at strukturere klasserne. Jeg vil dog vælge at springe let hen over det i denne omgang, da det er en større omgang at gå i dybden med og ikke hovedfokus for det jeg vil skrive om i det her indlæg.

Funktioner i javascript er som nævnt også meget anderledes i javscript, da funktioner er ”first class” koncepter. Det vil sige at disse opfattes som objekter og kan passes som argumenter til metoder og bruges som værdier på properties. Derfor vil de to nedenstående kodelinier betyde præcis det samme, da funktionen blot er et ”objekt” med et navn.

myFunc = function() {}
function myFunc {}

En anden vigtig forskel er brugen af this keywordet, der forstås anderledes end i andre sprog. I OO sprogene er this en reference en objektet hvorpå den kaldte metode findes, hvorimod det i javascript er en reference til det objekt der kalder funktionen. Man kan dog i javascript selv angive hvad this skal betyde ved at kalde en funktion igennem dennes .call eller .apply metode og passe en reference som første argument til det objekt man ønsker skal være this i den aktuelle kontekst.

var myCaller = new Object();
myFunc.call(myCaller);

JSON eller JavaScript Object Notation, er en anden måde at skabe objekter på i javascript, som er ved at vinde frem, da den kan være rarere at arbejde med i javascript, samtidig med det er et oplagt format til at serializere objekter i når de skal sendes imellem klienten og serveren og konverteres imellem javscript og dit OO language of choice. Jeg har skrevet om dette før men kort fortalt fungerer det ved at tuborg-klammer definerer et objekt, hårde klammer et array, kolon adskiller property navn og værdi, og elementer adskilles af komma.

var hunde = [
{Navn: ’King’, Fødselsdato:  new Date(2004,8,12)},
{Navn: ’Pluto’, Fødselsdato:  new Date(2006,6,10)}
 ];

JQuery – bliv gode venner med din DOM

Oprindeligt troede jeg egentlig bare at JQuery var en open source udgave af det scripting library der følger med til ASP.NET Ajax – en sammenligning jeg også har læst andre fremføre. Den sidste måned havde jeg imidlertid hørt nogle gode ting om det, så jeg ville lige kigge lidt nærmere på det. Efter at have læst og leget lidt med det, må jeg konkludere at det er meget lidt det har til fælles med ASP.NET Ajax, da det er nogle grundlæggende forskellige ting de to librarys søger at løse. ASP.NET Ajax er lavet med fokus på at give mulighed for at arbejde med et typesystem der minder mere om det der er i .NET, samtidig med at det understøtter udviklingen af Ajax Controls og Ajax Control Extenders. JQuery derimod har hovedfokus imod at det at arbejde med DOM’en på en html side, sådan at man på en præcis måde kan finde og modificere Dom elementer. Rigtigt nok er der overlap imellem ASP.NET Ajax og JQuery, da begge eksempelvis indeholder wrappere til at lave kald til webservices – men hovedfokus i de to er helt forskelligt.

JQuerys udgangspunkt er som navnet antyder at det giver mulighed for at ”query” elementer på en webside. Dette gøres meget naturligt igennem selectors ligesom man kender dem fra CSS. JQuery giver mulighed for at anvende et bredt udsnit af disse – og herunder flere end dem der reelt er standard i CSS i alle browsere i dag. Et helt basalt eksempel kunne være:

$(document).ready(function() {
$("div:odd").html("Woot"); 
});

Eksemplet viser et par forskellige ting som JQuery gør muligt. Den første linie kode viser brugen af et event som JQuery stiller til rådighed der bliver affyret når sidens elementer er hentet, men inden eksterne elementer som f.eks. billeder er læst helt ind. Det løser et problem man tit render på som er at hvis man skriver javscript i starten af en side, så kan man risikere at denne køres inden alle elementerne endnu er loaded, og omvendt hvis man bruger onload eventet ender man med at vente til alt er læst helt ind hvilket heller ikke altid er ønskværdigt. Den næste linie viser brugen af en selector der henter hvert andet (ulige) div element på siden, og sætter deres indhold til ”Woot”. Dette illustrerer hvor powerfull JQuery er, da man faktisk kan manipulere flere elementer i det der kaldes et wrapped set med meget lidt kode.

Udover at kunne manipulere eksisterende elementer vil man selvfølgelig også ofte gerne kunne tilføje nye elementer. Også her er det JQuery to the rescue, da det gør det meget enkelt.

$("<div>Totalt dynamisk indsat tekst der!<div/>").appendTo("#someParentDiv");

Her ses en af de andre mådet at bruge $ funktionen på, da den her fodres med noget html, som så udgør ens wrapped set. Derefter kaldes appendTo med en selector der finder de eksisterende elementer som der skal føjes til.
JQuery tilbyder en bred vifte af metoder til at arbejde med disse wrapped sets, manipulere elementer, properties, attributter osv. Fælles for dem alle er at de virker crossbrowser, hvilket er en af hovedpointerne i JQuery – nemlig at gøre det nemt og ensartet at skrive sine scripts. Udover almindelig element manipulation skal det nævnes at JQuery tilbyder funktioner til at lave animationer og effekter, wrapper funktioner til at foretage Ajax kald og det er bygget til at kunne extendes med plugins, som der allerede findes flere af.

En vigtig ting hvis JQuery skal bruges i samspil med andre javascript librarys er funktionen $ som også bruges af andre librarys. For at undgå denne konflikt kan man disable brugen af $ og i stedet tilgå funktionen direkte som ”jQuery”, hvilket $ i virkeligheden blot er en genvej til. For at disable $ skal man blot kalde jQuery.noConflict();

Har du fået lyst til at læse mere om JQuery kan jeg anbefale bogen JQuery in Action, som har været min primære inspirationskilde.

LINQ to JavaScript – endnu et skridt imod begrænsningen af for-loops

Navnet siger jo egentlig det hele, da de fleste efterhånden har hørt om og sikkert også leget lidt med LINQ. LINQ to JavaScript er helt enkelt et codeplex projekt, som implementere det der svarer til LINQ to objects i JavaScript. Fordelene ved LINQ er der allerede skrevet alt for meget om rundt omkring, så jeg vil gå lige på og fortælle lidt mere konkret om JavaScript implementationen.
Indtil videre er følgende operatorer implementeret, men der er med garanti flere på vej:

From, Where, Select, OrderBy, OrderByDescending, Count, Distinct, Any, All, Many, Reverse, First, Last, ElementAt, InterSect, DefaultIfEmpty, ElementAtOrDefault, FirstOrDefault og LastOrDefault.

Et eksempel på at bruge de mest gængse kunne være.

var myArray =  [
{Name:"Hans", Age:20 },
{Name:"Erik", Age:10 },
{Name:"Christian", Age:26 }
];

var myResult =
    From(myArray).
    Where(function(item){return item.Age > 15}).
    OrderBy("item.Name").Select(function(item){return item});

Som eksemplet viser kan operatorerne generelt tage to slags argumenter til at beskrive hvilken property der arbejdes på, idet man enten kan bruge en streng (eksempelvis ”item.Name”) eller en funktion der tager item som argument.
Jeg synes personligt at de er sluppet meget godt af sted med det der er implementeret i LINQ to JavaScript, og jeg er sikker på jeg selv nok skal komme til at bruge det en del fremover.
Ellers er der ikke mere jeg har tilbage at skrive om javascript og javascript frameworks for denne gang, men jeg håber det giver andre blod på tanden. Det i hvert fald har givet mig lyst til at arbejde mere med javascript efter at jeg har set hvad nogle af de her frameworks giver af muligheder.

Dynamic Language Runtime

by DotNetNerd 3. November 2007 23:36

DLR - Dynamic Language Runtime.

Jeg fik for et stykke tid siden øje på en blogpost der omhandlede endnu et tiltag Microsoft arbejder på til .NET frameworket - nemlig en Dynamic Language Runtime. Umiddelbart tænkte jeg "fint nok men hvad skal jeg bruge det til". Det spørgsmål fik jeg så besvaret nu her da jeg faldt over en video fra MIX07 omkring dette emne. Jeg vender tilbage til videoen senere, da den indeholdt et temmeligt fedt eksempel som jeg vil gengive.

Kort fortalt er styrken ved dynamiske sprog at de "bare er tekst" ligesom en aspx- eller xaml-fil. Derved giver de nogle muligheder for især webudviklere ved egentlig at vende en smule tilbage til webudviklingens barndom. Idet sprogene er fortolkede, og altså "bare tekst" der ikke skal kompileres for at kunne afvikles, kan man arbejde uden konstant at skulle igennem en code-compile-review cyklus.

Dette kan især være rart hvis man skal udgive rettelser til en webapplikation, men også under selve udviklingen da man kan sidde med browseren fremme på den ene skærm imens man retter i koden på den anden og ser ændringerne slå igennem med det samme.

Hvilke sprog kan man så kode i?

Til at at starte med arbejder Microsoft på at udvikle implementationer baseret på sprogene:

  • IronRuby
  • IronPython
  • JavaScript
  • Dynamic VB

Ligesom med den almindelige CLR er det meningen at det skal være muligt at udvide med flere sprog hen ad vejen. De 4 sprog der er med til at starte med er valgt ud fra at de for det første er meget udbredte, og så for JavaScripts vedkomne fordi det giver mulighed for at man meget let kan genanvende sine eksisterende Ajax scripts i f.eks en Silverlight applikation. VB er som altid representeret af hensyn til Microsofts eget Office team. IronRuby og IronPython er enormt populære sprog der er svære at komme uden om - og de har en force i at de begge har en lækker syntaks der er meget lidt verbos.

Mix and Match

Der før omtalte eksempel fra MIX07 synes jeg gav en virkelig god idé om hvilke muligheder der vil være for at lege "Mix and Match" i fremtiden, da det illustrerer hvor enkelt man kan blande forskellige sprog - hvad end det er CLR eller DLR sprog, og hvad enten det er ASP, Silverlight eller helt almindelig HTML.

Eksemplet er en Silverlight applikation skrevet i Ruby og benytter en knap skrevet i C#, som kører et animationsscript skrevet i DLR JavaScript der viser tekstelementer der floater rundt. Teksterne er hentet fra en service skrevet i VB, udfra et ord der er indtastet i en HTML textbox som tilgås via Silverlights HTML DOM.

require 'Silverlight.Samples.Controls.Version=0.0.0.0'

Controls = Silverlignt.Samples.Controls
Document = System.Windows.Browser.HtmlPage.Document

JS = require '3dText.js'
VB = require 'technorati.vbx'

def initialize(s, e)
    button = Controls.Button.new
    button.Text = "Click me"

    JS.initialize

    root.children.add button

    button.click do |s, e|
        JS.clearList
        term = Document.txtSearchTerm.Value
        items = VB.GetTitles(term)
        items.each { |item| JS.initializeName(item)}
        JS.playAnimation
    end
end

Som man kan se er Ruby meget letvægts, og hvis man tænker over antallet af komponenter skrevet i forskellige sprog fra forskellige miljøer der arbejder sammen her kan man ikke undgå at blive lidt imponeret over hvor smertefrit CLR og DLR sprog taler sammen.

Det er værd at bide mærke i de første 5 linier fra eksemplet hvor man ser hvor let det er at importerer komponenter fra serveren, samt at referere til dynamisk kode skrevet i andre sprog. Det er ganske enkelt bare at bruge en simpel require statement.

Derefter viser eksemplet en initialize metode, som det er defineret i den tilhørende XAML fil skal kaldes ved init. I initialize instantieres så en knap, og en tilsvarende initialize metode på JavaScript komponenten kaldes. Knappen tilføjes så til et canvas der er navngivet root. Knappen for derefter tildelt en anonym eventhandler, der clearer den liste af tekster og tilføjer nye ord hentet fra VB servicen. Til sidst er det blot at starte animationen og så er koden kørende.

Hvordan platformen blev til.

En sjov historie fra videoen er at en af dem der har været med til at lave det oprindeligt startede med at ville skrive en artikel for at lave grin med Microsoft, da han havde hørt at .NET var elendigt at bygge dynamiske sprog oven på.
Han skrev så en implementation af Python oven på CLR'en - og til hans store overraskelse sparkede den røv på den originale Python. Med andre ord viste benchmarks at hans implementation performede dobbelt så godt! Derefter endte han så med at arbejde for Microsoft og har været med til at bygge denne platform til at hoste dynamiske sprog.

AddThis

Share |

Who am I?

My name is Christian Holm Nielsen, and I work at Vertica A/S, in Denmark, where I build custom and Microsoft Commerce Server based solutions.

Some of my primary focus areas are code quality, programming languages and new technologies in .NET.

Google reader

Misc

Indlæser...