Jump to:

22992 Posts in 11842 Topics by 2828 members

General Questions

SilverStripe Forums » General Questions » (solved) Autocomplete TextFields: How can you get it to work?

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2 3
Go to End
Author Topic: 3179 Views
  • martimiz
    Avatar
    Forum Moderator
    1038 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    Hi there,
    I just found out that some errors found their way into the log - happened when I indeed renamed the AutoCompleteField class to BalbusAutoCompleteField to fix the conflict with the existing SilverStripe AutoCompleteField, but failed to correct all occurances of the fieldname in the documentation. Real sorry about that

    The only thing you need to change is the name of the files to BalbusAutocompleteField.php and BalbusAutocompleteField.js and then create the field by its proper name:

    $fields->addFieldsToTab('Root.Content.Main', array(
    new BalbusAutocompleteField(
    $name = 'MyField',
    $title = 'Enter a value'
    )
    ));

    And no, you don't have to do it that way, any correct way of adding a formfield to the CMS should do. Let me know if you run into any new problems...

  • BlueScreen
    Avatar
    Community Member
    36 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    Okay, after changing all instances of 'autocompletefield' to 'balbusautocompletefield', that seemed to resolve the conflicts, I can confirm the correct code is being run accordingly. However I am now back to where I was before: The autosuggest cannot seem to find anything

    EG: i type in 'pa' which should pick up 'paris' from this list:

    function suggest() {
          
          $return_arr = array(
             array('value' => 'London'),
             array('value' => 'Paris'),
             array('value' => 'Rome')
          );
          return json_encode($return_arr);
    }

    The result is just a long stream of unanswered GET requests, but perhaps that is normal behavior if the autosuggest naturally cannot find a reference list to suggest from?

  • BlueScreen
    Avatar
    Community Member
    36 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    My suspicions were correct. The function 'suggest()' is not being executed and therefor the autosuggest has no reference list to begin with.

    Not sure why at this point but that explains quite a bit.

    Add this:

    user_error("breakpoint:", E_USER_ERROR);


    inside the suggest() function. Does it successfully break for you?

    EDIT:

    "The url adds the url segment suggest to the AutocompleteField's link, using it as a simulated page url with param Action=Suggest. This automatically calls the AutocompleteField's suggest() method."

    Well it seems the correct url is being outputted (It returns a 404 if it wasn't) but it cannot access suggest() anyway. maybe there are permissions in the way or the redirect rules are screwing up the url. Either way something is stopping the url from calling suggest()

    Direct links (EG: $attributes['src'] = 'bookingmanager/code/balbusautocompletefield/suggest';) don't work either, damn

  • martimiz
    Avatar
    Forum Moderator
    1038 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    I know this is only a very basic autocomplete field. Thanks for your comments - it does set me to working on this thing again - and I did find a couple of issues So if you are willing to take this a step further, this would be the first test:

    Preferrably on a fresh install, in the Page class add:

    public static $db = array(
    'Test' => 'Varchar'
    );

    function getCMSFields() {
       $fields = parent::getCMSFields();

       ...

       $fields->addFieldsToTab('Root.Content.Autocomplete', array(
          new BalbusAutocompleteField (
             $name = 'Test',
             $title = 'Autocomplete testfield'
          )
       ));

       return $fields;
    }

    In the BalbusAutoCompleteField.php replace the suggest method by:

    function suggest() {
       $items = array(
          array('value' => 'London'),
          array('value' => 'Paris'),
          array('value' => 'Rome')
       );
       return json_encode($items);
    }

    Log in to your admin. Then do a /dev/build/?flush=1

    Now if you go to the following url (replace the path to your admin section):

    http://www.mydomain/admin/EditForm/field/Test/suggest?term=par

    It should return something like:

    [{"value":"London"},{"value":"Paris"},{"value":"Rome"}]

    Please let me know...

  • BlueScreen
    Avatar
    Community Member
    36 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    Basic is good for me, I can't deal with anything extremely sophisticated right now. If I can't get autocomplete working soon my boss will start asking me questions. So yes lets take this a step further.

    I followed the instructions: modified page.php, logged into the admin, ran dev/build and entered the URL.

    The result was a blank page with some cryptic "I can't let you do that, Dave" message on it. My log outputted this: 'Unknown column 'Page.Test' in 'field list' (http://[root]/admin)" so I don't think I did that right. I'll try that again.

    meanwhile my previous code in my module has just decided it wants to be broken. Now it tells me this: "TypeError: jQuery(this).autocomplete is not a function".

    [EDIT]

    I tried again, this time ensuring that I had the updated code from www.balbus.tk and I used a brand new server with nothing else on it.

    balbusautocomplete.php

    function setSourceClass($classname) {
          SS_Log::log(new Exception('Autocomplete: setSourceClass('.$className.')'), SS_Log::NOTICE);
    $this->sourceClass = $classname;
    }

    /*
    * set the sourcefield
    */
    function setSourceField($fieldname) {
          SS_Log::log(new Exception('Autocomplete: setSourceField('.$fieldName.')'), SS_Log::NOTICE);
    $this->sourceField = $fieldname;
    }

    /*
    * Override the existing TextField method and add
    * the jQuery requirements and the new field ettributes:
    * src - url called by ajax to retrieve the suggestions
    * autocomplete - flag setting autocompletion 'on' or 'off'
    */
    function Field() {
          SS_Log::log(new Exception('Autocomplete: Field()'), SS_Log::NOTICE);
    // Note: sometimes loading new JavaScripts in the CMS
    // will not work. Looks like the assets/_CombinedFiles
    // are the culprits (in that case just remove them)

    // Get jQuery from SilverStripe thirdparty
    Requirements::javascript(
    THIRDPARTY_DIR . '/jquery/jquery.js'
    );

    // Get the UI from Google (the SilverStripe way)
    Requirements::javascript(
    'http://ajax.googleapis.com/ajax/libs/jqueryui'.
    '/1.8.1/jquery-ui.min.js'
    );
    Requirements::css(
    'http://ajax.googleapis.com/ajax/libs/jqueryui'.
    '/1.8.1/themes/base/jquery-ui.css'
    );

    // NEW: Since inline JavaScript isn't loaded by jQueryOnDemand,
    // an external file is needed to set things in motion:
    Requirements::javascript(
    'balbusessentials/javascript/BalbusAutocompleteField.js'
    );

    // altered 'text' class to 'text AutocompleteField'
    $attributes = array(
    'type' => 'text',
    'class' => 'text AutocompleteField ' . ($this->extraClass()? $this->extraClass(): ''),
    'id' => $this->id(),
    'name' => $this->Name(),
    'value' => $this->Value(),
    'tabindex' => $this->getTabIndex(),
    'maxlength' => ($this->maxLength) ? $this->maxLength : null,
    'size' => ($this->maxLength) ? min( $this->maxLength, 30 ) : null
    );

    if($this->disabled) $attributes['disabled'] = 'disabled';

    // NEW: add een attribute to enable autocompletion
    $attributes['autocomplete'] = 'on';

    // NEW: add a sourceClass/sourcefield, if there is one
    $querystring = http_build_query(array(
    'sclass' => $this->sourceClass,
    'sfield' => $this->sourceField
    ), '', '&');

    // NEW: add the current link with the Action=suggest
    // parameter added as a new src parameter
    $attributes['src'] =
    parse_url($this->Link(),PHP_URL_PATH) . '/suggest?' . $querystring;

    // Create the tag
          SS_Log::log(new Exception('Autocomplete: creating Tag: '.http_build_query($attributes)), SS_Log::NOTICE);
    return $this->createTag('input', $attributes);
    }

          function suggest() {
             SS_Log::log(new Exception('Autocomplete: suggest()'), SS_Log::NOTICE);
             $items = array(
             array('value' => 'London'),
             array('value' => 'Paris'),
             array('value' => 'Rome')
             );
             SS_Log::log(new Exception('Autocomplete: suggesting: '.implode($items)), SS_Log::NOTICE);
             return json_encode($items);
          }

    balbusautocomplete.js

    alert("autocomplete running");
    try{
       BalbusAutocompleteField = Class.create();
    }catch(exception){
       alert("class create failed: "+exception);
    }
    try{
       BalbusAutocompleteField.applyTo('input.AutocompleteField');
    }catch(exception){
       alert("class apply failed: "+exception);
    }
    BalbusAutocompleteField.prototype = {
       
       // initialize Autocomplete fields
       initialize: function() {
    // only initialize once
    if (!this.strSource){
             
    // get source string src attribute
    this.strSource = jQuery(this).attr('src');
             alert("autocomplete source found: "+this.strSource);
             
    // remove src attribute from the textfield
    jQuery(this).attr('src', '');
             try{
       // jQuery Autocomplete
       jQuery(this).autocomplete({
        source: this.strSource,
        minLength: 2
       });
             }catch(exception){
                alert("autocomplete failed: "+exception);
             }
             alert("autocomplete end");
    } else {
             alert("source not found");
          }
    }
    };

    page.php

       public static $db = array(
          'Test' => 'Varchar'
       );

       public static $has_one = array(
       );

       function getCMSFields() {
          $fields = parent::getCMSFields();

          $fields->addFieldsToTab('Root.Content.Autocomplete', array(
          new BalbusAutocompleteField (
          $name = 'Test',
          $title = 'Autocomplete testfield'
          )   
          ));

          return $fields;
       }

    The link to http://[root]/admin/EditForm/field/Test/suggest?term=par definitely returns the following message:

    "I can't handle sub-URLs of a Form object."

  • BlueScreen
    Avatar
    Community Member
    36 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    new test case: I created two files in my fresh install of silverstripe

    mysite/code/Test_Contoller.php

    class Test extends Page {
       
    }

    class Test_Controller extends Page_Controller {
       
       public static $allowed_actions = array(
          'index',
          'suggest',
          'Form'
       );
       
       function init() {
          parent::init();
       }
       
       function index()
       {
          $this->init();
          return $this->renderWith('testform');
       }
       
       function Form(){
          SS_Log::log(new Exception('Rendering dummy form'), SS_Log::NOTICE);
          $fields = new FieldSet(
          new BalbusAutocompleteField (
              $name = 'Test',
              $title = 'Autocomplete testfield'
           )
       );
          
        // Create action
        $actions = new FieldSet(
             new FormAction('dummy', 'Submit')
          );
          
        $form = new Form($this, 'DummyForm', $fields, $actions);
          return $form;
       }
       
       function link() {
          
       }

    mysite/templates/includes/testform.ss

    <script language="javascript" type="text/javascript">
    //put jquery directly into here to try and force it
    </script>
    <style>#formbox {width: 600px; padding: 15px; border: solid;}</style>
    <div id="formbox">
       <p>Testing</p>
       $Form
    </div>

    mysite/_config.php

    Director::addRules(100, array(
    'test' => 'Test_Controller'
    ));

    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    SS_Log::add_writer(new SS_LogFileWriter(Director::baseFolder() . '/error_log.txt'), SS_Log::ERR);
    SS_Log::add_writer(new SS_LogFileWriter(Director::baseFolder() . '/error_log.txt'), SS_Log::NOTICE);
    SS_Log::add_writer(new SS_LogFileWriter(Director::baseFolder() . '/error_log.txt'), SS_Log::WARN);
    Director::set_environment_type("dev");

    navigate to [root]/test to see it work..or not work. The jquery does not appear to load with this configuration even though it closely imitates how my custom module uses forms. If I force the jquery in, it crashes on the first line.

    The php seems to be working, it usually gets about as far as the Field function:

    [18-Mar-2011 01:54:17] Notice at \mysite\code\Test_Controller.php line 29: Rendering dummy form
    [18-Mar-2011 01:54:17] Notice at \mysite\code\BalbusAutocompleteField.php line 44: Autocomplete: Field()
    [18-Mar-2011 01:54:17] Notice at \mysite\code\BalbusAutocompleteField.php line 101: Autocomplete: creating Tag: type=text&amp;class=text+AutocompleteField+&amp;id=Form_DummyForm_Test&amp;name=Test&amp;value=&amp;autocomplete=on&amp;src=DummyForm%2Ffield%2FTest%2Fsuggest%3Fsclass%3D%26sfield%3D

    Try it out, might help you find out why sometime it works and sometimes it does not.

  • martimiz
    Avatar
    Forum Moderator
    1038 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    OK - this is getting a bit complex... Again, I worked on the thing , and added an alternative fully jQuery BalbusAutocomplete.js javascript, that does support the field in the frontend - at least for me (bottom of the source page).

    Please check out this example, and let me know if it works for you (type auto into the field)
    http://www.balbus.tk/autocompletefield-example/

    If you still can't get yours to work, I'll see if I can put together a small module for you to download and install. Are you looking to use the field in your CMS or frontend?

  • BlueScreen
    Avatar
    Community Member
    36 Posts

    Re: (solved) Autocomplete TextFields: How can you get it to work? Link to this post

    FrontEnd only

    I will be coding in the autocompletefields exactly how I did in my test case: seperate pages and controllers physically located in mysite or another module

    The example on your site seems to work perfectly, its just what I need! Now if only I could figure out why my own module doesn't like it.

    If you can package the source code of that into a separate module, I'll run it on a fresh blank copy of sapphire on my home PC. If it works on the webserver I'm running at home and not at the one at work I can narrow down the problem to just conflicts or dependencies at my work webserver.

    3179 Views
Page: 1 2 3
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.