Add options to select box without Internet Explorer closing the box? - javascript

I'm trying to build a web page with a number of drop-down select boxes that load their options asynchronously when the box is first opened. This works very well under Firefox, but not under Internet Explorer.
Below is a small example of what I'm trying to achieve. Basically, there is a select box (with the id "selectBox"), which contains just one option ("Any"). Then there is an onmousedown handler that loads the other options when the box is clicked.
<html>
<head>
<script type="text/javascript">
function appendOption(select,option) {
try {
selectBox.add(option,null); // Standards compliant.
} catch (e) {
selectBox.add(option); // IE only version.
}
}
function loadOptions() {
// Simulate an AJAX request that will call the
// loadOptionsCallback function after 500ms.
setTimeout(loadOptionsCallback,500);
}
function loadOptionsCallback() {
var selectBox = document.getElementById('selectBox');
var option = document.createElement('option');
option.text = 'new option';
appendOption(selectBox,option);
}
</script>
</head>
<body>
<select id="selectBox" onmousedown="loadOptions();">
<option>Any</option>
</select>
</body>
</html>
The desired behavior (which Firefox does) is:
the user see's a closed select box containing "Any".
the user clicks on the select box.
the select box opens to reveal the one and only option ("Any").
500ms later (or when the AJAX call has returned) the dropped-down list expands to include the new options (hard coded to 'new option' in this example).
So that's exactly what Firefox does, which is great. However, in Internet Explorer, as soon as the new option is added in "4" the browser closes the select box. The select box does contain the correct options, but the box is closed, requiring the user to click to re-open it.
So, does anyone have any suggestions for how I can load the select control's options asynchronously without IE closing the drop-down box?
I know that I can load the list before the box is even clicked, but the real form I'm developing contains many such select boxes, which are all interrelated, so it will be much better for both the client and server if I can load each set of options only when needed.
Also, if the results are loaded synchronously, before the select box's onmousedown handler completes, then IE will show the full list as expected - however, synchronous loading is a bad idea here, since it will completely "lock" the browser while the network requests are taking place.
Finally, I've also tried using IE's click() method to open the select box once the new options have been added, but that does not re-open the select box.
Any ideas or suggestions would be really appreciated!! :)
Thanks!
Paul.

Have you considered calling the loadOptions method in the onblur event of one of the other interrelated fields on the form? This would load the list into the drop down box before it is clicked, but the behavior should still be similar.
I think you are going to have explore slightly different options to obtain what you want as you are probably stuck with Internet Explorer closing that drop down list if you use the onmousedown or onclick events. Another downside to using those events is if the user uses the keyboard to select the fields, your method may never get called.

I would suggest to load the contents of the selects that don't depend on any other select boxes on page load. Then in the onchange event of those selects load the contents of the rest of the selects that depend on them.
Your idea is sound from a programming point of view, but you will get that lag between clicking on the select and it being populated with all the options which from the user's point of view looks kind of sloppy.

I found a solution to this, the problem seems to lie in IE's implementation of onclick, hover, mouseover etc. After the items are added to the dropdown, the dropdown closes. If you instead of providing the method in the select attribute, let jquery add the function at runtime it works.
$(function() {
jQuery(".selectBox").live("focus", function() {
loadOptions();
});
});
The whole page:
<html>
<head>
<script src="jquery-latest.js" type="text/javascript"/>
</head>
<body>
<select id="selectBox" onmousedown="loadOptions();">
<option>Any</option>
</select>
<script type="text/javascript">
$(function() {
jQuery(".selectBox").live("focus", function() {
loadOptions();
});
});
function appendOption(select, option) {
try {
selectBox.add(option, null); // Standards compliant.
} catch (e) {
selectBox.add(option); // IE only version.
}
}
function loadOptions() {
// Simulate an AJAX request that will call the
// loadOptionsCallback function after 500ms.
setTimeout(loadOptionsCallback, 500);
}
function loadOptionsCallback() {
var selectBox = document.getElementById('selectBox');
var option = document.createElement('option');
option.text = 'new option';
appendOption(selectBox, option);
}
</script>
</body>

