Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

All other Modules /

Discuss all other Modules here.

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

Universal Autocomplete Field


Go to End


10 Posts   6498 Views

Avatar
Ingo

Forum Moderator, 801 Posts

23 August 2009 at 1:54pm

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.

Avatar
Ingo

Forum Moderator, 801 Posts

24 August 2009 at 10:06am

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.

Avatar
mobius

Community Member, 54 Posts

11 January 2010 at 1:18pm

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);
		}

Avatar
mobius

Community Member, 54 Posts

11 January 2010 at 4:29pm

Edited: 11/01/2010 4:37pm

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')) });

Avatar
abes

Community Member, 11 Posts

9 February 2010 at 8:55am

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.

Avatar
AdamJ

Community Member, 145 Posts

24 April 2010 at 3:59am

I installed this on a site build on SS 2.4.0 rc1, specifically in two instances on an object managed in ModelAdmin. One instance in the dataobject being managed, and one in a has_many relation managed through a DOM popup.

The one in the DOM popup works fine, but the one on the parent dataobject doesn't do a thing. It is the AutocompleteField input, just doesn't do any of the autocomplete javascript.

I added a console.log call to the autocomplete javascript (the one that mobius listed) and this only is called on the popup, not on the parent instance. Anyone have any ideas why this may be?

Avatar
otherjohn

Community Member, 125 Posts

3 June 2010 at 9:27am

Has anyone gotten this to work for SS 2.4
It's not working for me. I will try to debug what is going on.
John

Avatar
martimiz

Forum Moderator, 1391 Posts

30 June 2010 at 11:25pm

Edited: 30/06/2010 11:29pm

Hi all - and thanks anonimous user, whoever you are :-)

I've got it working (as a test) in ModelAdmin 2.4. Using the download from the 3rd post in this thread, added Mobius' fix and two of my own:

1. in AutocompleteField, line 221 replace

$response = new HTTPResponse($body);

with:

$response = new SS_HTTPResponse($body);

2. When using the field in ModelAdmin: this works when editiong an existing record, but not when adding a new one. This is because the latter doesn't use EditForm, it uses AddForm. So in AutocompleteField.js, replacing:

AutocompleteField.applyTo('#Form_EditForm input.AutocompleteField');

with

AutocompleteField.applyTo('input.AutocompleteField');

will make that work as well (can't think of any horrible implications just yet).

Cheers, Martine

P.s.: I'm not using the DataObject Manager, so no idea about any problems there...

Go to Top