JavaScript OOP – jQuery approach
Javascript is very elastic language. Although it's not meant to be OOP language you can create objects (coping prototype etc...). You can find many ways of creating and extending classes. However I want to present you one more. It's really simple if you use jQuery. You can create objects from jQuery Dom element or from whatever you want.
Lat's say you want to create a class that behaves like $('<div/>') but has some more features:
this.name = name;
this.init = function() {
console.log('BoxClass constructor');
return this;
}
this.sayHello = function() {
this.append('My name is ' + name);
}
return $('<div/>').extend(true, this).init();
}
generally magic is here:
Now when you create a new instance of BoxClass:
BoxClass function/class wil create new $('<div/>') element extend it with it's class methods and variables and call init() method on it.
Now you can do thinks like that:
box.text('abc'); //call of text method from jQuery dom object
box.fadeIn().sayHello(); //call fadeIn from jQuery $('<div/>') and then sayHello from BoxClass
You can specify private variables using var variableName inside BoxClass function so encapsulation is easy.
If you want to create class that inherits from BoxClass then just do it like that:
this.init = function() {
this.append('<h2/>').text('Abccc');
console.log('PanelClass constructor');
return this;
}
this.sayHop = function() {
this.append('HopHop' + name);
}
return (new BoxClass(name)).extend(true, this).init();
}
It's creating new BoxClass(name), extending it with PanelClass and calling init method. You can remove the call of init method if you don't want your class to have a constructor.
This extending method is really simple. Actually it's one line ( return $('<div>').extend(true, this) ) called in a proper manner and in right place:
var privateVariable = 'value';
this.publicMethod = function() {}
return $('<div/>').extend(true, this)
}
It's powerful - you can extend every visual and not visual object.
Zend FrontController per module plugins
It's always a problem to setup a concrete module in zend.
There is a per module Bootstrap class in Zend but it does not play as "per module" bootstrap.
It's becouse during the bootstrap no route is resolved so we don't know what module we are in yet.
I want to present you simple solution for per module configuration: FrontController plugins defined for specific module.
The concept is simple. You must add 2 classes to your application: Sel_Application_Resource_PluginLoader and Sel_Controller_Plugin_PluginLoader.
Pluginloader resource adds pluginLoader front plugin to front controller and instruct this what kind of plugins it should load, then pluginloader front plugin during routeShutdown adds plugins to front (adds only plugins needed for this module).
here is a code of Sel_Application_Resource_PluginLoader
public function init() {
$bootstrap = $this->getBootstrap();
$bootstrap->bootstrap('frontController');
$front = $bootstrap->getResource('frontController');
$loader = new Sel_Controller_Plugin_PluginLoader();
$options = $this->getOptions();
foreach($options as $module => $plugins) {
foreach($plugins as $plugin) {
$loader->addPlugin($module, $plugin);
}
}
$front->registerPlugin($loader);
}
}
And a code of Sel_Controller_Plugin_PluginLoader
private $_plugins = array();
public function addPlugin($module, $pluginName) {
$module = strtolower($module);
if( ! isset($this->_plugins[$module] ) )
$this->_plugins[$module] = array();
$this->_plugins[$module][] = $pluginName;
}
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$module = strtolower($request->getModuleName());
$front = Zend_Controller_Front::getInstance();
if( empty($this->_plugins[$module]) )
return;
foreach($this->_plugins[$module] as $pluginName) {
$front->registerPlugin(new $pluginName());
}
}
}
You can define plugin rules in application.ini file like that:
resources.pluginLoader.admin.plugin2 = "App_Controller_Plugin_Plugin2"
resources.pluginLoader.default.plugin3 = "App_Controller_Plugin_Plugin3"
Feel free to use it. (licence: I don't care)
Few changes in ZendDoctrineAmf
I don't really remember what is fixed. Well just download:)
Flex WYSIWYG component
http://blog.flexexamples.com
I've created wysiwyg text editor
<s:VGroup name="Wysiwyg"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import flash.text.engine.FontPosture;
import flash.text.engine.FontWeight;
import flashx.textLayout.formats.TextAlign;
import flashx.textLayout.formats.TextDecoration;
import flashx.textLayout.formats.TextLayoutFormat;
import mx.events.ColorPickerEvent;
import mx.events.FlexEvent;
import spark.events.IndexChangeEvent;
private var _anchorPos:int;
private var _activePos:int;
protected function _onSelectionChange(event:FlexEvent) : void {
var format:TextLayoutFormat;
_anchorPos = editor.selectionAnchorPosition;
_activePos = editor.selectionActivePosition;
format = editor.getFormatOfRange(null, _anchorPos, _activePos);
buttonBold.selected = (format.fontWeight == FontWeight.BOLD);
buttonItalic.selected = (format.fontStyle == FontStyle.ITALIC);
buttonUnder.selected = (format.textDecoration == TextDecoration.UNDERLINE);
buttonLeft.selected = (format.textAlign == TextAlign.LEFT);
buttonRight.selected = (format.textAlign == TextAlign.RIGHT);
buttonCenter.selected = (format.textAlign == TextAlign.CENTER);
buttonJustify.selected = (format.textAlign == TextAlign.JUSTIFY);
textColor.selectedColor = format.color;
ddlSize.selectedItem = format.fontSize;
}
protected function _onBoldClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
if(format.fontWeight == FontWeight.BOLD) format.fontWeight = FontWeight.NORMAL
else format.fontWeight = FontWeight.BOLD;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
}
protected function _onItalicClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
if( format.fontStyle == FontPosture.ITALIC) format.fontStyle = FontPosture.NORMAL;
else format.fontStyle = FontPosture.ITALIC;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
}
protected function _onUnderClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
if( format.textDecoration == TextDecoration.UNDERLINE) format.textDecoration= TextDecoration.NONE;
else format.textDecoration = TextDecoration.UNDERLINE;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
}
protected function _onSizeChange(event:IndexChangeEvent) : void{
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
format.fontSize = ddlSize.selectedItem;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
}
protected function _onLeftClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
format.textAlign = TextAlign.LEFT;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
buttonRight.selected = false;
buttonCenter.selected = false;
buttonJustify.selected = false;
}
protected function _onRightClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
format.textAlign = TextAlign.RIGHT;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
buttonLeft.selected = false;
buttonCenter.selected = false;
buttonJustify.selected = false;
}
protected function _onCenterClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
format.textAlign = TextAlign.CENTER;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
buttonLeft.selected = false;
buttonRight.selected = false;
buttonJustify.selected = false;
}
protected function _onJustifyClick(event:MouseEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
format.textAlign = TextAlign.JUSTIFY;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
buttonLeft.selected = false;
buttonRight.selected = false;
buttonCenter.selected = false;
}
protected function _onTextColorChange(event:ColorPickerEvent) : void {
var format:TextLayoutFormat = editor.getFormatOfRange(null, _anchorPos, _activePos);
format.color = textColor.selectedColor;
editor.setFormatOfRange(format, _anchorPos, _activePos);
editor.setFocus();
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="availableSizes" source="[6, 8, 10, 12, 14, 16, 24, 36, 72]"/>
</fx:Declarations>
<s:TextArea id="editor"
width="100%" height="100%"
minHeight="200"
focusEnabled="false"
selectionChange="_onSelectionChange(event)" />
<s:HGroup>
<s:ToggleButton id="buttonBold"
label="B"
width="30"
fontWeight="bold"
click="_onBoldClick(event)"/>
<s:ToggleButton id="buttonItalic"
label="I"
fontStyle="italic"
width="30"
click="_onItalicClick(event)"/>
<s:ToggleButton id="buttonUnder"
label="U"
textDecoration="underline"
width="30"
click="_onUnderClick(event)"/>
<s:DropDownList id="ddlSize"
width="60"
change="_onSizeChange(event)"
dataProvider="{availableSizes}" />
<s:Group>
<s:layout>
<s:HorizontalLayout gap="0"/>
</s:layout>
<s:ToggleButton id="buttonLeft"
label="L"
width="30"
click="_onLeftClick(event)"/>
<s:ToggleButton id="buttonCenter"
label="C"
width="30"
click="_onCenterClick(event)"/>
<s:ToggleButton id="buttonRight"
label="R"
width="30"
click="_onRightClick(event)"/>
<s:ToggleButton id="buttonJustify"
label="J"
width="30"
click="_onJustifyClick(event)"/>
</s:Group>
<mx:ColorPicker id="textColor" change="_onTextColorChange(event)" />
</s:HGroup>
</s:VGroup>
PureMVC notification joiner mediator
Hi.
This post is about loading thinks (grouping notifications) in PureMVC ActionScript framework.
It's always a problem to utilize loading and things like that. Let's imagine that you want to wait for many notifications and after that moment send one notification informing that everything is loaded, completed or done. You can always write new mediator that waits for whole these notifications and another one that waits for another notifications. To load proxies you can always use StartupMonitorProxy (that comes with PureMVC AppSkeleton application) - true.
I want to present you today somethink new. Mediator that waits for any list of notifications and after that moment sends one note. Now you can do this with one method.
I wrote this (I think usefull) class for this kind of stuff:
import org.puremvc.as3.multicore.core.View;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.interfaces.IView;
import org.puremvc.as3.multicore.patterns.mediator.Mediator;
import org.puremvc.as3.multicore.patterns.observer.Observer;
/**
* @author Szymon Wygnański ( szymon(at)selecton.net )
* @licence: Creative Commons Attribution – Share Alike.
*/
public class NotificationJoinerMediator extends Mediator {
static public const NAME:String = 'NotificationJoinerMediator';
private var _view:IView;
private var _joinRules:Object;
public function NotificationJoinerMediator() {
super(NAME);
}
override public function onRegister() : void {
_view = View.getInstance( multitonKey );
_joinRules = new Object();
}
public function addRule(notificationsList:Array, notificationToSendAfter:String) : void {
var observer:Observer = new Observer( handleNotification, this );
var noteList:Object = new Array();
for(var i:int = 0; i < notificationsList.length; i++) {
var note:String = notificationsList[i];
noteList.push( note );
_view.registerObserver( note, observer );
}
_joinRules[notificationToSendAfter] = noteList;
}
private function _checkRule(toSend:String) : void {
var rule:Array = _joinRules[toSend];
if( rule.length == 0 ) {
sendNotification(toSend);
delete _joinRules[toSend];
}
}
override public function handleNotification(notification:INotification) : void {
var noteName:String = notification.getName();
var existanceQuantity:int = 0;
for(var toSend:String in _joinRules ) {
var notes:Array = _joinRules[toSend];
var i:int = 0;
if( _deleteIfExist(notes, noteName) ) {
existanceQuantity++;
_checkRule(toSend);
}
}
if( existanceQuantity == 1 )
_view.removeObserver( noteName, this );
}
private function _deleteIfExist(list:Array, needle:String) : Boolean {
var exists:Boolean = false;
var i:int;
for( i = 0; i < list.length; i++) {
if( list[i] == needle ) {
exists = true;
break;
}
}
if( exists ) list.splice( i, 1 );
return exists;
}
}
}
How to use it?
First you have to register this mediator so that it grants it's multitionKey
After that you can add rule like that:
noteJoinerM.addRule( [ NOTE_1, _NOTE_2, _NOTE_3], NOTE_ALL_DONE );
And somewhere else register to NOTE_ALL_DONE. When NOTE_1 and NOTE_2 and NOTE_3 will be send notificationJoinerMediator will send NOTE_ALL_DONE notification and remove this rule.
I hope you will like this class and you will find it handy.
New version (v0.2) of ZendDoctrineAmf
Few changes has been made to ZendDoctrineAmf project.
Main thinks are:
- module amf was renamed to module webservices and amf controller was created here (Jarek's suggestion)
- amf services now are in APPLICATION_PATH "/modules/webservices/amfservices"
- static class for fast logging (Sel_Log) added
- example module "tests" with models has been added
- Sel_Controller_Action_Plugin_InitModules added. This module sets Doctrine models path specific for current module
You can download new version here:
ZendDoctrineAmf
I'm still working on this project so if you have any suggestions please leave a comment I will be really grateful.
Zend Framework + Doctrine + AMF
Whole day I was going through doctrine and zend tutorials to set up a framework with both. Finally I've created a working copy of Zend framework with module amf (containing services directory) and Doctrine model abstraction layer (thanks to Jarosław Kielmas for showing me this stuff. Must visit his blog: kielmas.com).
Of course my main source of information was documentation of Zend and Doctrine however it would be impossible to do that without some help from other bloggers like:
blog.hackix.com
ruben.savenne.be
www.riaspace.net
Big thanks
You can download my work here:
This file may be a good point to start your work.
Tile wallpaper creation
It's always a problem to make seamless wallpaper with no visible edge connection. You can try doing this in your graphical programs merging photo but it's really hard task.
I've got good news for you. There is a great program that can do it in few seconds. It's written in AIR.
Got to it's author's page for more info and binaries. It's really amazing:
http://www.studioludens.com/repper/
Moving the blog
Yeah!
Finally I moved this blog from blogger to wordpress and to my host provider.
By the way graphical layout was changed:)
I hope finding more time to post. Maybe I will write about somethink more then just programming?
But don't worry, main think you'll be able to find here will be classes:)
Many thinks changed in my life lately, but hopefully for good. For good for me and for you becouse I'll have more time to write now.
Please keep in mind that I'm still learning english. This blog is supposed to help me with this task so if you find any ort or grammar mistakes please let me know.
Blog changed the name. Earlier i was writing under my surname now I decided to change that. Hope you will like the blog name.
Why selecton? Becouse I'm the man with free will, making choices, selecting (not always) good ways.
O.K. that's all.
May the source be with you.