I''m trying to extended Ajax.Autocompleter to simplify the process of
looking up belongs_to associations, and giving you the option of
creating a new target object when the search yields no results. All of
which is working fine so far.
When the search yeilds no results, a single <li> is pops up where the
search results would be and says "not found. click here to create".
Clicking hides the current form, and pulls up a create_object form for
the target object via an Ajax.Update. All working like it should.
The problem comes here: when the new target object is created, I want
to server to feed back the id and name of that object into my
Autocompleter object, either via an rjs or the ":success" option of
the remote form on the creation page. But either way I try it, the
javascript that gets to the page won''t recognize the variable that
represents my Autocomplete object.
I don''t want to post too much code here, but the jist of it is, the
autocompeter is written to the page (via an extended form_builder)
like this:
<script type="text/javascript">
//<![CDATA[
var contribution_artist_name_auto_completer = new
Lookup.Autocompleter(''contribution_artist_name'',
''contribution_artist_name_auto_complete'', ''/artists/
auto_complete_for_name'',
{idField:''contribution_artist_id'', minChars:
4, newObjectUrl:''http://localhost:3002/artists/new'',
paramName:''name'',
targetObject:''artist''})
//]]>
</script>
So, I figure I should be able to call that variable
("contribution_artist_name_auto_completer"), and access a function in
it to complete the process once the target object (in this case
''artist'') is created. But sending back an rjs file like this,
(if
params[:lookup_name_id] == "contribution_artist_name") :
page.call((params[:lookup_name_id] + "_auto_completer").to_sym,
@artist.id, @artist.name)
Throws a javascript error:
RJS Error:
ReferenceError: contribution_artist_name_auto_completer is not
defined.
So the question, I guess, is: Is there a special scoping issue that
I''m not aware of? Or has anyone had experience similiar to this and
maybe could help point me in the right direction? I''d really
appreciate any help,
John Devine
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---
Hey John,
Before diving further into a client-side maintainance, is there any 
reason why your AC class is Local, instead of being AJAXy (if you used 
Ajax.Autocompleter as a base, you would, by definition, always get the 
latest information from the server side)?
If we stay client-side (which I''m not too fond of for AC''s), I
need to
make sure I understand what you''re saying:
1) The page loads
2) At some point in this loading process there''s an inline script that
    defines your AC variable.
3) The user looks up something (among local client-side data), doesn''t
    find it, gets a <li> that lets them create it
4) They click, get a form, fill it up, submit it (which is intercepted
    and then done through AJAX)
5) The server-side returns an RJS-created JS call that attempts to
    invoke a method on your local AC, as created on step 2.  The
    reference cannot be found.
