Solved

conflicting javascripts

Posted on 2009-04-01
4
1,348 Views
Last Modified: 2012-05-06
Hi all,
i have been using a javascript on my site called maxheight.js (see below). all was fine until i found another couple of scripts that deal with having max characters echo'd out for textareas.
The 2 scripts i found that deal with telling the end user how many characters left they have to type are:
textarea_maxlen.js (see below)
behaviour.js (see below)

The below basic html code makes a text area with the character left being printer as you type using the above 2 scripts.
When i add the new ElementMaxHeight() to the body tag from the maxheight.js the character read out feature stops working.
<body onload="new ElementMaxHeight();">

something is conflicting within the 2 scripts but i cannot see what. i didnt create the attached scripts.

Hope somone can help.

Thanks
// maxheight.js

////////////////////////////////////

var ElementMaxHeight = function() {

  this.initialize.apply(this, arguments);

}
 

ElementMaxHeight.prototype = {

  initialize: function(className) {

    this.elements = document.getElementsByClassName(className || 'maxheight');    

    this.textElement = document.createElement('span');

    this.textElement.appendChild(document.createTextNode('A'));

    this.textElement.style.display = 'block';

    this.textElement.style.position = 'absolute';

    this.textElement.style.fontSize = '1em';

    this.textElement.style.top = '-1000px';

    this.textElement.style.left = '-1000px';

    document.body.appendChild(this.textElement);

    this.textElementHeight = document.getDimensions(this.textElement).height;

    var __object = this;

    var __checkFontSize = this.checkFontSize;

    this.checkFontSizeInterval = window.setInterval(function() {return __checkFontSize.apply(__object)}, 500);
 

    this.expand();
 

    // Refresh elements height onResize event

    var __expand = this.expand;

    if (window.addEventListener) {

      window.addEventListener('resize', function(event) {return __expand.apply(__object, [( event || window.event)])}, false);

    } else if (window.attachEvent) {

      window.attachEvent('onresize', function(event) {return __expand.apply(__object, [( event || window.event)])});

    }

  },
 

  expand: function() {

    this.reset();

  	for (var i = 0; i < this.elements.length; i++) {  	

      this.elements[i].style.height = document.getDimensions(this.elements[i].parentNode).height + 'px';

  	}

  },
 

  reset: function() {

    for (var i = 0; i < this.elements.length; i++) {    

      this.elements[i].style.height = 'auto';

    }

  },
 

  checkFontSize: function() {

  	var height = document.getDimensions(this.textElement).height;

  	if(this.textElementHeight != height) {

  		this.textElementHeight = height;

  		this.expand();

  	}

  }  

}
 
 

if (!!document.evaluate) {

  document._getElementsByXPath = function(expression, parentElement) {

    var results = [];

    var query = document.evaluate(expression, parentElement || document,

      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    for (var i = 0, length = query.snapshotLength; i < length; i++)

      results.push(query.snapshotItem(i));

    return results;

  }

}
 

document.getElementsByClassName = function(className, parentElement) {

  if (!!document.evaluate) {

    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";

    return document._getElementsByXPath(q, parentElement);

  } else {

    var children = (parentElement || document.body).getElementsByTagName('*');

    var elements = [], child;

    for (var i = 0, length = children.length; i < length; i++) {

      child = children[i];

      if (child.className.length != 0 &&

          (child.className == className ||

           child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))) {      

        elements.push(child);

      }

    }

    return elements;

  }

}
 

document.getDimensions = function (element) {

  var display = element.style.display;

  if (display != 'none' && display != null) { // Safari bug

    return {width: element.offsetWidth, height: element.offsetHeight};

  }
 

  return {width: originalWidth, height: originalHeight};

}
 
 
 

////////////////////////////////////////

// textarea_maxlen.js

///////////////////////////////////////

var CSSrules = {

    'textarea' : function(element){

            element.onkeydown = function(event){

                return doKeyPress(element,event);

            }

            ,

            element.onpaste = function(){

                return doPaste(element);

            }

            ,

            element.onkeyup = function(){

                return doKeyUp(element);

            }

            ,

            element.onblur = function(){

                return doKeyUp(element);

            }

    }

}
 

