:: Forum >> Version 2 >>

AW.Templates.Textarea - let's get started



Okay, so I really need a skinned textarea.... and I love all the events, etc. that comes with input boxes so.....

That means this will involve many people and plenty of time... since after-all we want it to be good enough that Alex can easily include it into the next release (hopefully soon.... next bug release?).

So, I started by taking the imagetext Template and UI and began to take out the native HTML for the input box, and replace it with the native textarea element... easier said than done but we'll see how we can do it.

First off, remember that input boxes maintain a value. Textarea's maintain an innerHTML-type value.... BUT you'll notive the startEditGecko has a line in it for e.value..... because e.innerHTML isn't updated from the AW.HTML.TEXTAREA until you finish editing the textarea or explicitly set it....

BUGS:
1) I had to explicitly fire the startEdit event in the controller.... how is this supposed to be fired?
2) Should we not use the AW.HTML.TEXTAREA and use a straight textarea dom object? The input boxes are created as node2 in the bottom of the Gecko start... but not in ie... don't know why.
3) ANY SUGGESTIONS WILL HELP!
4) ANY SUGGESTIONS WILL HELP!
5) I DON'T understand all about the models, controllers, panels, etc. etc.... but I'm learning.

AW.Templates.Textarea AW.System.Template.subclass();
AW.Templates.Textarea.create = function(){
    var 
obj this.prototype;

    function 
_text(){return this.getControlProperty("text")}
    function 
_tooltip(){return this.getControlProperty("tooltip")}

    var 
span AW.HTML.SPAN;

    var 
ruler = new span;
    
ruler.setClass("item""ruler");

    var 
text = new AW.HTML.TEXTAREA;
    
text.setClass("item""text");
    
text.setContent("text"_text);

    var 
box = new span;
    
box.setClass("item""box");
    
box.setContent("sign""");
    
box.setContent("marker""");
    
box.setContent("ruler"ruler);
    
box.setContent("text"text);

    
obj.setTag("span");
    
obj.setClass("item""template");
    
obj.setClass("templates""textarea");
    
obj.setAttribute("title"_tooltip);
    
obj.setContent("box"box);

    if (
AW.gecko){
        
obj.setAttribute("tabIndex""-1");
    }

    var 
startEditIE = function(startText){

        var 
self this;
        var 
item self.getAttribute("aw");
        var 
originalText self.getControlProperty("text");
        var 
text originalText;
        var 
valid;

        var 
self.getContent("box/text").element();
        var 
self.element();

        
alert('startIE');

        if (!
|| !x) {
            return;
        }

        var 
textarea = (e.tagName == "textarea") || (e.tagName == "textarea");

        function 
raiseEvent(name){
            var 
text1 self.getControlProperty("text");
            var 
fullname AW.camelCase("on"itemname);
            var 
result self.raiseEvent(fullnametextself.$0self.$1self.$2);
            var 
text2 self.getControlProperty("text");
            if (
text2 != text1) {
                
updateText(text2);
            }
            return 
result;
        }

        if (
raiseEvent("editStarting")){
            
null;
            
null;
            return;
        }

        function 
nobubble(event){
            
event.cancelBubble true;
        }

        function 
updateText(text){
            
e.innerHTML text;
        }

        function 
onpropertychange(event){
            var 
text1 self.getControlProperty("text");
            var 
text2 e.innerHTML.replace(/ /g" ");
            if (
text2 != text1){
                
self.setControlProperty("text"text2);
            }
            var 
text3 self.getControlProperty("text");
            if (
text3 != text2 ) {
                
updateText(text3);
            }
        }

        function 
onkeydown(event){
            if (
event.keyCode == 27){ // 'escape' key
                
e.innerHTML originalText;

                
event.returnValue false;

                if (!
self.$owner){
                    return;
                }

                
onbeforedeactivate(event);
                if (
valid) {
                    
ondeactivate(event);
                }
                return;
            }
            if (
event.keyCode == 13){ // 'enter' key

                
text self.getControlProperty("text");

                if (!
self.$owner){
                    if (
raiseEvent("validating")){
                        return;
                    }
                    
raiseEvent("validated");
                    return;
                }

                
event.returnValue false;
                
event.cancelBubble true;

                
onbeforedeactivate(event);
                if (
valid) {
                    
ondeactivate(event);
                }
                return;
            }

            var 
r;

//            if (textarea) {
//                r = e.createTextRange();
//            }
//            else {
                
document.body.createTextRange();
                
r.moveToElementText(e);
//            }

            
var document.selection.createRange();

            if ((
event.keyCode == 36 || event.keyCode == 37) &&     // home, left arrow
                
r.compareEndPoints("StartToStart"s)){
                
event.cancelBubble true;
                
null;
                
null;
                return;
            }
            if ((
event.keyCode == 35 || event.keyCode == 39) &&     // end, right arrow
                
r.compareEndPoints("EndToEnd"s)){
                
event.cancelBubble true;
                
null;
                
null;
                return;
            }
        }

        function 
onbeforedeactivate(event){
            
valid false;
            
text self.getControlProperty("text");
            if (
text != e.innerHTML.replace(/ /g" ")){
                
text e.innerHTML.replace(/ /g" ");
                
self.setControlProperty("text"text);
            }
            var 
text2 self.getControlProperty("text");
            if (
text2 != text){
                
updateText(text2);
                
text text2;
            }

            if (
self.element().contains(event.toElement)){
                
event.returnValue false;
                return;
            }

            if (
raiseEvent("editEnding")){
                
event.cancelBubble true;
                
event.returnValue false;
                return;
            }
            if (
originalText == text){
                
valid true;
                return;
            }
            if (
raiseEvent("validating")){
                
event.cancelBubble true;
                
event.returnValue false;
                return;
            }
            
raiseEvent("validated");
            
valid true;
        }

        function 
ondeactivate(event){
            
text self.getControlProperty("text");
            
e.removeExpression("aw-value");
            
e.detachEvent("onselectstart"nobubble);
            
e.detachEvent("oncontextmenu"nobubble);
            
x.detachEvent("onmousedown"nobubble);
            
x.detachEvent("onmouseup"nobubble);
            
x.detachEvent("onclick"nobubble);
            
x.detachEvent("ondoubleclick"nobubble);
            
e.detachEvent("onpropertychange"onpropertychange);
            
e.detachEvent("onkeydown"onkeydown);
            
e.detachEvent("onbeforedeactivate"onbeforedeactivate);
            
e.detachEvent("ondeactivate"ondeactivate);

//            if (!textarea){
//                e.contentEditable = false;
//            }

            
e.parentNode.scrollLeft 0;
            
x.className x.className.replace(" aw-edit-" item"");
            if (
self.$owner) {
                
self.$owner.$edit false;
            }
            
raiseEvent("editEnded");
            
null;
            
null;
        }

        
x.className x.className.replace(/ aw-mousedown-\w+/g"") + " aw-edit-" item;

//        if (!textarea){
//            e.contentEditable = true;
//        }
        
e.attachEvent("onselectstart"nobubble);
        
e.attachEvent("oncontextmenu"nobubble);

//        if (textarea){
//            e.select();
//        }
//        else {
            
e.focus();
//        }

        
e.setExpression("aw-value"input ? "this.value" "this.innerHTML");
        
x.attachEvent("onmousedown"nobubble);
        
x.attachEvent("onmouseup"nobubble);
        
x.attachEvent("onclick"nobubble);
        
x.attachEvent("ondoubleclick"nobubble);
        
e.attachEvent("onpropertychange"onpropertychange);
        
e.attachEvent("onkeydown"onkeydown);
        
e.attachEvent("onbeforedeactivate"onbeforedeactivate);
        
e.attachEvent("ondeactivate"ondeactivate);

        if (
self.$owner) {
            
self.$owner.$edit true;
        }

        
raiseEvent("editStarted");

        if (
typeof(startText) == "string"){
            
e.innerHTML startText;
        }
    };

    var 
startEditGecko = function(startText){

        var 
self this;
        var 
item self.getAttribute("aw");
        var 
originalText self.getControlProperty("text");
        var 
text originalText;

//        alert(text);

        
var self.getContent("box/text").element();
        var 
self.element();

        if (!
|| !x) {
            return;
        }

        var 
updateText = function(text){
//            alert(text+' (U)');
            
e.innerHTML text;
        };

        function 
raiseEvent(name){
            var 
text1 self.getControlProperty("text");
            var 
fullname AW.camelCase("on"itemname);
            var 
result self.raiseEvent(fullnametextself.$0self.$1self.$2);
            var 
text2 self.getControlProperty("text");
            if (
text2 != text1) {
                
updateText(text2);
            }
            return 
result;
        }

        if (
raiseEvent("editStarting")){
            
null;
            
null;
//            alert('return due to editStarting');
            
return;
        }

        
updateText = function(text){
//            alert(text+' (2)');
            
e.innerHTML text;
        };

        function 
nobubble(event){
            
event.stopPropagation();
        }

        function 
oninput(event){
            var 
text1 self.getControlProperty("text");
            var 
text2 e.value;
//            alert(text1+' (3) '+text2);
            
if (text2 != text1){
                
self.setControlProperty("text"text2);
            }
            var 
text3 self.getControlProperty("text");
//            alert(text2+' (4) '+text3);
            
if (text3 != text2 ) {
                
updateText(text3);
            }
            
text text3;
        }

        function 
onkeydown(event){
            if (
event.keyCode == 27){ // 'escape' key

                
alert(originalText+' (ESC)');
                
e.innerHTML originalText;

                
event.preventDefault();

                if (!
self.$owner){
                    return;
                }

                
try {
                    
self.$owner.getContent("focus").element().focus();
                    return;
                }
                
catch(err){
                    
// ignore focus errors
                
}

                
onfocus(event);
                return;
            }
            if (
event.keyCode == 13){ // 'enter' key

                
text self.getControlProperty("text");

                
alert(text+' (ENT)');
                if (!
self.$owner){
                    
insideFocus true;
                    if (
raiseEvent("validating")){
                        
insideFocus false;
                        return;
                    }
                    
raiseEvent("validated");
                    
insideFocus false;
                    return;
                }

                
event.preventDefault();
                
event.stopPropagation();

                
try {
                    
self.$owner.getContent("focus").element().focus();
                    return;
                }
                
catch(err){
                    
// ignore focus errors
                
}

                
onfocus(event);
                return;
            }

            if ((
event.keyCode == 36 || event.keyCode == 37) &&     // home, left arrow
                
e.selectionStart 0){
                
event.stopPropagation();
                return;
            }
            if ((
event.keyCode == 35 || event.keyCode == 39) &&     // end, right arrow
                
e.selectionStart e.value.length){
                
event.stopPropagation();
                return;
            }
        }


        function 
cancelEvent(event){
            if (
event.target != document){
                
event.preventDefault();
                
event.stopPropagation();
            }
        }


        var 
insideFocus;

        function 
focusBack(event){
            
event.preventDefault();
            
event.stopPropagation();
            
e.focus();
            
window.removeEventListener("blur"cancelEventtrue);
            
insideFocus false;
        }

        var 
inDocFocus;

        function 
docFocus(event){
            if (
inDocFocus){
                return;
            }
            
inDocFocus true;

            var 
document.createEvent("HTMLEvents");
            
e.initEvent("focus"falsefalse);
            
e.deferred true;

            
window.setTimeout(function(){
                if (
inDocFocus){
                    
onfocus(e);
                }
                
null;
            });
        }

        function 
onfocus(event){

            if (
event.type=="focus" && event.target == document && !event.deferred){
                return 
docFocus(event);
            }

            
inDocFocus false;

            if (
insideFocus || (event.type=="focus" && event.target == e)){
                return;
            }

            
insideFocus true;
            
window.addEventListener("blur"cancelEventtrue);

            function 
isInside(parentchild){
                
try {
                    var 
range document.createRange();
                    
range.selectNode(parent);
                    return 
child && (range.compareNode(child) == 3);
                }
                
catch(err){
                    return 
false;
                }
            }

            if (
event.type == "focus" &&
                (
isInside(xevent.target) || isInside(self.$popupevent.target))){
                return 
focusBack(event);
            }

            
oninput(event);

            if (
raiseEvent("editEnding")){
                return 
focusBack(event);
            }

            if (
text != originalText){
                if (
raiseEvent("validating")){
                    return 
focusBack(event);
                }

                
raiseEvent("validated");
            }

            
window.removeEventListener("blur"cancelEventtrue);
            
insideFocus false;

            
e.removeEventListener("contextmenu"nobubblefalse);
            
x.removeEventListener("mousedown"nobubblefalse);
            
x.removeEventListener("mouseup"nobubblefalse);
            
x.removeEventListener("click"nobubblefalse);
            
x.removeEventListener("doubleclick"nobubblefalse);
            
e.removeEventListener("input"oninputfalse);
            
e.removeEventListener("keydown"onkeydownfalse);
            
window.removeEventListener("focus"onfocustrue);

//            if (!textarea){
//                node2.innerHTML = self.getControlProperty("text");
//                e.parentNode.replaceChild(node2, e);
//            }

            
x.className x.className.replace(" aw-edit-" item"");

            
AW.lockFocus false;

            if (
self.$owner) {
                
self.$owner.$edit false;
            }

            
raiseEvent("editEnded");
            
null;
            
null;
//            node1 = null;
//            node2 = null;

            
if (event.type=="focus" && event.deferred){
                
document.dispatchEvent(event);
            }

        }

        
x.className x.className.replace(/ aw-mousedown-\w+/g"") + " aw-edit-" item;

//        if (textarea){
//            e.select();
//        }
//        else {
//            var node1 = document.createElement("textarea");
//            node1.setAttribute("id", e.id);
//            node1.setAttribute("type", "text");
//            node1.setAttribute("class", e.className);
//            node1.setAttribute("autocomplete", "off");
//            node1.setAttribute("innerHTML", text);
//            var node2 = e.parentNode.replaceChild(node1, e);
//            e = node1;
//            e.focus();
//        }
        
e.focus();

        
e.addEventListener("contextmenu"nobubblefalse);
        
x.addEventListener("mousedown"nobubblefalse);
        
x.addEventListener("mouseup"nobubblefalse);
        
x.addEventListener("click"nobubblefalse);
        
x.addEventListener("doubleclick"nobubblefalse);
        
e.addEventListener("input"oninputfalse);
        
e.addEventListener("keydown"onkeydownfalse);
        
window.addEventListener("focus"onfocustrue);

        
AW.lockFocus true;

        if (
self.$owner) {
            
self.$owner.$edit true;
        }

        
raiseEvent("editStarted");

        if (
typeof(startText) == "string"){
            
e.innerHTML startText;
            
oninput.call(self);
        }

    };

    if (
AW.ie) {
        
obj.startEdit startEditIE;
    }

    if (!
AW.ie) {
        
obj.startEdit startEditGecko;
    }

};


