views:

472

answers:

3

Hi,

I'm trying to get an autocomplete form working, and I can't seem to figure out why I keep getting an this.element is null error.

Here is the js:

    //autocomplete
function AutoComp() {
new Ajax.Autocompleter("autocomplete", "autocomplete_choices", "fin/autocomplete", {});
}
document.onLoad = AutoComp();

HTML:

      <input type="text" id="autocomplete" name="autocomplete_parameter"/>
  <span id="indicator1" style="display: none">
    <img src="/shared/img/loading.png" alt="Working..." />
  </span>
  <div id="autocomplete_choices" class="autocomplete"></div>

When I load the page, I immediately get the this.element is null error from this section of controls.js:

var Autocompleter = { };
Autocompleter.Base = Class.create({
  baseInitialize: function(element, update, options) {
    element          = $(element);
    this.element     = element;
    this.update      = $(update);
    this.hasFocus    = false;
    this.changed     = false;
    this.active      = false;
    this.index       = 0;
    this.entryCount  = 0;
    this.oldElementValue = this.element.value;

If I set the value of the textfield manually via value="blah", I still get null. If I try to do an alert in controls.js, it seems to fail at this.element = element;. e.g. if I alert(element), it alerts the id of the field properly. If I alert(this.element) [after it is assigned], it alerts null.

Thanks.


Strange behavior...

If I change

  baseInitialize: function(element, update, options) {
    element          = $(element);
    this.element     = element;
    this.update      = $(update);
    this.hasFocus    = false;
    this.changed     = false;
    this.active      = false;
    this.index       = 0;
    this.entryCount  = 0;
    this.oldElementValue = this.element.value;

to:

  baseInitialize: function(element, update, options) {
    test          = $(element);
    this.test     = test;
    this.update      = $(update);
    this.hasFocus    = false;
    this.changed     = false;
    this.active      = false;
    this.index       = 0;
    this.entryCount  = 0;
    this.oldElementValue = this.test.value;

It does not throw the error. Is 'element' reserved?


I just ran the scriptaculous unit tests and there were some failures on the autocomplete test:

failed  testAjaxAutocompleter 7 assertions, 1 failures, 1 errors
Failure: 'ac_update' was not visible. undefined
TypeError: $("ac_update").firstChild is null(TypeError: $("ac_update").firstChild is null)
failed  testAfterUpdateElement 2 assertions, 2 failures, 0 errors
Failure: 'ac2_update' was not visible. undefined
Failure: assertEqual: expected "'afterupdate:LI'", actual "'abcdefg'"
failed  testTokenizing 1 assertions, 3 failures, 0 errors
Failure: assertEqual: expected "'test1'", actual "'abc'"
Failure: assertEqual: expected "'test1,test2'", actual "'abc,abc'"
Failure: assertEqual: expected "'test3,test2'", actual "'test1b,test2'"
failed  testAjaxAutocompleterNoLinebreaksInResult 7 assertions, 1 failures, 1 errors
Failure: 'ac_update_br' was not visible. undefined
TypeError: $("ac_update_br").firstChild is null(TypeError: $("ac_update_br").firstChild is null)
A: 

To get a better idea what is happening, either in IE8 use the Web Developer toolkit (for me I hit F12) and debug, then put in a break in the create function, or do the same with Firefox, using Firebug, and debug.

But, I am willing to bet this is your problem: element = $(element);

It is looking for an element type by that name. element = $('input') would get an array of all input elements on the page.

You may want element = $('#' + element), as that will get it by id, if you are using jquery, but I am not certain that that is the library you are using.

So put a break point in just before you do the assign and see what happens to the value of element before and after the assignation.

James Black
As I understood it, $(element) is prototype shorthand for getElementById, so essentially the element is the param passed to the function. So in my example, the param is 'autocomplete', hence the this.element is trying to be assigned 'autocomplete', no?
stormdrain
Also, firebug catches the error, but it is essentially the same info, it hangs at 'this.oldElementValue = this.element.value;' in controls.js...
stormdrain
Put the breakpoint before you get it by id and see if element had a value when passed into the function, then see what happens after. Which javascript library are you using?
James Black
I'm not sure I understand... But, what I noticed is that in firebug, if I set a breakpoint at element = $(element); = element is "autocomplete"this.element = element; = element is nullAs I mentioned in my edit to the original, if I change the names in the function from 'element' to 'test', it doesn't throw an error.
stormdrain
scriptaculous/prototype
stormdrain
You might be correct that element is being used for some other purpose by prototype. I haven't tried that, I try to pick names that won't be a keyword just in case, such as myelem, elem, telem. :)
James Black
eh, it turns out the issue was that the js was in the <head>... placed it before </body> and it doesn't throw that error (other errors now ;)Thanks for your help..
stormdrain
A: 

Problem was the script calling autocompleter was in the <head>... Needed to be after the input.

stormdrain
Glad you figured it out.
James Black
A: 

I haven't gotten this to work properly yet but I have eliminated the error. Put the Ajax.Autocompleter script at the bottom of the page, or at least after the controls are defined.

jim
Indeed. I had the script that was calling the ac in the `<head>`. And I did get it working, let me know if I can help.
stormdrain