Behaviour.register(CSSrules);
 

var detect = navigator.userAgent.toLowerCase();
 

// Keep user from entering more than maxLength characters

function doKeyPress(obj,evt){

    maxLength = obj.getAttribute("maxlength");

    var e = window.event ? event.keyCode : evt.which;

    if ( (e == 32) || (e == 13) || (e > 47)) { //IE

        if(maxLength && (obj.value.length > maxLength-1)) {

            if (window.event) {

                window.event.returnValue = null;

            } else {

                evt.cancelDefault;

                return false;

            }

        }

    }

}

function doKeyUp(obj){

    maxLength = obj.getAttribute("maxlength");

     if(maxLength && obj.value.length > maxLength){

           obj.value = obj.value.substr(0,maxLength);

     }

    sr = obj.getAttribute("showremain");

    if (sr) {

        document.getElementById(sr).innerHTML = maxLength-obj.value.length;

    }

}
 

// Cancel default behavior and create a new paste routine

function doPaste(obj){

maxLength = obj.getAttribute("maxlength");

     if(maxLength){

        if ((window.event) && (detect.indexOf("safari") + 1 == 0)) { //IE

          var oTR = obj.document.selection.createRange();

          var iInsertLength = maxLength - obj.value.length + oTR.text.length;

          try {

          var sData = window.clipboardData.getData("Text").substr(0,iInsertLength);

          oTR.text = sData;

          }

          catch (err) {

          }

          if (window.event) { //IE

            window.event.returnValue = null;

     } else {

            //not IE

            obj.value = obj.value.substr(0,maxLength);

            return false;

        }

        }

     }

}
 
 
 

//////////////////////////////////////////////

// behaviour.js

/////////////////////////////////////////////
 

/*

   Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work

   of Simon Willison (see comments by Simon below).
 

   Description:

   	

   	Uses css selectors to apply javascript behaviours to enable

   	unobtrusive javascript in html documents.

   	

   Usage:   

   

	var myrules = {

		'b.someclass' : function(element){

			element.onclick = function(){

				alert(this.innerHTML);

			}

		},

		'#someid u' : function(element){

			element.onmouseover = function(){

				this.innerHTML = "BLAH!";

			}

		}

	};

	

	Behaviour.register(myrules);

	

	// Call Behaviour.apply() to re-apply the rules (if you

	// update the dom, etc).
 

   License:

   

   	This file is entirely BSD licensed.

   	

   More information:

   	

   	http://ripcord.co.nz/behaviour/

   

*/   
 

var Behaviour = {

	list : new Array,

	

	register : function(sheet){

		Behaviour.list.push(sheet);

	},

	

	start : function(){

		Behaviour.addLoadEvent(function(){

			Behaviour.apply();

		});

	},

	

	apply : function(){

		for (h=0;sheet=Behaviour.list[h];h++){

			for (selector in sheet){

				list = document.getElementsBySelector(selector);

				

				if (!list){

					continue;

				}
 

				for (i=0;element=list[i];i++){

					sheet[selector](element);

				}

			}

		}

	},

	

	addLoadEvent : function(func){

		var oldonload = window.onload;

		

		if (typeof window.onload != 'function') {

			window.onload = func;

		} else {

			window.onload = function() {

				oldonload();

				func();

			}

		}

	}

}
 

Behaviour.start();
 

/*

   The following code is Copyright (C) Simon Willison 2004.
 

   document.getElementsBySelector(selector)

   - returns an array of element objects from the current document

     matching the CSS selector. Selectors can contain element names, 

     class names and ids and can be nested. For example:

     

       elements = document.getElementsBySelect('div#main p a.external')

     

     Will return an array of all 'a' elements with 'external' in their 

     class attribute that are contained inside 'p' elements that are 

     contained inside the 'div' element which has id="main"
 

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:

   See http://www.w3.org/TR/css3-selectors/#attribute-selectors
 

   Version 0.4 - Simon Willison, March 25th 2003

   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows

   -- Opera 7 fails 

*/
 