AW.UI.Textarea AW.System.Control.subclass();
AW.UI.Textarea.create = function(){

    
AW.Templates.Textarea.create.call(this);

    var 
obj this.prototype;

    
obj.setClass("templates""");
    
obj.setClass("ui""input");
    
obj.setClass("item""control");
    
obj.setClass("text""expand");

    
obj.setAttribute("tabIndex""-1");

    function 
_tabIndex(){
        return 
this.getTabProperty("index");
    }

    
obj.getContent("box/text").setAttribute("tabIndex"_tabIndex);

    var 
_refresh = function(){this.refresh()};

    var 
itemController = {
        
onControlActivated:     "startEdit",
        
onControlTextChanged:    _refresh,
        
onControlImageChanged:    _refresh,
        
onControlValueChanged:    _refresh,
        
onControlLinkChanged:    _refresh,
        
onControlTooltipChanged:_refresh,
        
onControlStateChanged:    _refresh };

    
obj.setController("item"itemController);

    
obj.setEvent("onactivate", function(event){
        var 
this.getContent("box/text").element();
        if (
&& event.srcElement != ){
            
this.setTimeout(function(){
                
e.setActive();
            });
        }
    });
};


    var 
TA = new AW.UI.Textarea;
    
TA.setSize(200,50);        //SUCCESS
    
