Jump to:

10380 Posts in 2195 Topics by 1711 members

All other Modules

SilverStripe Forums » All other Modules » Universal Autocomplete Field

Discuss all other Modules here.

Moderators: martimiz, Howard, Sean, Ryan M., biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2
Go to End
Author Topic: 3461 Views
  • Anonymous user
    Avatar
    Community Member
    1 Post

    Universal Autocomplete Field Link to this post

    Hello, since the current AutocompleteTextField is broken beyond all hope, I created a replacement field using jQuery Autocomplete. It comes with its own controller that handles automatic generation of Autocomplete suggestions from any class and field in your database.

    For example, to suggest an author name from the Member table, one could use the following code:

    // the Autocomplete source
    $optionsUrl = 'admin/Autocomplete/Member/FirstName';

    // create the field
    $authorField = new AutocompleteField('Author', 'Page author', $optionsURL);

    This is still a very early version, so caveat emptor.

    Download - Project

  • Ingo
    Avatar
    Forum Moderator
    787 Posts

    Re: Universal Autocomplete Field Link to this post

    Awesome, thanks for kicking off this effort - we're very keen on non-core formfields maintained by the community!

    Some quick remarks on your code:

    I suggest namespacing your module and class names, its too likely that common names like "AutocompleteField" will cause clashes in the future. I know we havent been very good about this ourselves in core, but that makes it even more important for third-party extensions to find more unique names.

    Keep in mind that each FormField is a controller in itself (as in: it extends RequestHandler), so you should merge AutocompleteController into AutocompleteField. This has the advantage that you don't have to secure your controller separately, as any autocomplete requests will be executed within the context of the controller+form+formfield. One consideration here is performance: Autocomplete relies on fast responses, which might be difficult to achieve if your formfield is embedded in a complicated form.

    Have a look at the "tagfield" module for ideas: http://silverstripe.org/tag-field-module. Its very similiar to your code, and uses jQuery.autocomplete as well.

    $response->addHeader('Content-Length', strlen($body));
    I don't think you need to set this explicitly, your webserver should handle this.

    $className = Convert::raw2sql($request->param('ClassName'));
    $fieldName = Convert::raw2sql($request->param('FieldName'));
    This is a bit of a security hole - although youre checking the canView() methods, not every field should be accessible in certain contexts. I suggest initializing the field with these values as opposed to getting them from each ajax request.

  • Anonymous user
    Avatar
    Community Member
    1 Post

    Re: Universal Autocomplete Field Link to this post

    Thank you for the feedback, it helped me a lot not only to improve the formfields (new version up!), but to understand how the fields work as controllers.

    Someone really ought to write a hands-on tutorial for the wiki. Maybe I can get around to, but no promises.

    The tagfield is great, and exactly what I need for another part of my project. Mind if I bundle it into the small formfields module I put up? It is intended as a collection of ready-to-use simple form fields.

    Download - Project

  • Ingo
    Avatar
    Forum Moderator
    787 Posts

    Re: Universal Autocomplete Field Link to this post

    Aweeesome, that was fast! Looking much better now. The only question I have is around $SuggestURL - why would somebody want to customize this value? I don't think it needs getters/setters.

    > Mind if I bundle it into the small formfields module I put up?

    Sure, its opensource and you can redistribute it. Just make sure that any alterations are fed back to the main development line. You can manage these thirdparty plugins via svn:externals or specialized tools like http://piston.rubyforge.org/.

    > It is intended as a collection of ready-to-use simple form fields.

    I'd be careful with bundling too much stuff together in one "collection", as it gets more and more unlikely that all fields are needed in a specific use case. A consistent release process also gets more complicated - you might want to label one field implementation as "stable", another one as "alpha". its generally pretty easy to have multiple modules in SilverStripe (in the end theyre just folders), so if in doubt, I'd start one project per formfield.

  • Anonymous user
    Avatar
    Community Member
    1 Post

    Re: Universal Autocomplete Field Link to this post

    The possibility to customize $suggestURL was added more of less as an homage to AutocompleteTextField. I'll admit there is not much use to it.

    As for a formfield collection, I do not see the problem with having a number of unused field classes around. Are they adding some overhead I am not aware of?

    I like having some sort of "standard library" which I can just drop into any new project I am working on, with an AutocompleteField, a jQuery-UI Calender field etc. -- but putting each of them into an individual folder is too cluttered for my taste.

  • mobius
    Avatar
    Community Member
    54 Posts

    Re: Universal Autocomplete Field Link to this post

    Hi, I've just started using this field, and it works well except for one small bug - the source filter is never copied in to the object in the constructor.

    Changing the constructor like so fixes this issue:

    function __construct($name, $title = null, $value = "", $maxLength = null, $sourceClass = null, $sourceField = null, $sourceFilter = null)
          {
             // set source
             $this->sourceClass = $sourceClass;
             $this->sourceField = $sourceField;
             $this->sourceFilter = $sourceFilter; // <--- this is needed
             
             // add the AutocompleteField class used to initialize fields
             $this->addExtraClass('AutocompleteField');
             
             // construct the TextField
             parent::__construct($name, $title, $value, $maxLength);
          }

  • mobius
    Avatar
    Community Member
    54 Posts

    Re: Universal Autocomplete Field Link to this post

    Also, as it's using jQuery to start with, you can replace all that stuff in AutocompleteField.js with one line:

    jQuery('input.AutocompleteField').each(function () { jQuery(this).autocomplete(jQuery(this).attr('src')) });

  • abes
    Avatar
    Community Member
    9 Posts

    Re: Universal Autocomplete Field Link to this post

    Ingo wrote:
    "The only question I have is around $SuggestURL - why would somebody want to customize this value? I don't think it needs getters/setters."

    If you don´t use the field in a form context the suggestURL determination of the AutocompleteField would fail: FormField->Link() uses FormField->form->FormAction(). In this case it is useful to set an customized suggestURL.

    I would encourage to maintain this method for those use cases.

    3461 Views
Page: 1 2
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.