﻿/// <reference name="MicrosoftAjax.debug.js" />

//script by yvoschaap.com
//freely useable
//optional link back would be very web 2.0 :)

// I have used the original script by yvoschaap.com
// and changed it all to work compelely with ASP.NET AJAX
// library.

// Register a new Namespace
Type.registerNamespace("bhaidar.CodeSuite.AJAX");

// Define the constructor of the InlineEdit class
bhaidar.CodeSuite.AJAX.InlineEdit = function (uiElement) {
    // Call base class just for completeness
    bhaidar.CodeSuite.AJAX.InlineEdit.initializeBase(this);
    
    this._uiElement = uiElement;
    this._postPage = "InlineEditHandler.aspx";
    this._otherVars = "";
    this._editMode = false;
    
    this._spanToEdit = null;
    
    // ChangeDisplay Delegate
    this._changeDisplayDelegate = Function.createDelegate(this, this.ChangeDisplay);
}

// Define the properties and methods of the InlineEdit class
// using the Prototype Design Pattern
bhaidar.CodeSuite.AJAX.InlineEdit.prototype= {
    
    // Define uiElement Property
    // This property is used to hold the ID of the UI
    // control that is to be edited inline
    get_uiElement:function() {
        // Get
        return this._uiElement;
    },
    set_uiElement:function(value) {
        // Set
        this._uiElement = value;
    },

    // Define postPage Property
    // The page to post to that will handle
    // saving the text typed on the page into a
    // data store
    get_postPage:function() {
        // Get
        return this._postPage;
    },
    set_postPage:function(value) {
        // Set
        this._postPage = value;
    },

    // Define otherVars Property
    // This variable is used to supply additional
    // variables to the postPage
    get_otherVars:function() {
        // Get
        return this._otherVars;
    },
    set_otherVars:function(value) {
        // Set
        this._otherVars= value;
    },

    // Define editMode Property
    // This variable is used to keep track of 
    // editing mode of the _uiElement
    get_editMode:function() {
        // Get
        return this._editMode;
    },
    set_editMode:function(value) {
        // Set
        this._editMode = value;
    },

    // Define spanToEdit Property
    // This property is used to hold the span control
    // that is going to be edited
    get_spanToEdit:function() {
        // Get
        return this._spanToEdit;
    },
    set_spanToEdit:function(value) {
        // Set
        this._spanToEdit = value;
    },
    
    // This method parses the HTML page, get all spans with class "editText",
    // then configures each span to be clickable and editable
    EditBoxInit:function ()
    {
	    if (!document.getElementsByTagName){ return; }
	    var spans = document.getElementsByTagName("span");
    
    	// loop through all span tags
    	for (var i=0; i<spans.length; i++)
    	{
		    var spn = spans[i];
		    if (spn != null)
		    {
                // if the span has a class with name "editText", then
                // configure it
                if (((' '+spn.className+' ').indexOf("editText") != -1) && (spn.id)) 
		        {
                    this._spanToEdit = spn;
                    $addHandler(spn, 'click', this._changeDisplayDelegate);
                    
        			//spn.onclick = Function.createDelegate(this, this.ChangeDisplay(spn));
			        spn.style.cursor = "pointer";
			        spn.title = "Click to edit ...";	
       	        }
       	    }
	    }
    },
    
    // This method changes the display from a span tag
    // into a textbox for the user to use to add the new
    // text
    ChangeDisplay: function() 
    {
        spn = this.get_spanToEdit();
        if (!this.get_editMode())
        {   
		    width = Sys.UI.DomElement.getBounds(spn).width + 20;
		    height = Sys.UI.DomElement.getBounds(spn).height + 2;
		    
		    if(width < 100)
    			width = 150;
		    if(height < 40)
    			spn.innerHTML = "<input id=\""+ spn.id +"_field\" style=\"width: "+width+"px; height: "+height+"px;\" maxlength=\"254\" type=\"text\" value=\"" + spn.innerHTML + "\" onkeypress=\"return FieldEnter(this,event,'" + spn.id + "')\" onfocus=\"HighLight(this);\" onblur=\"NoHighLight(this); return FieldBlur(this,'" + spn.id + "');\" />";
		    else
    			spn.innerHTML = "<textarea name=\"textarea\" id=\""+ spn.id +"_field\" style=\"width: "+width+"px; height: "+height+"px;\" onfocus=\"HighLight(this);\" onblur=\"NoHighLight(this); return FieldBlur(this,'" + spn.id + "');\">" + spn.innerHTML + "</textarea>";
    	
	        this._editMode = true;
        }
        spn.firstChild.focus();
    },

    // This method handles a keypress event inside the
    // editable area and fires a WebRequest to the server
    // to update the edited text in the data store
    FieldEnter: function(ctrl, event, fieldID) 
    {
	    event = (event) ? event : window.event;
	    if (event.keyCode == 13 && ctrl.value != "") 
	    {
            // Execute a POST asynchornous request
            this.UpdateDataStore($get(fieldID), ctrl);
    		
		    // remove glow
		    NoHighLight($get(fieldID));
    				
		    // Page is not in editing stage
		    this._editMode = false;
		    return false;
	    } 
	    else {
		    return true;
	    }
    },

    // This method handles a blur event on the
    // editable area and fires a WebRequest to the server
    // to update the edited text in the data store
    FieldBlur: function(ctrl, fieldID)
    {
	    if (ctrl.value != "") 
	    {
		    // Execute a POST asynchornous request
            this.UpdateDataStore($get(fieldID), ctrl);		

		    this._editMode = false;
		    return false;
	    }
    },
    
    // This method adds a highlight border
    // to the area under edit
    HighLight: function(span)
    {
        span.parentNode.style.border = "2px solid #D1FDCD";
        span.parentNode.style.padding = "0";
        span.style.border = "1px solid #54CE43";          
    },

    // This method sets post/get vars for update
    // Variables can be something as SessionID, etc ...
    SetOtherVars: function(vars)
    {
	    this._otherVars = vars;
    },
    
    // This method removes the highlight from
    // the area under edit
    NoHighLight: function(span)
    {
        span.parentNode.style.border = "0px";
        span.parentNode.style.padding = "2px";
        span.style.border = "0px";
    },
    
    // This method is responsible to contact the server
    // and update the edited text in a data store
    UpdateDataStore: function(elem, ctrl)
    {
        // Instantiate the WebRequest object.
        var webRequest =  new Sys.Net.WebRequest();

        // Set the request Url.
        webRequest.set_url(this.get_postPage()); 
         
        // Set the request verb.
        webRequest.set_httpVerb("POST");
    
        // Encode the content before sending it to the server
        var encodedContent = escape(ctrl.value);
        encodedContent= encodedContent.replace(/\//g,"%2F");
        encodedContent= encodedContent.replace(/\?/g,"%3F");
        encodedContent= encodedContent.replace(/=/g,"%3D");
        encodedContent= encodedContent.replace(/&/g,"%26");
        encodedContent= encodedContent.replace(/@/g,"%40");

        var body = "fieldName=" + escape(elem.id) + "&content=" + encodedContent;
        if (this.get_otherVars() != "")
            body = body + "&" + this.get_otherVars();
            
        webRequest.set_body(body);
        webRequest.get_headers()["Content-Length"] = body.length;
         
        // Set the web request completed event handler,
        // for processing return data.
        // Make sure to add the createDelegate so that the complete method will run
        // under the same context of this class instance, means being able to accesss
        // properties on this instance of the class
        webRequest.add_completed(Function.createDelegate(this, this.OnUpateStoreCompleted));
        
        // Execute the request.
        webRequest.invoke();  
    },

    // This the handler for the Web request completed event
    // that is used to display return data.
    OnUpateStoreCompleted: function(executor, eventArgs) 
    {
        if(executor.get_responseAvailable()) 
        {
            var result = executor.get_responseData();
            $get(this.get_uiElement()).innerHTML = result;
        }
        else
        {
            if (executor.get_timedOut())
                alert("Request Timed Out. Sorry for the inconvience");
            else
                if (executor.get_aborted())
                    alert("Request Aborted. sorry for the inconvience");
        }
    }
}

// Register the class
bhaidar.CodeSuite.AJAX.InlineEdit.registerClass("bhaidar.CodeSuite.AJAX.InlineEdit");

Sys.Application.notifyScriptLoaded();