modifying select with DOM - javascript

I've found some results for this on google but nothing satisfying so I was hoping someone here might know.
It seems as though populating a select element using innerHTML does not work in IE
I have set up a file that does nothing but that and it works with everything but IE, here's the code in case anyone cares:
<html>
<head></head>
<body onload="populate();">
<script type="text/javascript">
function populate()
{
document.getElementById("test").innerHTML = '<option id="a">works</option>';
}
</script>
<select id="test"></select>
</body>
</html>
Anyone know a solution to this? I don't want to remove everything and then manually use appendChild as I am returned html from a different function, and it seems ridiculous that this doesn't work.
Any ideas would be appreciated.

EDIT: This answer was written before the OP said he didn't want to use appendChild(). I will keep this answer up for reference.
This post will use POJSF. (Plain Old JavaScript Framework, the framework every other framework is based on!)
For those who don't get it, that's a poor attempt a humor...
Instead of using innerHTML, you can create your <option> using document.createElement()
var newOption = document.createElement('option');
newOption.label = 'works';
newOption.appendChild(document.createTextNode(newOption.label));
newOption.id = 'a';
document.getElementById('mySelect').appendChild(newOption);
If you want to remove all <option> in a <select>:
var selectEl = document.getElementById('mySelect');
for(var i = selectEl.children.length - 1; i >= 0; i--) {
selectEl.removeChild(selectEl.children[i]);
}

Check out: BUG: Internet Explorer Fails to Set the innerHTML Property of the Select Object

Related

Uncaught TypeError: Cannot read property 'append' of null in jQuery