Related

Tab order on prompt page

Using Cognos Analtyics 11.1.7IF9.
I have a user who, oddly enough, wants Cognos to make his workflow more efficient. (The nerve!) He thinks that if he can use the TAB button to navigate a prompt page, he'll be faster because he never needs to reach for the mouse.
To test this I created a simple report with a very simple prompt page using only textbox prompts. As I tab I notice it tabs to everything in the browser: browser tabs, the address bar, other objects in Cognos, ...even the labels (text items) I created for the prompts. Oh... and yes, at some point focus lands on a prompt control.
Within Cognos, I see that the tab order generally appears to be from the top down. (I haven't tried multiple columns of prompts in a table yet.) I must tab through the visual elements between the prompts. Also, while value prompts get focus, there is no visible indication of this.
Is there a way to set the tab order for the prompts on a prompt page?
Can I force it to skip the non-prompt elements?
Can the prompts be made to indicate that they have focus?
I tagged this question with javascript because I figure the answer will likely involve a Custom Control or a Page Module.
Of course, then I'll need to figure out how all this will work with cascading prompts and conditional blocks.
I found a similar post complaining about this being a problem in Cognos 8. The answer contains no detail. It just says to go to a non-existent web page.
I had the same frustration as your user and I made a solution a while back that could work for you. It's not the most elegant javascript and I get a weird error in the console but functionally it works so I haven't needed to fix it.
I created a custom control script that does 2 things on a prompt page.
First, it removes the ability to "select" text item elements on the page. If you only have text items and prompts on the page it sets it's "Tabindex" to "-1". This allows you to tab from one prompt field to the next without it selecting invisible elements or text elements between prompts.
Secondly, if you press "Enter" on the keyboard it automatically submits the form. I am pasting the code below which you can save as a .js and call it in a custom control on a prompt page. Set the UI Type to "None"
define( function() {
"use strict";
function AdvancedControl()
{
};
AdvancedControl.prototype.initialize = function( oControlHost, fnDoneInitializing )
{
function enterSubmit (e)
{
if(e.keyCode === 13)
{
try {oControlHost.finish();} catch {}
}
};
function setTab () {
let nL = [...document.querySelectorAll("[specname=textItem]")]
//console.log(nL)
nL.forEach((node) =>{
node.setAttribute('tabindex','-1')
})
};
setTab();
let exec_submit = document.addEventListener("keydown", enterSubmit, false);
try {exec_submit;} catch {}
fnDoneInitializing();
};
return AdvancedControl;
});

Keyup not firing in IE but working in Chrome

I have the below code with which I am basically syncing textbox value changes across various fields sharing the same class name. The issue is that this is not working in IE but working in Chrome. Can some please have a look and let me know what I am missing here.
My scenario : I have two tabs where I have textboxes..Initially the second tab is hidden and when user saves the page the without postback the second tab becomes available. So the second tab has textbox which when becomes visible is not being bound to the change event. If I refresh the whole page then the sync is working fine.
$(document).ready(function () {
$(".txtDateFrom").keyup(function () {
$(".txtDateFrom").val($(this).val());
});
});
Thanks

Simulate Mouse Click on dropdown

My Wordpress theme interacts with WooCommerce so that when a user selects a specific product variable from a drop-down a particular price is shown for their region.
This works fine when a user manually selects the drop-down, however, I'm trying to speed up the process by pre-selecting the appropriate option for the user based on a browser cookie (or lack of one).
For instance, if the user hasn't entered their region their browser will not have a cookie I've named "pc-entered" and the following jQuery script will run:
$(function() {
$('ul li.product').each( function() {
/*If no region set by cookie*/
if( document.cookie.indexOf("pc-entered=") < 0) {
/*Set downdown to generic*/
$(this).find("#pa_region").val('generic');
}
});
});
This works, successfully pre-selecting the correct 'generic' dropdown option automatically.
Unfortunately, and this is where I'm stuck - although the dropdown is correct the price isn't auto-populating like it does when a user manually selects their region.
E.g.
1) When auto-populated using my script:
2) When user selected:
I've tried replacing this in my script:
$(this).find("#pa_region").val('generic');
With the options listed on this thread, however, they don't seem to work in this case. I've also tried firing the script after all other scripts on the page and even delaying the script running with a timeout function but nothing seems to be working.
My test site is here.
TLDR - Why is my jQuery script not populating the price?
With $(this).find("#pa_region").val('generic'); you are only changing the HTML value (text) of dropdown.
You need to attach the event handler which will trigger the change to the function where you change the value.
function changeValue(){
$("#pa_region").val('generic');
$("#pa_region").trigger('change');
}
$( "#pa_region" ).change(function() {
console.log( "Handler for .change() called." );
});
This is the way on how to solve it.
I also made a JSFiddle so you can test it.

