Solved

conflicting javascripts

Posted on 2009-04-01
4
1,344 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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

I've been trying to accomplish this for a while and it just struck me yesterday how to accomplish this task. I have done searches all over the internet looking for ways to email pages from my applications and finally I have done it!!! Every single s…
The task A number given should be formatted for easy reading by separating digits into triads. Format must be made inline via JavaScript, i.e., frameworks / functions are not welcome. So let’s take a number like this “12345678.91¿ and format i…
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…

707 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

13 Experts available now in Live!

Get 1:1 Help Now