Strange design error when sending "select" from javascript - javascript

I have two sets of code, that basically sends a drop down list to a div from Javascript.
The strange thing is that I am basically sending the same thing in both the cases. But in the first code, the select drop down is perfectly being shown, while in the second code, it is being broken.
Code 1:
document.getElementById('start_day_div').innerHTML += "<select name='start_day' id='start_day'><option value='1'>option1</option><option value='2'>option2</option></select>";
Code 2: (Basically I am sending the same data as the code 1)
document.getElementById('start_day_div').innerHTML += "<select name='start_day' id='start_day'>";
document.getElementById('start_day_div').innerHTML += "<option value='1'>option1</option>";
document.getElementById('start_day_div').innerHTML += "<option value='2'>option2</option>";
document.getElementById('start_day_div').innerHTML += "</select>";
Any idea why this is happening for the same code?

After each call to element.innerHTML += the browser will correct any incorrect html.
In your case you create the following html (which is invalid in itself as <option>'s cannot float around like that.)
<select name='start_day' id='start_day'></select>
<option value='1'>option1</option>
<option value='2'>option2</option>
If you want to do it, you need to do it in one go. If you want to format it better, concatenate with a +:
document.getElementById('start_day_div').innerHTML += "<select name='start_day' id='start_day'>"
+ "<option value='1'>option1</option>"
+ "<option value='2'>option2</option>"
+ "</select>";
<div id="start_day_div"></div>

If you are creating an incomplete select, most browsers will correct the error by closing the select html in order to render the control and make it an accessible object in the DOM with the normal select object properties etc. So afterwards the options are appended separately. If you inspect the resulting html this backs this theory up.

Related

changing text input to select in wordpress using jQuery

I am using a WordPress module abase to get some data from database and send them to a form. The problem is, that abase form does not allow to use select input. Because of that I am trying to convert text input to a select. I created function toSelect, to which I pass id of element and list of options (for testing I put id of element to function definition).
function toSelect(itemid,valuelist) {
var out = '';
out += '<select id="bus311mtd_2_status" style="width:50px;">';
for (i=0; i < valuelist.length; i++) {
out += '<option value="'+valuelist[i]+'">'+valuelist[i]+'</option>';
}
out += '</select>';
alert(out);
$("#bus311mtd_2_status").replaceWith(out);
//$("#bus311mtd_2_status").replaceWith('<input type="text" value="zamontowane">');
}
alert(out) gives nice select input code, but $("#bus311mtd_2_status").replaceWith(out) does not work.
Even something like: $("#bus311mtd_2_status").replaceWith('<input type="text" value="zamontowane">') doesn't work.
Element with id bus311mtd_2_status for sure exists (i.e. changing its value using document.getElementById() works fine)
Maybe jQuery doesn't work?
Your code seems to work fine for me. Perhaps it's your function call. I used:
toSelect(null, ['a', 'b', 'c']);
itemid doesn't appear to be used in the function.
Here's a fiddle with your code working:
http://jsfiddle.net/dgrundel/Lko6aftf/
Here's a slightly optimized version of the function, that uses the itemid argument:
function toSelect2(itemid,valuelist) {
var html = '<select id="' + itemid + '" style="width:50px;"><option>' +
valuelist.join('</option><option>') +
'</option></select>';
$('#' + itemid).replaceWith(html);
}
toSelect2('myInput2', ['d', 'e', 'f']);
Thank you for the answer and optimization. I used itemid initially but because of problems I temporarily replaced it with id of some existing element to make sure that the problem is somwhere else.
All the code until first alert works fine and alert(out) gives the popup window with text:
<select id="bus311mtd_2_status" style="width:50px;"><option value="ready">ready</option><option value="awaiting">awaiting</option></select>
This works as was expected. But the problem starts with the next line.
I wanted to show that even such an easy code like below doesn't work.
$("#bus311mtd_2_status").replaceWith('<input type="text" value="zamontowane">');
So it looks like the jQuery was not supported.
And I've got another observation: within script tags no empty lines are allowed (the code doesn't work if they are present).

How to create a list with formatted items using DOM instead on HTML concatenation?

Please forgive me and let me know if my post is not right since I am brand new to this forum.
I have found most of the answer here (Create a <ul> and fill it based on a passed array), but my problem comes with .createTextNode. My users are using multiple editor boxes to build an outline. Within these boxes they can format the text (underline, color, bold, etc.). So the array items that I am passing to .createTextNode actually have HTML tags in them to format the line items. However .createTextNode makes it just plain text which in turn just spits out the tag instead of applying it when displayed via document.getElementById('foo').appendChild...
I know that I should stay away from HTML concatenation but it is looking very tempting.
Is there any way to retain the formatting of the list items when appended and displayed?
Thank you in advance for your assistance.
Try innerHTML, which will try to parse the content string as HTML structure. For example you have a P tag
<p id="asdf"></p>
<script>
document.getElementById('asdf').innerHTML = 'qwerty';
</script>
Will give you a clickable anchor
<p id="asdf">
qwerty
</p>
But be careful!!! (Notice I use three bang sign here) You must be sure there's no harmful code before you insert it. Check this example:
document.getElementById('asdf').innerHTML = '<img src="image.png" onload="alert(1)">'
You will see an alert dialog. This example is simple though, in practice it can be much more dangerous, e.g. dynamically append a cross site script into you page, aka XSS.
EDIT: here is a demo.
var options = ['Option 1','Option 2'];
function makeUL(){
var LIs = '';
for (i = 0; i < options.length; i += 1){
LIs += '<li>' + options[i] + '</li>';
}
return '<ul>' + LIs + '</ul>';
}
document.getElementById('foo').innerHTML = makeUL();
<div id="foo"></div>

