Skip to content

Commit

Permalink
[#2375] Add ability to autocomplete packages
Browse files Browse the repository at this point in the history
As a test this has been implemented on the edit group form.
  • Loading branch information
aron committed Jul 25, 2012
1 parent 4dcbb38 commit 14b6c1f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 10 deletions.
41 changes: 33 additions & 8 deletions ckan/public/base/javascript/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
* the data into an array of strings. This also will remove duplicates
* from the results (this is case insensitive).
*
* data - The parsed JSON response from the server.
* data - The parsed JSON response from the server.
* options - An object of options for the method.
* objects: If true returns an object of results.
*
* Examples
*
Expand All @@ -50,7 +52,13 @@
*
* Returns the parsed object.
*/
parseCompletions: function (data) {
parseCompletions: function (data, options) {
if (typeof data === 'string') {
// Package completions are returned as a crazy string. So we handle
// them separately.
return this.parsePackageCompletions(data, options);
}

var map = {};
var raw = data.ResultSet && data.ResultSet.Result || {};

Expand All @@ -59,10 +67,11 @@
item = jQuery.trim(item);

var lowercased = item.toLowerCase();
var returnObject = options && options.objects === true;

if (lowercased && !map[lowercased]) {
map[lowercased] = 1;
return item;
return returnObject ? {id: item, text: item} : item;
}

return null;
Expand Down Expand Up @@ -90,13 +99,29 @@
* Returns an object of item objects.
*/
parseCompletionsForPlugin: function (data) {
var items = this.parseCompletions(data);
return {
results: this.parseCompletions(data, {objects: true})
};
},

items = jQuery.map(items, function (item) {
return {id: item, text: item};
/* Parses the string returned by the package autocomplete endpoint which
* is a newline separated list of packages. Each package consists of
* a name and an id separated by a pipe (|) character.
*
* string - The string returned by the API.
*
* Returns an array of parsed packages.
*/
parsePackageCompletions: function (string, options) {
var packages = jQuery.trim(string).split('\n');
var parsed = [];

return jQuery.map(packages, function (pkg) {
var parts = pkg.split('|');
var id = jQuery.trim(parts.pop() || '');
var text = jQuery.trim(parts.join('|') || '');
return options && options.objects === true ? {id: id, text: text} : id;
});

return {results: items};
},

/* Requests config options for a file upload.
Expand Down
49 changes: 48 additions & 1 deletion ckan/public/base/test/spec/client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('ckan.Client()', function () {

});

describe('.parseCompletions(data)', function () {
describe('.parseCompletions(data, options)', function () {
it('should return a string of tags for a ResultSet collection', function () {
var data = {
ResultSet: {
Expand Down Expand Up @@ -106,6 +106,34 @@ describe('ckan.Client()', function () {

assert.deepEqual(target, ["Test"]);
});

it('should return an array of objects if options.objects is true', function () {
var data = {
ResultSet: {
Result: [
{"Format": "json"}, {"Format": "csv"}, {"Format": "text"}
]
}
};

var target = this.client.parseCompletions(data, {objects: true});

assert.deepEqual(target, [
{id: "json", text: "json"},
{id: "csv", text: "csv"},
{id: "text", text: "text"}
]);
});

it('should call .parsePackageCompletions() id data is a string', function () {
var data = 'Name|id';
var target = sinon.stub(this.client, 'parsePackageCompletions');

this.client.parseCompletions(data, {objects: true});

assert.called(target);
assert.calledWith(target, data);
});
});

describe('.parseCompletionsForPlugin(data)', function () {
Expand All @@ -128,7 +156,26 @@ describe('ckan.Client()', function () {
]
});
});
});

describe('.parsePackageCompletions(string, options)', function () {
it('should parse the package completions string', function () {
var data = 'Package 1|package-1\nPackage 2|package-2\nPackage 3|package-3\n';
var target = this.client.parsePackageCompletions(data);

assert.deepEqual(target, ['package-1', 'package-2', 'package-3']);
});

it('should return an object if options.object is true', function () {
var data = 'Package 1|package-1\nPackage 2|package-2\nPackage 3|package-3\n';
var target = this.client.parsePackageCompletions(data, {objects: true});

assert.deepEqual(target, [
{id: 'package-1', text: 'Package 1'},
{id: 'package-2', text: 'Package 2'},
{id: 'package-3', text: 'Package 3'}
]);
});
});

describe('.getStorageAuth()', function () {
Expand Down
3 changes: 2 additions & 1 deletion ckan/templates/group/snippets/group_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
{% endif %}

{% set dataset_name = 'packages__%s__name' % data.packages|length %}
{{ form.input(dataset_name, label=_('Add Dataset'), id="field-dataset", value=data[dataset_name]) }}
{% set dataset_attrs = {'data-module': 'autocomplete', 'data-module-source': '/dataset/autocomplete?q=?'} %}
{{ form.input(dataset_name, label=_('Add Dataset'), id="field-dataset", value=data[dataset_name], classes=['control-medium'], attrs=dataset_attrs) }}
{% endblock %}

<div class="form-actions">
Expand Down

0 comments on commit 14b6c1f

Please sign in to comment.