74

The code below works on a live site but I can't get it to run on the site jsfiddle .

See this for example.

Can anyone tell me why it's not working on jsfiddle?

On the console it logs: ReferenceError: fillList is not defined and ReferenceError: mySelectList is not defined.

The code works as you can see when it's embedded here as snippet:

function BetterSelect(oSelList) {
  this.objSelectList = oSelList;
  this.objSelectList.onchange = this.selectionChanged;
}
BetterSelect.prototype.clear = function() {
  this.objSelectList.options.length = 0;
}
BetterSelect.prototype.fill = function(aValues) {
  this.clear();
  for (var i = 0; i < aValues.length; i++) {
    this.objSelectList.options[i] = new Option(aValues[i]);
  }
}
BetterSelect.prototype.find = function(strToFind, bSelect) {
  var indx = -1;
  this.objSelectList.options.selectedIndex = -1;
  for (var i = 0; i < this.getCount(); i++) {
    if (this.objSelectList.options[i].text == strToFind) {
      indx = i;
      if (bSelect)
        this.objSelectList.options.selectedIndex = i;
    }
  }
  return indx;
}
BetterSelect.prototype.getCount = function() {
  return this.objSelectList.options.length;
}
BetterSelect.prototype.selectionChanged = function() {
  alert("selection changed!");
}

var mySelectList = null;
window.onload = function() {
  mySelectList = new BetterSelect(document.getElementById('theList'));
}

function fillList() {
  mySelectList.fill(["one", "two", "three", "four", "five"]);
}

function findIt() {
  mySelectList.find(document.getElementById('txtToFind').value, true);
}
<form action="" method="post">
  <select multiple="multiple" name="Select1" id="theList" style="width: 152px; height: 226px">
  </select>
  <br />
  <input name="Button1" type="button" value="Fill The List" onclick="fillList()" />
  <input name="Button4" onclick="mySelectList.clear()" type="button" value="Clear The List" />
  <br />
  <input name="Button2" onclick="alert(mySelectList.getCount())" type="button" value="What's The Count?" />
  <br />
  <input name="Text1" type="text" id="txtToFind" />
  <input name="Button3" type="button" value="Search" onclick="findIt()" />
</form>
Ruslan López
  • 4,433
  • 2
  • 26
  • 37
Leahcim
  • 40,649
  • 59
  • 195
  • 334
  • 3
    see also the possible duplicate [Simple example doesn't work on JSFiddle](http://stackoverflow.com/questions/5431351/simple-example-doesnt-work-on-jsfiddle) – Bergi Mar 11 '13 at 16:05

4 Answers4

92

The functions you define are defined in an onload function, so whereas before they were referenceable, because they are defined in that function they can only be referenced from within that function. You reference them as globals in your HTML. You have three options

a) ( easiest, quickest, not ideal ) - change function blah(){} to window.blah = function(){}; making the functions global.

b) ( ideal way ) - use unobtrusive Javascript to attach behaviour to DOM elements from within the JS solely, meaning separate HTML from JS.

c) Make the jsfiddle not wrap the stuff onload. Change onLoad to no wrap ( body or head ).

So instead of <p onclick="lol()" id="foo"> you'd do var e = document.getElementById('foo'); e.onclick = lol; in the JS only.

I recommend b as it encourages best practices.

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
  • 1
    thank you. how is it then that the code works on a live site? – Leahcim Mar 29 '11 at 05:45
  • 6
    Because the functions are not defined within another function on the live site. The jsfiddle throws your JS inside a function. View source on http://fiddle.jshell.net/mjmitche/afPrc/show/ – meder omuraliev Mar 29 '11 at 05:46
  • 4
    Thanks. It's pretty absurd that this workaround is required, though. – Jonah Jun 04 '16 at 17:55
49

In your fiddle select no wrap (head) in the dropdown on the left, click Run and it will work.

See example →

When onLoad is selected your functions are defined within the closure of the $(document).ready(function() {}); only.

mVChr
  • 49,587
  • 11
  • 107
  • 104
6

I found the same issue and solve it by changing Load Type in the JavaScript settings:

No wrap-in<head> or No wrap-in<body> in the drop down JavaScript settings menu. Refer the below image.

JavaScript Settings Menu

theblindprophet
  • 7,767
  • 5
  • 37
  • 55
Don D
  • 726
  • 1
  • 9
  • 19
0

Look at:

https://stackoverflow.com/a/4935684/6796393

Or it is better to see this one:

https://stackoverflow.com/a/19110630/6796393

Here is what I tested:

function testJSON() { 
    var jsonString = '{"param1":"123","param2":"XXX78","param3":"11378"}'; 
    var tmp_obj = eval('(' + jsonString + ')');
    document.getElementById("result").innerHTML =  tmp_obj.param2;
}

and

function testJSON() { 
    var jsonString = '{"param1":"123","param2":"XXX78","param3":"11378"}'; 
    var tmp_obj = JSON.parse(jsonString);
    document.getElementById("result").innerHTML =  tmp_obj.param2;
} 

It is better to use the second aproach.

P.S.> I came from How to parse parameters from JSON String using JS?

Community
  • 1
  • 1
Ye K
  • 143
  • 2
  • 9