dynamically generated select / options empty in IE but OK in other browsers - javascript

I'm generating a 'select' element then populating it with options and inserting it into the DOM of my page. Everything's fine in FF, Chrome, Chromium etc. but in IE no options show in the drop-down list but highlights show under the cursor and when I click in the blank list the event handler gets triggered and processes correctly.
Here's the relevant HTML area:
<span id="spn_fyear" style="position:absolute; top:7px; left:200px; height:24px; cursor:pointer; color:#000000;" onclick="spn_fyear_onclick(this)">
<span id="spn_fyearno" style="position:absolute; top:0px; font:italic bold 17px sans-serif; color:#FFFEF2;"><?=$thisPage->getVar('start_year')?></span>
</span>
and here's the javascript in question:
function spn_fyear_onclick(_obj)
{
//make start year list
var lstto = document.getElementById('lst_year');
var topts = new Array();
var nopt = null;
for(i=0; i<lstto.options.length; i++)
{
topts[i] = lstto.options[i].text;
}
var lstf = document.createElement('SELECT');
lstf.id = "lst_fyear";
lstf.style.position = "absolute";
lstf.style.top = "-3px";
lstf.style.left = "1px";
lstf.style.fontFamily = "sans-serif";
lstf.style.fontWeight = "normal";
lstf.style.fontSize = "12px ";
lstf.style.width = "55px";
lstf.style.color = "#000000";
lstf.style.display = "inline";
lstf.onchange = lst_fyear_onchange;
for(i = 0; i < topts.length; i++)
{
if(topts[i] != 'undefined')
{
nopt = document.createElement('OPTION');
nopt.text = topts[i];
nopt.value = topts[i];
lstf.appendChild(nopt);
}
}
document.getElementById('spn_fyear').appendChild(lstf);
}
In this line: var lstto = document.getElementById('lst_year')
I'm creating a reference to an existing select object from which I copy the option data. lst_year gets populated by a php database query when the page first loads. I created the array (var topts = new Array()) in desperation in case IE has a quirk which copies attributes and properties but to no avail. Like I said - everything works like a dream in FF or Chrome both in Linux and Windoze but falls in a heap with IE. I've scoured MSDN etc. for some obscure behaviour but I'm stumped. Any suggestions would be greatly appreciated :)
Kind regards,
Jen