How to add history to jQuery UI tabs using a back button

I've got a PHP file with 5 tabs (jquery ui). Tab four and five contain
forms. Forms and tab work fine - expect to this: I submit the form (POST
method not XHR), then click the right mouse button (Firefox and IE behave
identical) and select back and then select tab five in the page by mouse
click the entered form data is still available.
I try to build a link, that is more convenient for the user.
<a href="#" onClick='history.back();$("#tabs").tabs("select","4");'>modify</a>
If click on my modify link, it still jumps back to tab one and the form fields in tab five are empty.
I read several posts about jQuery UI tabs and the back button, but all seem not to address my problem.
Where is my fault and is the difference between doing this steps by hand and my link with JS?
Javascript stops executing once you leave the page that it's running on -- the second half of your onClick handler never runs.
Following from the comments here is a function that will remember what your last tab was that you selected. It does rely on you using a set "Back" button.
The problem you will find, as far as I can see, is that you can't intercept a user clicking the browser back button. I have found that creating an obvious and clear back button on the site does the job and the feedback I have had so far on our sites seem to back that up.
The function is:
$(function() {
var $previousTab = 0;
var $backButtonUsed = false;
// Initialise tabs
$("#tabs").tabs();
$("#tabs").bind("tabsselect", function(event, ui) {
if ($backButtonUsed)
{
$backButtonUsed = false;
} else {
$previousTab = $("#tabs").tabs('option', 'selected');
}
return true;
});
$("#back").live('click', function() {
$backButtonUsed = true;
$("#tabs").tabs({ selected: $previousTab });
return true;
});
});​
I have also included this in a JSFiddle, so you can see it in action with the HTML and jQuery UI Tabs.
Let me know what you think.

Why doesn't this code work the whole time?

I have this javascript code:
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0)
{
$(window).load(function()
{
$('input:-webkit-autofill').each(function()
{
var text = $(this).val();
var name = $(this).attr('name');
$(this).after(this.outerHTML).remove();
$('input[name=' + name + ']').val(text);
});
});
}
It is designed to remove the background color of the webkit autofill background color in inputs.
However, it only works sometimes and doesn't work when I click on an input, or a button that executes jQuery async functions at around the same time that the page loads.
What is wrong with this code that makes it not work sometimes, but work other times? What must I adapt?
This is what I am doing: How do you disable browser Autocomplete on web form field / input tag?
But I want to keep autocomplete on, while removing the background. I need this, as the background goes over a background image in my text input, so you can't see it.
Is this what you're attempting? How do you disable browser Autocomplete on web form field / input tag?
if not--
Can you confirm that all the elements are being selected, and that the problem lies in the timing of the browser's autofill? What happens if you use the more common $.ready instead?

Categories