Ok so first off here is my very basic jQuery plugin
(function ($){
$.fn.greenify = function (options) {
var settings = $.extend({
// These are the defaults
color: '#556b2f',
backgroundColor: 'white'
}, options);
}(jQuery));
$('a').greenify({
color: 'orange'
}).showLinkLocation();
Basically all this does is change the text color and background-color with the provided element. Now what I am trying to do is convert this simple plugin into TypeScript
I have tried a few things and the closest I got is this.
TypeScript
/// <reference path="../../typings/jquery/jquery.d.ts" />
module Coloring
{
interface IGreenifyOptions
{
color: string;
backgroundColor: string;
}
export class GreenifyOptions implements IGreenifyOptions
{
// Fields
color: string;
backgroundColor: string;
constructor(color: string, backgroundColor: string)
{
this.color = color;
this.backgroundColor = backgroundColor;
}
}
export class Greenify
{
// Fields
element: JQuery;
options: GreenifyOptions;
constructor(element: JQuery, options: GreenifyOptions)
{
this.element = element;
this.options = options;
this.OnCreate();
}
OnCreate()
{
this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
}
}
}
JQuery which calls it
$(function ()
{
var options: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');
var $elems = $('a');
$elems.each(function()
{
var result = new Coloring.Greenify($(this), options)
});
});
However I don't want to provide the element like the above new Coloring.Greenify($(this), options)
, I basically want to do something like this
$('a').Coloring.Greenify(options);
or
$('a').Coloring.Greenify(Coloring.GreenifyOptions()
{
color: '#F0F',
backgroundColor: '#FFF'
});
But I can't seem to figure how to tell TypeScript that the element it is attached to already is the Jquery
element. Could anyone shine some light on this to help me out.
P.S. the above I have works fine, I just want to change the calling code.
Update
This is what I have at the moment and it works
TypeScript
interface JQuery
{
Greenify();
Greenify(options: Coloring.GreenifyOptions);
}
(function ($)
{
$.fn.Greenify = function (options)
{
return new Coloring.Greenify(this, options);
}
})(jQuery);
jQuery
var $elems = $('a').Greenify(options);
However it means I have to provide options and if I do the constructor without options I get options is undefined. The answer I have ticked as correct is correct for the question I have asked. However just keep in mind that the answer provided required you provide options into your typescript constructor, I am going to see on how to have default options and then override them in the constructor but this is a different question :)
Update 2
Just to let everyone know I have found a way to provide options to your plugin or not.
What you can do is this
TypeScript class
export class Greenify
{
// Default Options
static defaultOptions: IGreenifyOptions =
{
color: '#F00',
backgroundColor: '#00F'
};
// Fields
element: JQuery;
options: GreenifyOptions;
constructor(element: JQuery, options: GreenifyOptions)
{
// Merge options
var mergedOptions: GreenifyOptions = $.extend(Greenify.defaultOptions, options);
this.options = mergedOptions;
this.element = element;
this.OnCreate();
}
OnCreate()
{
this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
}
}
TypeScript Interface
interface JQuery
{
Greenofy();
Greenify(obj?: any);
Greenify(options?: Coloring.GreenifyOptions);
}
(function ($)
{
$.fn.Greenify = function (options)
{
return new Coloring.Greenify(this, options);
}
})(jQuery);
jQuery code to call the plugin with one optional option
$(function ()
{
var $elems = $('a').Greenify(<Coloring.GreenifyOptions>{
color: '#00F'
});
});
So not the output will make the anchors background color '#00F' which is the default and the option I have provided will make the anchor text color '#00F'.
I hope this helps anyone else that is having the same problem as me :)
Creating jQuery plugins along with TypeScript can get a bit messy. I personally prefer keeping the jQuery plugin chaining syntax, mostly for consistency and maintainability .
So, after the module declaration you can basically wrap around your implementation extending the jQuery prototype as:
module Coloring {
interface IGreenifyOptions {
color: string;
backgroundColor: string;
}
export class GreenifyOptions implements IGreenifyOptions {
// Fields
color: string;
backgroundColor: string;
constructor(color: string, backgroundColor: string) {
this.color = color;
this.backgroundColor = backgroundColor;
}
}
export class Greenify {
// Fields
element: JQuery;
options: GreenifyOptions;
constructor(element: JQuery, options: GreenifyOptions) {
this.element = element;
this.options = options;
this.OnCreate();
}
OnCreate() {
this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
}
}
}
//jquery plugin wrapper.
;
(function(w, $) {
//no jQuery around
if (!$) return false;
$.fn.extend({
Coloring: function(opts) {
//defaults
var defaults: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');
//extend the defaults!
var opts = $.extend({}, defaults, opts)
return this.each(function() {
var o = opts;
var obj = $(this);
new Coloring.Greenify(obj, o);
});
}
});
})(window, jQuery);
Fetching the plugin as:
$(function() {
var $a = $('a').Coloring();
var $div = $('div').Coloring({
color: '#F0F',
backgroundColor: '#FFF'
});
var $div = $('strong').Coloring({
color: '#gold',
backgroundColor: 'pink'
});
});
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With