Javascript Issue with IE 7 + 8 - javascript

So I've been trying to get this script working in IE 7 & 8. The lack of support for getElementsByClassName was difficult to say the least, but i have filled support for that with a jQuery library.
My issue here is that the code shows no errors in any browser, yet the code does not run properly in IE. I've tested this in FF, Chrome, and Safari. All other browsers work fine, excluding IE.
I know semantics wise the code could be smaller (Trust me when get it working i will fix that.) But for now i need to figure out what is holding up IE.
jQuery(document).ready(function() {
var forms = jQuery('.form_item');
var firstFader = forms[4].getElementsByTagName('input');
var secondFader = forms[6].getElementsByTagName('input');
jQuery(firstFader[0]).click(function() {
jQuery('#nearSighted').hide('slow');
jQuery('#farSighted').show('slow');
jQuery('#astigmatism').hide('slow');
});
jQuery(firstFader[1]).click(function() {
jQuery('#nearSighted').show('slow');
jQuery('#farSighted').hide('slow');
jQuery('#astigmatism').hide('slow');
});
jQuery(firstFader[2]).click(function() {
jQuery('#nearSighted').hide('slow');
jQuery('#farSighted').hide('slow');
jQuery('#astigmatism').show('slow');
});
jQuery(secondFader[2]).click(function() {
jQuery('#presbyopia').show('slow');
jQuery('#cataracts').hide('slow');
});
jQuery(secondFader[3]).click(function() {
jQuery('#presbyopia').hide('slow');
jQuery('#cataracts').show('slow');
});
});
What this code does is take an array of all form items, then breaks two specific ones down into their individual input elements, when one of the elements is clicked it hides or shows a div that contains information about that specific condition. Any ideas?

