[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

conflicting javascripts

Posted on 2009-04-01
4
Medium Priority
?
1,361 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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 …
This article discusses how to implement server side field validation and display customized error messages to the client.
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…

656 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