SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Addict skunkbad's Avatar
    Join Date
    Apr 2008
    Location
    Temecula, CA
    Posts
    272
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    IE7 and IE8 not liking my clone/replace of form input

    I'm trying to do a simple click event on a checkbox that shows/hides the password in a form. It works in FF and IE9, but IE7 and IE8 are not cooperating. I get the following error in the IE console:

    SCRIPT5022: Exception thrown and not caught
    jquery-1.6.2.js, line 548 character 3

    This is using the non-minified version of jquery 1.6.2

    Code is super simple:
    Code:
    $(document).ready(function(){
    
    	// Allow the password to be seen as plain text if desired
    	$('#passcheck').click(function(e){
    		$('.form_input').each( function(i, el){
    			var new_input = $(el).clone();
    			if( new_input.attr('type') == 'text' ){
    				new_input.attr('type', 'password');
    			}else{
    				new_input.attr('type', 'text');
    			}
    			$(el).replaceWith(new_input);
    		});
    	});
    
    });
    I know some of you are javascript gurus and can probably tell me what's wrong instantly. I've been working on this for hours, so I'd really appreciate your help!

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    While it seems to work fine in Firefox/Chrome/IE9 etc, it certainly does fall over in IE7. I have a theory that perhaps IE6/7 don't allow you to change the type attribute of an input element. (Don't quote me on that though...)

    I just did a quick test to confirm my suspicion. I ran the below code:

    Code HTML4Strict:
    <!DOCTYPE html>
    <html>
    <head>
    	<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    	<script type="text/javascript">
    	$(document).ready(function(){
    		$("#btn").click(function(){
    			var new_input = $("#pass").clone();
    			if( new_input.attr('type') == 'text' ){
    				new_input.attr('type', 'password');
    			}else{
    				new_input.attr('type', 'text');
    			}
    			$("#pass").replaceWith(new_input)
    		});
    	});
    	</script>	
    </head>
    <body>
    	Pass: <input type="password" id="pass" ><br>
    	Text: <input type="text" id="txt"><br>
    	<button id="btn" value="Button">Button</button>
    </body>
    </html>

    This works fine in modern browsers, but IE6/7 has a problem with it. The apparent solution would be to construct a completely new input dynamically based on the current attributes that it has.

    For example, replace the JavaScript from the code above and run the code, you'll see that it works in the modern browsers as well as IE7 (and presumably 6, I haven't tested this though).

    Code JavaScript:
    $(document).ready(function(){
    	$("#btn").click(function(){
    		var $input = $("#pass"),
    			inputType = $input.attr("type"),
    			inputId = $input.attr("id"),
    			inputVal = $input.val();
     
    		if( inputType == 'text' ){
    			newType = "password"
    		}else{
    			newType = "text"
    		}
    		$("#pass").replaceWith("<input type='"+newType+"' id='"+inputId+"' value='"+inputVal+"'>");
    	});
    });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    SitePoint Addict skunkbad's Avatar
    Join Date
    Apr 2008
    Location
    Temecula, CA
    Posts
    272
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I went around in circles with this for hours... and finally came up with this, which works in all browsers:

    Code JavaScript:
    $(document).ready(function(){
    	// Allow the password to be seen as plain text if desired
    	$('#see_pass').click(function(e){
    		$('#new_pass, #new_pass_conf').each( function(i, el){
    			// Get the value
    			var current_password = $(el).val();
    			// Get the type
    			var current_type = $(el).attr('type');
    			// Get the ID
    			var current_id = $(el).attr('id');
    			// determine the replacement
    			if( current_type == 'text' ){
    				var replacement = '<input id="' + current_id + '" type="password" value="' + current_password + '" class="form_input"/>';
    			}else{
    				var replacement = '<input id="' + current_id + '" type="text" value="' + current_password + '" class="form_input"/>';
    			}
    			// Remove the element
    			$(el).remove();
    			// Do the replacement
    			$('#' + current_id + '_div').append( replacement );
    		});
    	});
    });

    It may look clunky, but it gets the job done!

    By the way, thanks for an alternative solution. I tried it, but for some reason it was causing the fieldset to have a display issue.
    Last edited by skunkbad; Aug 12, 2011 at 21:47. Reason: To say thanks

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    Glad to see you got it going.

    A note about your comments though. When comments are used to explain what the code is doing, such comments are not considered to be useful.

    Code:
    // Remove the element
    $(el).remove();
    Instead of explaining what your code does, comments are more more useful when used to explain why things are happening.

    Code javascript:
    // Allow the password to be seen as plain text if desired
    $('#see_pass').click(function(e){
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •