Jump to content
Wiki Home
EPrints Home
Bazaar
Files
Main menu
Main menu
move to sidebar
hide
Navigation
Front Page
EPrints 3 Manual
EPrints Training Course
EPrints Glossary
Installing EPrints
How-to Configure EPrints
EPrints 3.2+ API
EPrints 3 Reference
EPrints Plugins
Wiki
All categories
Recent changes
Main Page
Help
EPrints Documentation
Search
Search
Appearance
Log in
Request account
Personal tools
Log in
Request account
Pages for logged out editors
learn more
Contributions
Talk
Editing
Adding an Auto-Completer to a non-workflow page
Page
Discussion
British English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
[[Category:Howto]] ===NOTE: THIS IS INCOMPLETE - CAN SOMEONE FILL IN THE DETAILS??=== Known to work for EPrints 3.2 Using the EPrints application framework, we can create auto-completion for any input, but we need to understand how the system works, and build the pages by the rules. ===How Auto-Completion works, in general=== Understanding AJAX Auto-Completion is a bit of a circular process, so bear with me. You need three things # An Auto-Completer "engine" (a complex Javascript code-base) # A script to do the lookup work & return ''stuff'' # (x)html structure to accept the returned ''stuff'' The process: * When the user types into an input box, a javascript event is triggered which sends that input value to a script. * The script returns an unordered list, which the Auto-Completer code displays for the user to select from * The Javascript engine then fills in the identified inputs with the selected values. ===A very simple example=== ====Input==== Here we have an input: <pre> <input type="textfield" size="25" id="oarj_oname" name="organisation_name" onkeypress="return EPJS_block_enter( event )" /> </pre> There are two important factors here: * <code>id="oarj_oname"</code> defines the identity of the element, which we need to read the "seed" value from, and fill in with the selected data. This element actually breaks down into two sub-parts: ** "oarj" is the ''component'' ** "oname" gives the part of the components * <code>onkeypress="return EPJS_block_enter( event )"</code> is the EPrints application ''magic incantation" to trigger some javascript when the user types something into the input box. =====Input with return locations===== What we also need the (x)html to receive the output of the mysterious javascript call: <pre> <input type="textfield" onkeypress="return EPJS_block_enter( event )" size="25" id="oarj_oname" name="organisation name"> <div style="display: none;" id="oarj_oname_drop" class="ep_drop_target"></div> <div style="display: none;" id="oarj_oname_drop_loading" class="ep_drop_loading"> <img src="/style/images/loading.gif" alt="" style="border: 0pt none ;"> </div> </pre> Some of this is more ''magic incantation'' There are two <code>div</code>s - one to accept the return from the AJAX magic, and one to display the "I'm doing stuff" graphic. Their ids are declared in the Javascript call, however they should be derived from the id of the input field: * "oarj_oname_drop" is the named element to receive the output of the javascript * "''xxxx''_loading" is the element that displays the "I'm busy" graphic. It's name is specific: it is the same as the ''drop'' element, with <code>_loading</code> appended. =====Input with return locations and javascript call===== Finally, we need to append the bit that makes the Auto-Completer call: <pre> <input type="textfield" onkeypress="return EPJS_block_enter( event )" size="25" id="oarj_oname" name="organisation name"> <div style="display: none;" id="oarj_oname_drop" class="ep_drop_target"></div> <div style="display: none;" id="oarj_oname_drop_loading" class="ep_drop_loading"> <img src="/style/images/loading.gif" alt="" style="border: 0pt none ;"> </div> <script type="text/javascript"> // <![CDATA[ ep_autocompleter( "oarj_oname", "oarj_oname_drop", "/cgi/get_orgs", {relative: "oarj_oname", component: "oarj" }, [ $("oarj_oname")], [], "&field=name") // ]]></script> </pre> The javascript has multiple fields: # <code>"oarj_oname"</code> is the id of the element that the Auto-Completer reads from # <code>"oarj_oname_drop"</code> is the id of the element the return data is put into # <code>"/cgi/get_orgs"</code> is the name of the script called to get the return data # <code>{relative: "oarj_oname", component: "oarj" }</code> is ''magic incantation'' - referred to as ''basenames'' in the javascript code, I give it the id of the element and the component level name # <code>[ $("oarj_oname")]</code> more ''magic incantation'' - ''width_of_these'' ?? # <code>[]</code> would be the ''fields_to_send'' # <code>"&field=name"</code> is ''extra_params'' - a way of passing extra cgi parameters to the script ====The Returned Data==== The final part of this loop is the returned data. It doesn't particularly matter what is used to create this data, so long as the users client receives the data in the right format With the EPrints Auto-Completer, the format for this return is fairly simple: <pre> <ul> <li>Some informative text<br /> (with something else on a new line <ul> <li id="for:value:component:_oname">Fandangle</li> <li id="for:value:component:_diddle">Fruit Loops</li> <li id="for:value:component:_a1">Another One</li> <li id="for:value:component:_b2">Befuddled Too</li> </ul> </li> <li> ..... </li> </ul> </pre> To break this down, we're looking at a list of returns, each of which has a list of "fill-in" items Lets break the list down into parts: <pre> <ul> <li>Some informative text<br /> (with something else on a new line</li> <li> Another entry </li> <li> The Third Way </li> <li> Option Four </li> </ul> </pre> This is the list of items to display to the user - in this case, 4 items. What we don't have here is the data to be filled in, once a selection has been made. That looks like this: <pre> <li>Some informative text<br /> (with something else on a new line <ul> <li id="for:value:component:_oname">Fandangle</li> <li id="for:value:component:_diddle">Fruit Loops</li> <li id="for:value:component:_a1">Another One</li> <li id="for:value:component:_b2">Befuddled Too</li> </ul> </li> </pre> Each item has a sub-list, where each item has a ''magic incantation'' for it's id: <code>for:value:component:</code> is the bit that the EPrints Auto-Completer code looks for, and <code>_''xxx''</code> names the sub_element that the data does into. Given the <code>ep_autocompeter</code> call above, we have defined a ''component'' of <code>oarj</code>. Thus: * <code><li id="for:value:component:_oname">Fandangle</li></code> puts "Fandangle" in the element <code>id="oarj_oname"</code> * <code><li id="for:value:component:_diddle">Fruit Loops</li></code> puts "Fruit Loops" in the element <code>id="oarj_diddle"</code> * <code><li id="for:value:component:_a1">Another One</li></code> puts "Another One" in the element <code>id="oarj_a1"</code> * <code><li id="for:value:component:_b2">Befuddled Too</li></code> puts "Befuddled Too" in the element <code>id="oarj_b2"</code> '''Note''': If the element does not exist, then the value is ignored... sensibly. ===Creating the (x)html in an EPrints page=== To make an Auto-Completer form within eprints, it's basically a case of assembling the DOM: <pre> $d = $session->make_element("div"); $d->appendChild( $session->render_input_field( type=>"textfield", name=>"oarj_oname", id=>"oarj_oname", class=>"ep_form_text", size=>25 ) ); $d->appendChild( $session->make_element("div", class=>"ep_drop_target", id=>"oarj_oname_drop", style=>"display:none" ) ); $div = $session->make_element("div", class=>"ep_drop_loading", id=>"oarj_oname_drop_loading", style=>"display:none"); $div->appendChild( $session->make_element( "img", style=>"border:0", alt=>"", src=>"/style/images/loading.gif" ) ); $d->appendChild( $div ); $d->appendChild( $session->make_javascript( 'ep_autocompleter( "oarj_oname", "oarj_oname_drop", "/cgi/get_orgs", {relative: "oarj_oname", component: "oarj" }, [ $("oarj_oname")], [], "&field=name")' ) ); </pre> ====Making an EPrints page from a CGI script==== Making a page from a CGI script is fairly easy: <pre> #!/path/to/appropraite/perl use EPrints; my $session = EPrints::Session->new(); my( $page, $title ) = make_page( $session ); $session->build_page( $title, $page ); $session->send_page(); $session->terminate(); exit; sub make_page { my( $repository) = @_; my $page = $repository->make_doc_fragment; my $title = $repository->make_text( "OARJ Organisation management tool" ); ## Stuff to build return( $page, $title ); } </pre> ====Making an EPrints page within the interface==== For this, you need a new module in <code>perl_lib/EPrints/Plugins/Screen/</code> - see (''somewhere else'') ===The code to create the return ''stuff''=== Auto-Completers are fine, but they need something to look-up information and return ''stuff'' for the user to select from. The important factors you need to know to write a script are: * The value from the input field will be in a parameter called "q" * You need to return data with an xml header * You need to return an unordered list * You can send back more data than you are going to use ====An example==== Here is my lookup from Open Access Repository Junction: <pre> use EPrints; my $dbh = /// connect to database sub get_orgs { my ($dbh, $index_key, $index_value) = @_; my $db_return = /// a reference to a list of returns from a database query //// name, acronym, url my %data = (); # build up a lump of (x)html for each item foreach my $ref (@$db_return) { my $html = "<li>".$ref->[0]; $html .= "(".$ref->[1].")" if $ref->[1]; $html .= "[".$ref->[2]."]" if $ref->[2]; $html .= "<ul>"; $html .= "<li id='for:value:component:_oname'>".$ref->[0]."</li>"; $html .= "<li id='for:value:component:_ourl'>".$ref->[1]."</li>"; $html .= "<li id='for:value:component:_oacronym'>".$ref->[2]."</li>"; $html .= "</ul></li>\n"; $data{$ref->[2]} = $html; } my @html = (); if (!scalar keys %data) { push @html, "<!-- no matches -->"; return (join "\n", @html) } push @html, "<ul class='journals'>\n"; foreach my $id (keys %data) { push @html, "$data{$id}\n"; } push @html, "</ul>\n"; return (join "\n", @html) } my $session = EPrints::Session->new(); # we need the send an initial content-type print <<END; <?xml version="1.0" encoding="UTF-8" ?> END # then we send the fragment of html for the autocompleter my $value = ""; my $field = ""; $value = $session->param( "q" ); $field = $session->param( "field" ); print get_orgs($dbh, $field, $value); #print STDERR get_journals( $q ); $session->terminate; </pre>
Summary:
Please note that all contributions to EPrints Documentation may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
EPrints Documentation:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)