Is this the actual scheme for your problem?
-- 
Christophe Porteneuve aka TDD
tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---
Christophe --
With a few exceptions, you''ve got the jist of it -- step 5 is exactly
right
and the root of my problem -- I can''t see the original Autocompleter
variable,
either in Firebug, or call it through an RJS or an "onSuccess" call of
the remote
form.
Actually my Autocompleter isn''t Local -- it''s extended from
Ajax.Autocompleter :
var Lookup = {};
Lookup.Autocompleter = Class.create();
Object.extend(Object.extend(Lookup.Autocompleter.prototype,
Ajax.Autocompleter.prototype), {
  initialize: function(element, update, url, options) {
    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.url                   = url;
    this.idFieldId             = this.getIdFieldId(this.options);
    this.idField               = $(this.idFieldId);
            .... .....
    this.newObjectUrl          = this.options.newObjectUrl;
    this.targetObject					 = this.options.targetObject || null;
    this.setCreateNewDiv(options);
    this.options.afterUpdateElement = this.afterUpdateElement;
  },
 etc.
Actually the first step on the page I''d trying to debug now is to
load
a "show" page of the parent object that doesn''t orginally
include the
autocompleter,
in this case "play.rhtml". That just lists the attributes of a play.
To add an
author (or composer, or lyricist) to the play, you click to
link_to_remote
anchor which updates a div with the form for a "contribution", which
is a join object
linking an artistic_work, an artist, and an artistic_role.
That Ajax-loaded form rhtml includes a hidden input field for the
artist_id and a "lookup" field for the artist -- too many for a
drop down, and I don''t want them to be able to input someone I
don''t
have an id for
since I''m creating a join object that has "artist" as a
belongs_to.
The Lookup is obviously reaching my page, as all the ajaxy goodness
happens
and my extensions are being called, etc. By overriding onComplete, I
have the
page give the option to create a new target object by calling up a
remote_form
for the target object:
onComplete: function(request) {
   this.update.innerHTML = request.responseText;
   if(this.update.firstChild &&
this.update.firstChild.childNodes.length == 1 ){
      if(!this.changed && this.hasFocus) {
        li = document.createElement(''li'');
        li.innerHTML = "Not found. Click here to create."
        Element.addClassName(li,"selected")
        Event.observe(li,"click",
this.createNewObject.bindAsEventListener(this));
        this.update.firstChild.appendChild(li);
        if(this.hasFocus) {
          this.show();
          this.active = true;
        }
      }
      this.entryCount = 0;
      this.stopIndicator();
      this.index = 0;
    } else {
      this.updateChoices(request.responseText);
    }
  },
The form which is called up by this.createNewObject takes all the
attributes
of the target object (artist) creates and saves a new active record
(via Ajax calls)
, and returns the id and name so that they can be populated into the
original form.
That''s where I get stuck.
Do variables that are set to the window via "evalScripts" (which is
how the "lookup" autocompleter
got there in the first place) reside in the same window context as
variables included
statically on the orginal page, or is there a special way to access
them?
Still stuck, so any thoughts appreciated.
John
On Feb 23, 3:16 am, Christophe Porteneuve
<t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org>
wrote:> Hey John,
>
> Before diving further into a client-side maintainance, is there any
> reason why your AC class is Local, instead of being AJAXy (if you used
> Ajax.Autocompleter as a base, you would, by definition, always get the
> latest information from the server side)?
>
> If we stay client-side (which I''m not too fond of for
AC''s), I need to
> make sure I understand what you''re saying:
>
> 1) The page loads
> 2) At some point in this loading process there''s an inline script
that
>     defines your AC variable.
> 3) The user looks up something (among local client-side data),
doesn''t
>     find it, gets a <li> that lets them create it
> 4) They click, get a form, fill it up, submit it (which is intercepted
>     and then done through AJAX)
> 5) The server-side returns an RJS-created JS call that attempts to
>     invoke a method on your local AC, as created on step 2.  The
>     reference cannot be found.
>
> Is this the actual scheme for your problem?
>
> --
> Christophe Porteneuve aka TDD
> t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---
just a quick revision: the rjs file in the original post was an old version -- should read like this: page.call((params[:lookup_name_id] + "_auto_completer.loadNewObject"), @artist.id, @artist.name) But it still yeilds the same error: contribution_artist_name_auto_completer is not defined. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Further googling finally revealed the answer:
from http://www.sergiopereira.com/articles/prototype.js.html at the
end of the section: Using the Ajax.Updater class:
<quote>
 In case you''ve tried it before, you know it doesn''t work. The
reason
is that the script block will be evaluated, and evaluating a script
like the above will not create a function named sayHi. It will do
nothing. To create this function we need to change our script to
create the function. See below.
<script language="javascript" type="text/javascript">
	sayHi = function(){
		alert(''Hi'');
	};
</script>
<input type="button" value="Click Me"
onclick="sayHi()"/>
Note that in the previous example we did not use the var keyword to
declare the variable. Doing so would have created a function object
that would be local to the script block (at least in IE). Without the
var keyword the function object is scoped to the window, which is our
intent.
</quote>
So, by editing my lookup_field helper (which was copied from the
ActionView::Helpers::JavascriptMacrosHelpers#auto_complete_field
helper) to not include the "var" at the beginning of my declaration,
the whole thing now works as expected.
    def lookup_field(field_id, options = {})
        function =  "#{field_id}_auto_completer = new
Lookup.Autocompleter("
        function << "''#{field_id}'', "
        function << "''" + (options[:update] ||
"#{field_id}_auto_complete") + "'', "
        function <<
"''#{url_for(options[:url])}''"
          ... ...
        function << ('', '' +
options_for_javascript(js_options) + '')'')
        javascript_tag(function)
    end
whereas the first line (and the auto_complete_field helper) read:
        function =  "var #{field_id}_auto_completer = new
Lookup.Autocompleter("
Is there a good argument for including the "var" in the first place?
Would this be something that should be changed in the rails helpers?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---