Selected option not displaying as selected after append()

I'm building a string of HTML based on JSON data. In the HTML is a <select> with its <option>s. If the <option>'s value is the same as some JSON data, it includes the selected="selected" attribute to the option tag as well. After that, the whole shebang is .append()ed to a display.
All of that seems to work fine and dandy, except that the selected option isn't selected. Checking the code in Chrome's Web Dev tools shows that the selected="selected" attribute is there. Doing a console.log() of the :selected options picks them up. However, when I drill down to a specific <option> and look at it, is shows the selected attribute as set to false.
Wha...?
I've tried using the .select() and .attr("selected","selected") jQuery methods after-the-fact to force the issue, but neither has made any difference.
Can anyone else figure out what's going on here? It might just be my squirrely ignorance, but this seems to me like it should be working.
Code for reference. dataArray is an array of objects. $display is the jQuery wrapped <table> the HTML is .append()ing to:
$orderNumberField = jQuery("#orderNumber");
_orderNumberArray = $.parseJSON( $orderNumberField.val() );
for( n in dataArray ) {
var _displayString = "";
// ... other table data cells ...
_displayString += "<td><select class='orderNumSelect'>";
_displayString += " <option value=''></option>";
for( i in _orderNumberArray ){
_displayString += "<option value='" + _orderNumberArray[i] + "'";
if( dataArray[n].orderNum == _orderNumberArray[i] ) _displayString += " selected='selected'";
_displayString += ">" + _orderNumberArray[i] + "</option>";
}
_displayString += "</select></td>";
// ... still other table data cells ...
$display.append( _displayString );
}
I'm not sure what's not working on your code,but you can try to generate the elements rather than appending text. I tested out with this code and it works fine
<script>
var dataArray=["test","testm2","Tasat3"];
function append(){
var td=document.createElement("td");
var sel=document.createElement("select");
var o=document.createElement("option");
sel.appendChild(o);
for (n in dataArray){
o=document.createElement("option");
o.value=dataArray[n];
o.text=dataArray[n];
if (n==1) o.selected=true;
sel.appendChild(o);
}
td.appendChild(sel);
document.getElementById("display").appendChild(td);
}
append();
</script>
As it turns out, the code outlined above was not at fault for the behavior I described. There is other code executing after it that resets form inputs. The jQuery selector in the other code was written too generally and was picking up the generated select fields also when it shouldn't have.
Thank you to all the commentors. I did end up rewriting the code to use DOM elements instead of generating a string, which is a little easier to read. Hooray for unintentional side effects.

javascript += operator

In my JSON javascript live pull I have:
html += "<tr><td width=60 valign=top><a href='"+item.url+"' target='_blank'>"+item.site+"</a></td>";
The += seems to strip out my tr td values
So I tried amending it to = which just seems to fail.. I tried setting td as a var and still no luck
Any ideas of a way round this, my js is basic so even if you think its silly your answer could help me greatly..
EDIT
to confuse things things further the = alone works in Firefox but on IE the items are loading hidden in the background.. I don't get why the browsers would perform so differently over the use of one + sign...
try:
html += "<tr><td width=60 valign=top><a href='"+item.url+"' target='_blank'>"+item.site+"</a></td></tr>";
Your markup generated is invalid (not closing the anchor tag) so it's possible the browser isn't interpreting the html very well.
x += y is just a shorthand for x = x + y. If you change it to html = "...", you'd be overwriting anything that already existed in the html variable.
How are your "tr td values" being stripped?

html select execute javascript onload

I am using HTML select onchange event to fire another javascript function func1.
This html select is written into a form element, which are dynamically generated when users click on a button.
The problem is how can I fire the javascript func1 when the dynamically generated form is first shown ?
I am thinking of something along the line of on_first_show event for form ?
Here is the snippet. I couldnt get the alert('don') to work either (the one just after div)
var sPopupContents = "<div ><script type='text/javascript'>alert('don');</script> </div>"; // this javascript is not executed ? I cant get the alert.
sPopupContents += "<form name='theform' >";
sPopupContents += "<select name='theselect' onchange='alert(2);";
sPopupContents += "func1()>'";
sPopupContents += "<option value='0' selected='selected'>Value1</option><option value='1'>Value2</option><br/>";
sPopupContents += "</form>";
-- EDIT --
I guess I can add another option in the html select that tells users to select, so forcing the onchange to take effect. Or I can just add a Submit button.
You could use document.createElement method instead of using literal srings, and add the onchange event handler by calling addEventListener.
You are closing the select tag before the single quote
sPopupContents += "<select name='theselect' onchange='alert(2);";
sPopupContents += "func1()>'";
should be:
sPopupContents += "<select name='theselect' onchange='alert(2);";
sPopupContents += "func1()'>";
A library such as jQuery would let you do this:
(function() {
function selectChange() {
// save baby seals here
};
$('select[name=theselect]').live('change', selectChange)
$(document).ready(selectChange);
}();
You don't need a library for this for most browsers, however. A change event will bubble up to the containing element, so you can listen for it there. I believe it's IE that won't bubble up a change event.

Categories

Resources