Starting from this jQuery code:
var country_name_list=document.getElementById("country");
$.post(getcountry,function (data) {
var Rcountry_name_list=JSON.parse(data);
var arr=[];
for(var i=0;i<Rcountry_name_list.countries.length;i++){
var r_id=Rcountry_name_list.countries[i].country_id;
var r_name= Rcountry_name_list.countries[i].country_name;
var option_name = document.createElement("option");
option_name.textContent =r_name;
option_name.value = r_id;
country_name_list.append(option_name);
}
});
HTML
<form method="post" action="" id="rform" novalidate="novalidate">
<label class="control-label">Country </label>
<select id="country" name="country" class="form-control" >
<option value=" " disabled selected hidden>Select Country</option>
<option value="0"></option>
</select>
</form>
On the line country_name_list.append(option_name); I get the following error
Uncaught TypeError: Cannot read property 'append' of null in jQuery
First of all, when a DOM selector returns null, it means the element was not found. So you have to wait for the DOM to be loaded.
With jQuery it's enough to wrap your selector in the following statement
$(document).ready(function(){
});
vi5ion's right, but you could also improve your code
var country_name_list = document.getElementById("country");
Here you didn't use jQuery, so you have to keep using javascript DOM methods.
$.get(getcountry, function (data) {
Here $.get is enough
var response = JSON.parse(data);
I think Capital letter is only for classes
var option, current;
If you create the variables here, you avoid creating a new variable for each loop, so will save time!
var list = response.countries;
for(var i=0; i < list.length; i++){
current = list.countries[i];
option = document.createElement("option");
option.textContent = current.country_name;
option.value = current.country_id;
country_name_list.appendChild(option_name);
As vi5ion suggests appendChild() is what you need
}
});
It seems easier to read the code now, didn't it?
Hope this is useful!
country_name_list is not a jQuery object and therefore doesn't have the append() function.
In fact, most of your code is plain JavaScript and not jQuery, so you would probably want to use the function appendChild() instead.
Edit: added alternative jQuery solution below
If you insist on using jQuery you could wrap your variable.
That can either be done here
var country_name_list = $('#country');
or here
$(country_name_list).append(option_name);
but not both.
When you receive an error of type "Cannot read property XXX of null", you want to make sure that your element exists when your script is called.
For instance, you would place your javascript right before the closing tag to make sure that the element has is in the DOM.
Alternatively, if you have your script inserted in the header, or prior in the page, you may want to enclose i inside the $.ready() method to ensure that it is only run after the DOM is ready
$( document ).ready(function() {
... your code
}
You can find more information at: https://api.jquery.com/ready/
I faced a similar issue, I did try the above solutions, but mine was due to different reason.
Therefore, one solution would be wrapping it under the document.ready
$(document).ready(function(){
});
One another solution will be, try using jQuery() instead of $(), this was helpful for me.
jQuery('#item_field').append('<div></div>');
instead of
$('#item_field').append('<div></div>');
I got the same error
I tried entering the script tag in the body section
It worked for me

Javascript, viewing [object HTMLInputElement]

I'm just started to learn HTML. Doing an alert() on one of my variables gives me this result [object HTMLInputElement].
How to get the data, that were added in text field, where my input type is text?
Say your variable is myNode, you can do myNode.value to retrieve the value of input elements.
Chrome Developer Tools has a Properties tab which shows useful DOM attributes.
Also see MDN for a reference.
If the element is an <input type="text">, you should query the value attribute:
alert(element.value);
See an example in this jsFiddle.
Also, and seeing you're starting to learn HTML, you might consider using console.log() instead of alert() for debugging purposes. It doesn't interrupt the execution flow of the script, and you can have a general view of all logs in almost every browser with developer tools (except that one, obviously).
And of course, you could consider using a web development tool like Firebug, for instance, which is a powerful addon for Firefox that provides a lot of functionalities (debugging javascript code, DOM inspector, real-time DOM/CSS changes, request monitoring ...)
It's not because you are using alert, it will happen when use document.write() too. This problem generally arises when you name your id or class of any tag as same as any variable which you are using in you javascript code. Try by changing either the javascript variable name or by changing your tag's id/class name.
My code example:
bank.html
<!doctype html>
<html>
<head>
<title>Transaction Tracker</title>
<script src="bank.js"></script>
</head>
<body>
<div><button onclick="bitch()">Press me!</button></div>
</body>
</html>
Javascript code:
bank.js
function bitch(){ amt = 0;
var a = Math.random(); ran = Math.floor(a * 100);
return ran; }
function all(){
amt = amt + bitch(); document.write(amt + "
"); } setInterval(all,2000);
you can have a look and understand the concept from my code. Here i have used a variable named 'amt' in JS. You just try to run my code. It will work fine but as you put an [id="amt"](without square brackets) (which is a variable name in JS code )for div tag in body of html you will see the same error that you are talking about.
So simple solution is to change either the variable name or the id or class name.
change:
$("input:text").change(function() {
var value=$("input:text").val();
alert(value);
});
to
$("input:text").change(function() {
var value=$("input[type=text].selector").val();
alert(value);
});
note: selector:id,class..
<input type="text" id="name">
and in javascript
var nameVar = document.getElementById("name").value;
alert(nameVar);
<input type="text" />
<script>
$("input:text").change(function() {
var value=$("input:text").val();
alert(value);
});
</script>
use .val() to get value of the element (jquery method), $("input:text") this selector to select your input, .change() to bind an event handler to the "change" JavaScript event.
When you get a value from client make and that a value for example.
var current_text = document.getElementById('user_text').value;
var http = new XMLHttpRequest();
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200 ){
var response = http.responseText;
document.getElementById('server_response').value = response;
console.log(response.value);
}

Adding option elements using .innerHTML in IE

I have a txt variable that contains my html string that I need to set for a drop down list. The code works fine in all the other browsers except for IE. The basic code is shown below.
while loop with some more code
document.getElementById('theSelector').innerHTML = txt;
where 'theSelector' is the id of my select element for my form
So basically IE poops out and doesn't generate my list. I'll post my webpage below if you'd like to look at the source and everything that I'm doing. If you want to see how the site should function just run it in another browser that's not ie.
http://1wux.com/Resume/signUp.html
Based on your comment that it isn't generating your list, and Jared's comment that you're trying to add options, try something like this:
var list = document.getElementById('theSelector');
var newOp = document.createElement("option");
newOp.text = "Txt";
newOp.value = "1";
list.options.add(newOp);
EDIT
Per Jared's comment, the following may offer you a bit of a performance advantage:
list.options[list.options.length] = newOp;
As others have mentioned, this is a bug in all version of IE. I would use #AdamRackis's solution, but if you must build your HTML with string, the only workaround seems to be use outerHTML and include your <select> in the string.
Demo: http://jsfiddle.net/ThinkingStiff/TWYUa/
HTML:
<select id="select"></select>
Script:
var options = '<select id="select"><option>one</option><option>two</option></select>';
document.getElementById( 'select' ).outerHTML = options;
use Jquery
$('#theSelector').html(txt);

document.getElementById().innerHTML for select tag doesn't work in IE

i have the following simple script
<input type="button" onclick="document.getElementById('a').innerHTML = '<option>something</option>';"/>
<select id="a" style="width: 150px;">
</select>
but it doesn't work in IE.
could you tell me why?
thanks
You will be better off having the AJAX script return a JSON object containing the options you want, then using DOM methods to create the option nodes to match them.
If you really must do this with HTML strings, the way to do it is to write a completely new <select> element with the options inside. Then you can copy the information from the <option> nodes into to the select you were originally targeting.
var select= document.getElementById('a');
select.options.length= 0;
var div= document.createElement('div');
div.innerHTML= '<select>'+options+'</select>';
var options= div.firstChild.options;
for (var i= 0; i<options.length; i++) {
var o= options[i];
select.options[i]= new Option(o.text, o.value, o.selected);
}
Or simply use jQuery and html() instead of innerHTML...
So...
$("#a").html("<option>Whatever</option>");
Works great in all browsers for all objects!
Use this code:
var optionElement = document.createElement("option");
optionElement.innerHTML = "some text here";
document.getElementById('a').appendChild(optionElement);
IE doesn't tend to like you doing things that way for such items. Same goes for setting the innerHTML of tables.
You should learn to do things the DOM way....for instance, using createElement ("OPTION"), then appendChild() (first removing children with removeChild() if needed). In general it is way better than innerHTML.

Toggle CSS values using Javascript

I'm trying to modify the behavior of some web parts in Sharepoint (thus forcing IE down my throat) for our users who use the Project server pages. I'm not really the best JavaScript guy, and this is driving me nuts.
On one webpart to display the work from Project, there is a subrow 'Planned' shown below the actual data entry row that clutters the view. We want to turn the 'Planned' row off.
I can do it with a simple three liner like this:
<style type="text/css">
.XmlGridPlannedWork {display:none;}
</style>
But the users want to toggle the lines on and off.
So I thought I'd try reading then writting the current CSS value like so:
<script type="text/javascript">
function toggle_PlannedLine()
var ObjPlanned = Document.getElementById("tr").getElementsByTagName("XmlGridPlannedWork");
for(var i=0;i<ObjPlanned.length;i++)
{
if (OjbPlanned[i].display != "none")
{
// toggle the 'Planned' line off
ObjPlanned[i].style.display = "none";
}
else
{
// toggle the 'Planned' line on
ObjPlanned[i].style.display = "inline";
}
}
return;
}
</script>
<button onClick="toggle_PlannedLine();">Toggle Planned Line</button>
The actual segment I'm targeting looks like this:
<tr class="XmlGridPlannedWork" RowID="694810f9-e922-4321-9236-e495dd5048d9B" ID="GridDataRow">
Of course, when you click the button, the rows don't disappear.
At this point, I'm pretty sure I'm missing something obvious, but like I mentioned, I'm no JavaScript guru.
Easiest Solution
Ok, so my answer below should help you out, but here is another way to approach it that is much simpler:
CSS
<style type="text/css">
.XmlGridPlannedWork {display:none;}
body.showPlanned .XmlGridPlannedWork { display: block}
</style>
HTML/JavaScript
<script type="text/javascript">
function toggle_PlannedLine() {
if(document.body.className.match(/\bshowPlanned\b/) > -1)
document.body.className = document.body.className.replace(/\bshowPlanned\b/,'');
else
document.body.className += " showPlanned";
}
</script>
<button onClick="toggle_PlannedLine();">Toggle Planned Line</button>
Original Answer
You were really close in the concepts you wanted, but as the other answers point out a number of things were missing. I rewrote your function to work cross browser, and please ask if you have any questions about it:
<script type="text/javascript">
function toggle_PlannedLine() {
var objs = [];
if( document.querySelector){
objs = document.querySelectorAll('tr.XmlGridPlannedWork');
} else if (document.getElementsByClassName) {
objs = document.getElementsByClassName('XmlGridPlannedWork');
} else {
var temp = document.getElementsByTagName('tr');
for(var j = 0; j < temp.length; j++){
if(temp[j].className.match(/\bXmlGridPlannedWork\b/) > -1){
objs.push(temp[j]);
}
}
}
for(var i=0;i<objs.length;i++)
{
if (objs[i].style.display != "none")
{
// toggle the 'Planned' line off
objs[i].style.display = "none";
}
else
{
// toggle the 'Planned' line on
objs[i].style.display = "inline";
}
}
}
</script>
<button onClick="toggle_PlannedLine();">Toggle Planned Line</button>
For those arguing that jQuery is not a valid answer, please take the following code as an example of why jQuery is so easy to use. All of the previous code is summed up like this:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(function(){
$('button.toggle').click(function(){
$("tr.XmlGridPlannedWork").toggle();
})
})
</script>
<button class="toggle">Toggle Planned Line</button>
You forgot the opening brace for your function.
You are using getElementByTagName incorrectly. This function gets elements that match based on tag name (a, img, etc.) not CSS class. You can use jquery to accomplish what you want, or you can enumerate through every element on the page until you find the one you want. There are some open-source implementations of this available online. Your best bet, though, would be to add an id to the tag you care about, and then use getElementById.
Finally, Document should be document, and JavaScript is case sensitive.
Hope this helps!
document.getElementsByTagName looks for elements based on the name of their HTML tag, not their class attribute. Newer (not IE) browsers have support for document.getElementsByClassName(), and there are open source functions that do the same thing, falling back on the browser-native versions where available. This function will return a NodeList containing all the elements that use that class, and you can access each element and hide it through that list.
First, document should be lowercase in your var ObjPlanned declaration.
Second, getElementById returns an element based on a unique ID and you're passing it the element, or tag, name. getElementsByTagName returns an array of elements matching a certain tag but you're passing it a className. There is no 'getElementsByClassName' built in to JavaScript, but you can easily use Google to find a solution.
Use jQuery. It provides a very useful $.css() method, which does what you're looking for in a very simple fashion.

Categories