Your click handlers aren't being called because your <input>s are styled display:none, i.e. they're hidden. Modern browsers are lenient because they see a <label for="id"> so they fire the click event as though it were the input itself (see http://jsfiddle.net/MMUyA/).

var firstFader = forms[4].getElementsByTagName('input')[0];
var secondFader = forms[6].getElementsByTagName('input')[0];

I see you're not actually clicking the input elements, but the label elements for those inputs.
It seems IE doesn't properly propagate the click event to the hidden input, therefor your .click() event never gets executed.
See also: IE - hidden radio button not checked when the corresponding label is clicked
The simple solution would to not bind the click() events to the input but to the label instead.

It looks to me like in IE7, the radio button input object has zero size and the label for it is what actually receives the click and displays the radio button. Perhaps you need to intercept clicks on the associated label in addition to the input field.

Related

How to detect rightclick + cut/delete/paste/undo in javascript?

In my JavaScript/jQuery code, I have a text field that I run an event when the text changes using the keyup event. However currently I only account for changes done using the keyboard.
Is there a way I can detect when a text field text changed because the user did a right click and clicked on cut or delete or paste or undo?
Note: This needs to work in IE9, and preferably Firefox and chrome, but definitely needs to work in IE9.
Thanks
jsFiddle Demo
Use jquery to bind an input event to the element like this:
$('#myInput').bind('input',function(){
//use this for the input element when input is made
var inputValue = this.value;//for example
});
As a start, this is not really the correct way to do it. But if you react on the mouseout event of a input you will most likely get it to behave the way you want.
$('#input').mouseout(function(){
if($('#input').is(":focus"))
console.log("Right-click");
});
Though it is to note that this might not work as well on textareas since they tend to be larger and the mouse might not be outside of it when the contextmenu has been clicked.
Note: Other than #Travis J that react to all interaction, this will (probably) only trigger an event on rightclick (and regular mouseout).

innerHTML ignores DOM changes for checkbox and radio input in IE8

I would like to get the updated DOM html string for the form elements (e.g. <input type="text">, <input type="radio">, <input type="radio">, <textarea>).
I found this question and I am trying to use the formhtml plugin written by gnarf:
jQuery html() in Firefox (uses .innerHTML) ignores DOM changes
The problem is that it works in Firefox and Chrome but only works partially in IE8 (I have not tested other versions).
If you open the following page in IE8, you can see there is a text box, some checkboxes and radios. Try entering some text and check the checkboxes and radios.
http://jsfiddle.net/e9j6j/1/
Then click on the 'Click' button.
You can see that no matter I am retrieving the html string through the innerHTML property of a native DOM object or by using the formhtml() function of the plugin. The html returned only reflects the changes in the value attribute of the textbox, you can never see the checked="checked" attributes in <input type="radio"> and <input type="checkbox"> even you have already checked them before clicking the button.
Why is this happening, and how I can make it work in IE?
Thanks in advance.
EDIT:
I am sorry. I made some mistakes in my question, now it has been rewritten.
EDIT:
The sample codes were created to demonstrate my problem but I made some mistakes. Both IE7 and IE8 do give expected results (I also did the tests again).
In my original codes, I do not directly use formhtml() function on the $('#div1') but rather clone it before using formhtml() like this:
alert($('#div1').clone().formhtml());
And on IE8 with jQuery 1.3.2, the returned html does not reflect the checked states of those checkboxes and radios, I never thought it would be the problem of the clone() function that's why when I created the sample codes, I did not clone it and so the actual problem failed to be demonstrated.
The updated sample codes are here (with jQuery version changed to 1.3.2):
http://jsfiddle.net/e9j6j/4/
This may show the problem of the clone() function on IE8 (I don't have IE8 right now, I will test it when I am home, I will report later).
EDIT:
I have just did the test. It's really the problem of clone() function in jQuery 1.3.2 on IE8. It fails to copy the states of checkboxes and radios. After changing it to jQuery 1.5.1. It works perfectly.
I tried the test case at http://jsfiddle.net/e9j6j/1/ on IE8 and IE7 and they worked for me.
Steps to replicate problem:
Load http://jsfiddle.net/e9j6j/1/ in IE browser.
Enter text in the text field, check first radio button, check first checkbox.
Press 'Click' button.
Expected result:
Both alerts show value on text field and 'checked' state on first radio & first checkbox.
Actual result:
As expected. However, bear in mind that IE's representation of the DOM means that checked="checked" is actually reported as CHECKED but it is correct.
UPDATED:
Added a test to ensure that the checked state can be copied to a new dom node:
$('#btn1').click(function() {
alert($('#div1').formhtml());
alert(document.getElementById('div1').innerHTML);
var div1 = $('#div1');
div1.clone().insertAfter(div1);
});
This creates another set of fields which retain the original input state.
View on jsfiddle.

Javascript - get the form if of current control location

I have a form and it has 4 input elements. if the user enters just two entries and clicks anywhere on the screen (out the form)...i would like to save the details..it is like auto-save.
I have id of my form..i want to compare with form id of the current control on the screen..so that i can ssave the data if both form ids are different..
could you please tell me how can i get the form id of current control location on screen (some times the control could be outside the forms..in that case form id of current cotrol location would null)... but how can i determine that in javascript.
please suggest...
Many Thanks in advance,
Jack.
That's an interesting question.
Well, if you didn't think a second (as I admittedly did), you would just hook on the blur event of the HTML <form> element in question.
<form onblur="autosave(this)">
However, the HTML <form> element doesn't support that event. Too bad.
I then thought about jQuery's new 1.4 focusout() event.
$('form').focusout(function() { autosave(this); });
Unfortunately that event get fired as well when you just jump (tab, click) to the next input field inside the same form. Not so nice, it'll probably be too expensive to autosave on every fieldjump. The same effect as with an $(':input').blur(function() { autosave(this.form); });.
I then tried the other way round using focusin():
$('form').focusin(function() {
$(this).addClass('focused');
});
$(':not(form)').focusin(function(e) {
if (!$(e.target).parents('form.focused').length) {
var form = $('form.focused').removeClass('focused');
autosave(form);
}
});
Strangely enough this works in IE only and not in the other browsers. It'll be another IE bug/quirk that focus is supported by all elements other than input elements.
Your best bet will probably be hooking on the click() event instead.
$('form').focusin(function() {
$(this).addClass('focused');
});
$(':not(form)').click(function(e) {
if (!$(e.target).parents('form.focused').length) {
var form = $('form.focused').removeClass('focused');
autosave(form);
}
});
This works fine. You can find here a live demo.
Note that I don't mean to push you jQuery (a JS library which insanely eases HTML DOM traversion and manipulation) through your throat or so, but I don't see nice ways in plain JavaScript to achieve this without writing 10 times as much as code here.

Unselect textbox on blur with jQuery in IE8

I'm trying to have the default behavior of a form select (or highlight) the text when you tab to the next input. I've had to add the .select() function on my password form fields for this to work in IE8. Is there an equivalent to the jquery .select() for deselecting text?
$("#MyTextBox").focus(function() {
$(this).select();
});
$("#MyTextBox").blur(function() {
// Deselect here
});
Not that I am aware, however this ought to work for you:
$(this).val($(this).val());
Here you set the value of the field to itself. the cursor should automatically be put on the end.
The posted answer by James Wiseman worked perfectly in IE8, but for me at least, didn't work in Firefox 3.6.x.
I appreciate that the original question is specific to IE8, however, to help out those searching for a single solution that works in FF and IE, I used the following code:
var temptext = $(textbox).val();
$(textbox).val('');
$(textbox).val(temptext);
(where textbox is the textbox object to work with).
It uses the same theory as James Wiseman's solution, however, it adds the specific step of setting the textbox's text to a blank string prior to setting the textbox text back to the original string. Hope this helps!

Problem getting selected text when using a sprited button and selection.createRange() in Internet Explorer

I'm working on implementing sprited buttons in Stackoverflow's beloved WMD markdown editor and I've run into an odd bug. On all versions of IE, the selected text is lost upon button clicks, so, say, highlighting a block of text and clicking the code button acts like you placed the cursor at the end of the selection and clicked the button.
e.g. highlighting this:
This
Is
Code
and clicking the code button give you:
This
Is
Code`enter code here`
What's really weird is that I left the original non-sprited button bar in and that works just fine. In fact ALL buttons and keyboard shortcuts code use the same doClick(button) function!
Old-style non-sprited buttons: OK
Keyboard shortcuts: OK
Sprited buttons in non-IE browsers: OK
Sprited buttons in IE: WTF
I've isolated the problem down to a call to selection.createRange() which finds nothing only when the sprited button is clicked. I've tried screwing around with focus()ing and making sure as little as possible happens before the doClick() but no joy. The keyboard shortcuts seem to work because the focus is never lost from the input textarea. Can anyone think of a hack that will let me somehow collect the selected text in IE?
The onclick handler looks like this:
button.onmouseout = function(){
this.style.backgroundPosition = this.XShift + " " + normalYShift;
};
button.onclick = function() {
if (this.onmouseout) {
this.onmouseout();
}
doClick(this);
}
I've tried moving the onmouseout call to after the doClick in case that was causing a loss of focus but that's not the problem.
EDIT:
The only thing that seems to be different is that, in the original button code, you are clicking on an image. In the sprited code, you are clicking on a list item <li> with a background image set. Perhaps it's trying to select the non-existent text in my list item?
/EDIT
Actual code is located in my wmd repository on git in the button-cleanup branch.
If you revert to the 0d6d1b32bb42a6bd1d4ac4e409a19fdfe8f1ffcc commit you can see both button bars. The top one is sprited and exhibits the weird behavior. The bottom one contains the remnants of the original button bar and works fine. The suspect code is in the setInputAreaSelectionStartEnd() function in the TextareaState object.
One last thing I should mention is that, for the time being, I'm trying to keep the control in pure Javascript so I'd like to avoid fixing this with an external library like jQuery if that's possible.
Thanks for your help!
I know what the answer to my own question is.
The sprited buttons are implemented using an HTML list and CSS, where all the list items have a background image. The background image is moved around using CSS to show different buttons and states (like mouseover highlights). Standard CSS button spriting stuff.
This works fine in IE with one exception: IE tries to select the empty list text when you click on the background image "button". The selection in the input textarea goes away and the current selection (which will be returned by document.selection.createRange()) is moved to the empty text in the list item.
The fix for this is simple - I created a variable to cache the selection and a flag. In IE I cache the selection and set the flag in a mousedown event handler. In the text processing, I check for the presence of the flag - if it's set I use the cached range instead of querying document.selection.createRange().
Here are some code snippets:
wmd.ieCachedRange = null;
wmd.ieRetardedClick = false;
if(global.isIE) {
button.onmousedown = function() {
wmd.ieRetardedClick = true;
wmd.ieCachedRange = document.selection.createRange();
};
}
var range;
if(wmd.ieRetardedClick && wmd.ieCachedRange) {
range = wmd.ieCachedRange;
wmd.ieRetardedClick = false;
}
else {
range = doc.selection.createRange();
}
The solution is only a few lines of code and avoids messing around with the DOM and potentially creating layout engine issues.
Thanks for your help, Cristoph. I came up with the answer while thinking and googling about your answer.
You have to blur() a button before IE can select anything else on a page.
Can you provide a minimal example (only containing relevant code) which reproduces the bug?

Categories