function getAllChildren(e) {

  // Returns all children of element. Workaround required for IE5/Windows. Ugh.

  return e.all ? e.all : e.getElementsByTagName('*');

}
 

document.getElementsBySelector = function(selector) {

  // Attempt to fail gracefully in lesser browsers

  if (!document.getElementsByTagName) {

    return new Array();

  }

  // Split selector in to tokens

  var tokens = selector.split(' ');

  var currentContext = new Array(document);

  for (var i = 0; i < tokens.length; i++) {

    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;

    if (token.indexOf('#') > -1) {

      // Token is an ID selector

      var bits = token.split('#');

      var tagName = bits[0];

      var id = bits[1];

      var element = document.getElementById(id);

      if (tagName && element.nodeName.toLowerCase() != tagName) {

        // tag with that ID not found, return false

        return new Array();

      }

      // Set currentContext to contain just this element

      currentContext = new Array(element);

      continue; // Skip to next token

    }

    if (token.indexOf('.') > -1) {

      // Token contains a class selector

      var bits = token.split('.');

      var tagName = bits[0];

      var className = bits[1];

      if (!tagName) {

        tagName = '*';

      }

      // Get elements matching tag, filter them for class selector

      var found = new Array;

      var foundCount = 0;

      for (var h = 0; h < currentContext.length; h++) {

        var elements;

        if (tagName == '*') {

            elements = getAllChildren(currentContext[h]);

        } else {

            elements = currentContext[h].getElementsByTagName(tagName);

        }

        for (var j = 0; j < elements.length; j++) {

          found[foundCount++] = elements[j];

        }

      }

      currentContext = new Array;

      var currentContextIndex = 0;

      for (var k = 0; k < found.length; k++) {

        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {

          currentContext[currentContextIndex++] = found[k];

        }

      }

      continue; // Skip to next token

    }

    // Code to deal with attribute selectors

    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {

      var tagName = RegExp.$1;

      var attrName = RegExp.$2;

      var attrOperator = RegExp.$3;

      var attrValue = RegExp.$4;

      if (!tagName) {

        tagName = '*';

      }

      // Grab all of the tagName elements within current context

      var found = new Array;

      var foundCount = 0;

      for (var h = 0; h < currentContext.length; h++) {

        var elements;

        if (tagName == '*') {

            elements = getAllChildren(currentContext[h]);

        } else {

            elements = currentContext[h].getElementsByTagName(tagName);

        }

        for (var j = 0; j < elements.length; j++) {

          found[foundCount++] = elements[j];

        }

      }

      currentContext = new Array;

      var currentContextIndex = 0;

      var checkFunction; // This function will be used to filter the elements

      switch (attrOperator) {

        case '=': // Equality

          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };

          break;

        case '~': // Match one of space seperated words 

          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };

          break;

        case '|': // Match start with value followed by optional hyphen

          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };

          break;

        case '^': // Match starts with value

          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };

          break;

        case '$': // Match ends with value - fails with "Warning" in Opera 7

          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };

          break;

        case '*': // Match ends with value

          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };

          break;

        default :

          // Just test for existence of attribute

          checkFunction = function(e) { return e.getAttribute(attrName); };

      }

      currentContext = new Array;

      var currentContextIndex = 0;

      for (var k = 0; k < found.length; k++) {

        if (checkFunction(found[k])) {

          currentContext[currentContextIndex++] = found[k];

        }

      }

      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);

      continue; // Skip to next token

    }

    

    if (!currentContext[0]){

    	return;

    }

    

    // If we get here, token is JUST an element (not a class or ID selector)

    tagName = token;

    var found = new Array;

    var foundCount = 0;

    for (var h = 0; h < currentContext.length; h++) {

      var elements = currentContext[h].getElementsByTagName(tagName);

      for (var j = 0; j < elements.length; j++) {

        found[foundCount++] = elements[j];

      }

    }

    currentContext = found;

  }

  return currentContext;

}
 

/* That revolting regular expression explained 

/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/

  \---/  \---/\-------------/    \-------/

    |      |         |               |

    |      |         |           The value

    |      |    ~,|,^,$,* or =

    |   Attribute 

   Tag

*/
 
 
 

//////////////////////////////////

Basic HTML code for text area character read out

<html>

<head>

<script type="text/javascript" src="/scripts/behaviour.js"></script>

<script type="text/javascript" src="/scripts/textarea_maxlen.js"></script>

</head>

<body>
 

<p>Limit 120 Characters: <TEXTAREA rows="5" cols="30" maxlength="120" showremain="limitOne"></TEXTAREA> 

<br>Chars Remaining:<span id="limitOne">--</span></p>
 

<p>Limit 50 Characters: <TEXTAREA rows="2" cols="30" maxlength="50" showremain="limitTwo"></TEXTAREA> 

<br>Chars Remaining:<span id="limitTwo">--</span></p>
 

</body>

</html>

Open in new window

0
Comment
Question by:satmanuk
  • 2
  • 2
4 Comments
 
LVL 12

Expert Comment

by:alien109
ID: 24045723
The conflict is with overwriting the windows onload event. When the behavior js loads, it assigns a callback to the event. Then when textarea_maxlen loads, it overwrites behaviors event.

Rather than using the onload=... on the body, try using Behaviors addLoadEvent function.


<html>

<head>

<script type="text/javascript" src="/scripts/behaviour.js"></script>

<script type="text/javascript" src="/scripts/textarea_maxlen.js"></script>

<script type="text/javascript">

Behaviour.addLoadEvent(function() {new ElementMaxHeight();});

</script>
 
 

</head>
 

<body>

<p>Limit 120 Characters: <TEXTAREA rows="5" cols="30" maxlength="120" showremain="limitOne"></TEXTAREA>

<br>Chars Remaining:<span id="limitOne">--</span></p>
 

<p>Limit 50 Characters: <TEXTAREA rows="2" cols="30" maxlength="50" showremain="limitTwo"></TEXTAREA>

<br>Chars Remaining:<span id="limitTwo">--</span></p>
 

</body>

</html>

Open in new window

0
 
LVL 1

Author Comment

by:satmanuk
ID: 24054936
hi thanks for the reply,

i have tried your code but the element that gives max height to the content on my site no longer works.

To clarify i have changed the code below.

the javascript for the character remaining works but the body element doesnt.

Thanks


<script src="maxheight.js" type="text/javascript"></script>

<script type="text/javascript" src="behaviour.js"></script>

<script type="text/javascript" src="textarea_maxlen.js"></script>

</head>

<body onload="new ElementMaxHeight();">
 

into
 

<script type="text/javascript">

Behaviour.addLoadEvent(function() {new ElementMaxHeight();});

</script>
 

<script type="text/javascript" src="behaviour.js"></script>

<script type="text/javascript" src="textarea_maxlen.js"></script>
 

</head>

<body>

Open in new window

0
 
LVL 12

Accepted Solution

by:
alien109 earned 500 total points
ID: 24063419
<script type="text/javascript">
Behaviour.addLoadEvent(function() {new ElementMaxHeight();});
</script>

needs to come after

<script type="text/javascript" src="behaviour.js"></script>
<script type="text/javascript" src="textarea_maxlen.js"></script>

You can't reference ElementMaxHeight, before the script has been read.
0
 
LVL 1

Author Comment

by:satmanuk
ID: 24066770
Hi thanks,

i tried that but the maxheight still breaks. before i implimented the script for char left on the text area any columns that have maxheight worked fine.

Now they dont?

i want to post the whole page but i had issues when i did that before. maybe i can knock up a demo page with the same functionality so i can post it.

thanks for your help.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, we'll look how to sort an Array in JavaScript, including the more advanced techniques of sorting a collection of records either ascending or descending on two or more fields. Basic Sorting of Arrays First, let's look at the …
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now