TA.setPosition(400,100);    //SUCCESS
    
TA.setControlTooltip("this is a test");   //SUCCESS
    
TA.setControlText("Starting\nValue");    //SUCCESS
//    TA.onControlValueChanging=function(){stat.setControlText('onControlValueChanging');};  //FAILED
//    TA.onControlValueChanged=function(){stat.setControlText('onControlValueChanged');};        //FAILED
//    TA.onControlActivating=function(){stat.setControlText('onControlActivating');};   //SUCCESS
//    TA.onControlActivated=function(){stat.setControlText('onControlActivated');};    //SUCCESS
//    TA.onControlDeactivating=function(){stat.setControlText('onControlDeactivating');};    //SUCCESS
//    TA.onControlDeactivated=function(){stat.setControlText('onControlDeactivated');}; //SUCCESS
//    TA.onKeyPress=function(){stat.setControlText('onKeyPress');};    //SUCCESS
//    TA.onControlMouseOver=function(){stat.setControlText('onControlMouseOver');};    //SUCCESS
//    TA.onControlMouseOut=function(){stat.setControlText('onControlMouseOut');};    //SUCCESS
//    TA.onControlMouseDown=function(){stat.setControlText('onControlMouseDown');};    //SUCCESS
//    TA.onControlMouseUp=function(){stat.setControlText('onControlMouseUp');};    //SUCCESS
//    TA.onControlClicked=function(){stat.setControlText('onControlClicked');};    //SUCCESS
//    TA.onControlDoubleClicked=function(){stat.setControlText('onControlDoubleClicked');};    //SUCCESS
//    TA.onControlEditStarting = function(text){stat.setControlText('onControlEditStarting '+text);};    //SUCCESS
//    TA.onControlEditStarted = function(text){stat.setControlText('onControlEditStarted '+text);};    //SUCCESS
//    TA.onControlValidating = function(text){stat.setControlText('onControlValidating '+text);};    //SUCCESS
//    TA.onControlValidated = function(text){stat.setControlText('onControlValidated '+text);};    //SUCCESS
//    TA.onControlEditEnding = function(text){stat.setControlText('onControlEditEnding '+text);};    //SUCCESS
//    TA.onControlEditEnded = function(text){stat.setControlText('onControlEditEnded '+text);};    //SUCCESS
    
document.write(TA);


    var 
but = new AW.UI.Button;
    
but.setPosition(800,10);
    
but.setControlText('Push Test');
    
but.onClick=function(){TA.setControlText('Testing\nTesting\nTesting');};
    
document.write(but);

    var 
get = new AW.UI.Button;
    
get.setPosition(800,50);
    
get.setControlText('Get Test');
    
get.onClick=function(){alert(TA.getControlText());};
    
document.write(get);


    var 
ref = new AW.UI.Input;
    
ref.setPosition(400,50);
    
ref.setControlText('For Reference');
    
document.write(ref);

    var 
stat = new AW.UI.Label;