Most likely, your problem is here:
nopt = document.createElement('OPTION');
Try this method mentioned here:
JavaScript: add extra attribute after new Option()
(I've had a lot of problem with <option> elements and IE before until I started using the new Option constructor.

Related

Javascript InnerText, setAttributes not working only on iphones

let thankYouMain = document.querySelector(".thank-you-main-div");
let woocommerceTYBtn = document.querySelectorAll(
".woocommerce-MyAccount-downloads-file"
);
//get product title
let productTitle = document.querySelectorAll(".download-product a");
//get product price
let priceAmount = document.querySelectorAll(".woocommerce-Price-amount bdi");
//create elements for each product item
for (let i = 0; i < woocommerceTYBtn.length; i++) {
let thankYouInnerDiv = document.createElement("div");
thankYouInnerDiv.setAttribute("class", "thank-you-inner-div");
thankYouMain.append(thankYouInnerDiv);
let thankYouImg = document.createElement("img");
thankYouImg.setAttribute(
"src",
"https://slowtravellerss.com/wp-content/uploads/2022/04/IMG_0169.png"
);
thankYouImg.setAttribute("width", "300px");
let thankYouContent = document.createElement("div");
thankYouContent.setAttribute("class", "thank-you-content");
let thankYouDownloadBtn = document.createElement("a");
thankYouDownloadBtn.setAttribute("class", "thank-you-dw-btn");
thankYouDownloadBtn.textContent = "Download";
thankYouInnerDiv.append(thankYouImg, thankYouContent, thankYouDownloadBtn);
let thankYouProductTitle = document.createElement("a");
thankYouProductTitle.setAttribute("class", "thank-you-pd-title");
let thankYouProductDevider = document.createElement("span");
thankYouProductDevider.setAttribute("class", "thank-you-pd-devider");
let thankYouProductPrice = document.createElement("p");
thankYouProductPrice.setAttribute("class", "thank-you-pd-price");
thankYouContent.append(
thankYouProductTitle,
thankYouProductDevider,
thankYouProductPrice
);
//function to set href via get and set attributes
function settingAttr() {
thankYouDownloadBtn.setAttribute(
"href",
woocommerceTYBtn[i].getAttribute("href")
);
thankYouProductTitle.innerText = productTitle[i].innerText;
thankYouProductPrice.innerText = priceAmount[i].innerText;
}
settingAttr();
}
<div class="download-product">
This is the product title
</div>
<div class="woocommerce-Price-amount"><bdi>$99</bdi></div>
Download
<div class="thank-you-main-div">
</div>
I am trying to get data from one set of divs and show it in another div dynamically using getAttribute, setAttribute and innerText. The code is working fine on windows, mac and android devices. You can see the below code working just fine, But it does not work on iPhones. I tried using android and it works without any issue. This happens only on iphones. No idea how to fix this or find the issue. Does anyone have any suggestions?
This first part is to the point, but the latter section is "Meh. Take it if it makes sense." Sorry, I'm a bit of a snob. I have, uhm, "aesthetic" issues with what you're doing, but I'll separate that from the functionally-relevant issue.
The main bits
The main problem is that you're trying to use setAttribute for a structural, rendering-related attribute. I don't see why it'd be a "SHOULD NOT support" usage, but I'm not surprised it's a "MAY support" usage. In the following jsfiddle, I switch out your use of <element>.setAttribute for use of <element>.classList.add, and I confirm it's working as intended: https://jsfiddle.net/azpLj57f/1/ Note that the use of <element>.setAttribute for other attributes is retained...so far.
The opinionated fluff
I do hope you actually like this version of. It's going to look quite different, but I'll edit it to answer any questions you add in the comments: https://jsfiddle.net/q1my9c45/

Filling CSS grid with JavaScript

I am working on a personal project with a canvas that is a CSS grid. It is 17 rows and columns and instead of adding 289 divs manually, that I would create a for loop to do it for me when the page loads.
JavaScript:
var row = 1;
var column = 1;
function init() {
for (var i = 0; i < 289; i++) {
var div = document.createElement("div");
div.style.color = "gray";
div.style.gridRow = row;
div.style.gridColumn = column;
column += 1;
if (column == 17) {
row += 1;
column = 0;
}
console.log("test");
}
}
HTML:
<body onLoad="init();">
<canvas id="myCanvas" width="600" height="600"></canvas>
</body>
This is the only 'version' that I've tried that doesn't spit an error at me, but still nothing shows up. It runs though, because the console displays "test".
I've tried replacing:
var div = document.createElement("div");
with
var div = document.canvas.createElement("div");`,
var div = document.myCanvas.createElement("div");
...etc. (which probably aren't the right syntax but I tried them anyway) and it gives me this error when evaluating document.myCanvas.createElement:
TypeError: undefined is not an object
Basically I just want each grid box in the canvas to be filled using JS when the page loads. Also, I'm very new to programming so simple terms are much appreciated. Thank you in advance.
I ended up creating a div that had the canvas inside it and replacing:
var div = document.createElement("div");
with:
var newDiv = document.createElement("div");
document.getElementById("background").appendChild(newDiv);
and it worked great.

Adding options to a Select control in IE8/IE9

I have an iframe with a select control in it that I would like to add some options to. I am able to add options to the select inside the iframe using IE10+, Firefox, and Chrome, but my current solution does not work for IE8 and IE9.
I would like to find a way to add options to my select control. I have tried several solutions proposed on other stack overflow questions, but they do not seem to be working for me.
Here is the relevant part of my HTML view:
<!-- In the iframe -->
<div>
<div class="inline-block">SelectSomething: </div>
<select name="select-dialog" id="select-dialog" class="inline-block"></select>
</div>
Here is a snippet of my javascript code that tries to add options to the select control above:
// Grab select from iframe
var dialogSelect = document.getElementById('myFrame').contentWindow.document.getElementById('select-dialog');
var isIE8 = (isIE && getIEVersion() === 8);
if (isIE8)
{
dialogSelect.innerHTML = '';
// Attempt 1
var opt = new Option();
opt.innerHTML = 'Kobe';
opt.value = 'BlackMamba';
var opt2 = new Option();
opt2.innerHTML = 'RKelly';
opt2.value = 'PiedPiper';
dialogSelect.appendChild(opt);
dialogSelect.appendChild(opt2);
// Attempt 2
// var opt = dialogSatelliteSelect.options;
// opt[0] = new Option('Kobe', 'BlackMamba');
// opt[1] = new Option('R Kelly', 'PiedPiper');
console.log('innerHTML: ' + dialogSelect.innerHTML);
}
else
{
// The select is not populated with options in IE8 and IE9. This works with other browsers
dialogSelect.innerHTML = getOptions();
}
The console output for both attempts 1 and 2 are:
innerHTML: <OPTION value=BlackMamba selected>Kobe</OPTION><OPTION value=PiedPiper>RKelly</OPTION>
Even though the innerHTML contains the options I have created, I cannot select them using IE8/IE9. The drop down appears blank with nothing selected.
What do I need to do to have these options display in my select control? Is there some special step I need to take with IE8 to show the current options?

How can I apply CSS to elements created with javascript in IE?

I've been trying to create an auto complete function for text boxes wherein the user enters the first few characters and the system shows them a list of entries that begin with the user's given input. These entries are fetched from the database and displayed in the UI through javascript. It all works perfectly except in good ol' Internet Explorer where the style sheet properties don't work on the p elements created by javascript. Could anyone please tell me what I'm doing wrong here? Here is the code I'm using
HTML/JSP
<table>
<tr>
<td nowrap>WO Number</td>
<td style="text-align:left;">
<html:text property="won" styleClass="epntextBox" onkeyup="autokom();" styleId="won"/>
<div id="wondiv"></div>
</td>
</tr>
</table>
Javascript (This is some long code. It works fine though...)
function autokom(){
var number = document.getElementById("won").value;
var url = "Fetch_Won?wonnum="+number;
while(document.getElementById("wondiv").hasChildNodes()){
document.getElementById("wondiv").removeChild(document.getElementById("wondiv").childNodes[0]);
}
if(number=="" || number==null){
return false;
}
if(window.XMLHttpRequest)
{
req = new XMLHttpRequest();
try
{
req.open("GET",url,true);
}
catch(e)
{
alert(e);
}
req.onreadystatechange = processfetchWON;
req.send(null);
}
else if(window.ActiveXObject)
{
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req)
{
req.open("GET", url, true);
req.onreadystatechange = processfetchWON;
req.send(null);
}
}
}
function processfetchWON(){
if (req.readyState == 4)
{
if (req.status == 200)
{
try{
var responseXML = req.responseXML;
var parents = responseXML.getElementsByTagName("won");
var won;
var wondiv = document.getElementById("wondiv");
var num = 0;
if(parents.length>=15){
num = 15;
}else {num = parents.length;}
for (var loop = 0; loop < num; loop++)
{
won = parents[loop].childNodes[0].nodeValue;
var p = document.createElement("p");
p.setAttribute("class", "wonp");
p.setAttribute("id", won);
p.onclick = function() { setwon(this.id); };
p.innerHTML = won;
wondiv.appendChild(p);
}
}catch(e){
alert("Exception in fetching WON/ SWON numbers");
}
}
}
}
function setwon(swon){
document.getElementById("won").value=swon;
while(document.getElementById("wondiv").hasChildNodes()){
document.getElementById("wondiv").removeChild(document.getElementById("wondiv").childNodes[0]);
}
}
CSS
#wondiv{ /*This part works just fine*/
position: absolute;z-index:2;
}
.wonp{ /*But the following doesn't*/
display:block;
margin:0px;
padding:4px;
border:1px inset #000000;
cursor: pointer;
background: white;
width:123px;
}
.wonp:hover{
background: #cbcbcb;
}
I haven't had any problems with the javascript code but the style sheet not being applied to the dropdown by IE(8 - 11) is driving me nuts! Someone please help. I'm at the end of my wits here. (The same css works fine for elements that haven't been js created)
Change
p.setAttribute("class", "wonp");
to
p.className = "wonp";
Some versions of IE have a bug in that they expect you to use "className" with setAttribute, even though the attribute's name is class, not className. But all versions of IE and other browsers use className for the reflected property name, so the change above will solve the problem.
It's rare to actually need to use setAttribute. Virtually all of the attributes you might set (with the obvious exception of data-* attributes) have reflected properties on the element instance that are more useful. class and for (as in, on label elements) have slightly odd names (className and htmlFor) because class and for are reserved words in JavaScript and when this was being defined, JavaScript didn't let you use reserved words as property name literals (it does now), but most other reflected properties have the same name as the attribute they reflect:
element.setAttribute("class", x) => element.className = x
labelElement.setAttribute("for", x) => labelElement.htmlFor = x
element.setAttribute("id", x) => element.id = x
formElement.setAttribute("target", x) => formElement.target = x
linkElement.setAttribute("rel", x) => linkElement.rel = x
element.setAttribute("src", x) => element.src = x (script, img, ...)
Sometimes there are slight differences. For instance, element.getAttribute("href") will give you the actual text of the href attribute, but element.href will give you the resolved version (e.g., relative paths expanded to full ones). Similarly, the value property of input elements is only initialized from the "value" attribute, after which it takes on a life of its own (usually, but not always, reflected as defaultValue).

Ckeditor selected html not working correct with chrome browser

Iam working in an mvc application and using ckeditor 3.6.2 version. I have used the following code for getting selected html from ckeditor.
CKEDITOR.editor.prototype.getSelectedHtml = function () {
if (CKEDITOR.env.ie) {
this.focus();
selection = this.getSelection();
} else {
selection = this.getSelection();
}
if (selection) {
var bookmarks = selection.createBookmarks(),
range = selection.getRanges()[0],
fragment = range.clone().cloneContents();
selection.selectBookmarks(bookmarks);
var retval = "",
childList = fragment.getChildren(),
childCount = childList.count();
for (var i = 0; i < childCount; i++) {
var child = childList.getItem(i);
console.log(child);
retval += (child.getOuterHtml ?
child.getOuterHtml() : child.getText());
}
return retval;
}
};
I have an issue in chrome browser when I selected a text and call CKEDITOR.instances.editor1.getSelectedHtml().
For example, suppose in my editor there is a content <span style="color:red;">Welcome Note</span>. If I selected "Welcome Note" and call getSelectedHtml() method firefox,safari,IE8 returns "Welcome Note" with span tag, but chrome returns only the text "Welcome Note". If Iam trying to replace the selected content using CKEDITOR.instances.editor1.insertHtml("<div style='font-size:12px'>"+ CKEDITOR.instances.editor1.getSelectedHtml()+"</div>"), in chrome I lost the font color since getSelectedHtml() returns only the selected text. But this works fine with other browsers.
Note : If the content is "Welcome <span
style="color:red;">Note</span>" and the selected word is "Welcome
Note". In this case,this will be correct in chrome and other browsers.
Please suggest a proper solution.
There have been some similar cases that are documented on the CKEDITOR web site. In particular, take a look at this one:
http://cksource.com/forums/viewtopic.php?f=11&t=20202

Categories

Resources