Merge lp:~jcsackett/launchpad/picker-buttons-should-disappear into lp:launchpad

Proposed by j.c.sackett
Status: Merged
Approved by: j.c.sackett
Approved revision: no longer in the source branch.
Merged at revision: 13339
Proposed branch: lp:~jcsackett/launchpad/picker-buttons-should-disappear
Merge into: lp:launchpad
Diff against target: 108 lines (+54/-3)
2 files modified
lib/lp/app/javascript/tests/test_personpicker.js (+38/-0)
lib/lp/app/javascript/widgets.js (+16/-3)
To merge this branch: bzr merge lp:~jcsackett/launchpad/picker-buttons-should-disappear
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+65562@code.launchpad.net

Commit message

[bug=798778] [r=allenap] Hides the extra buttons on personpicker when a search is made.

Description of the change

Summary
=======
Personpicker introduces assign me and remove assignee buttons to all person assigning activities. However, it's confusing to see the assign me and remove me buttons when there are results from a search in the picker.

This branch makes the buttons disappear if there are search results, but provides the buttons if no results are found, in which case one might concievably want to assign one's self.

Proposed fix
============
Using the YUI event model, we want to detect the presence of results and hide the extra buttons if they exist after results are loaded.

Pre-implementation notes
========================
Spoke with Curtis Hovey, explaining likely implementation.

Implementation details
======================
The personpicker now has overrided the picker's bindUI call, adding a section that creates a handler for the 'resultChange' event fired by the picker. This handler checks for the result condition (e.g. are there results, and was a search done) and determines whether to apply the unseen class to the extra buttons based on that information.

There are also some drive by fixes to the method invocations in personpicker, to make better use of the YUI event and widget model.

Tests
=====
firefox lib/lp/app/javascript/tests/test_personpicker.html

Demo and Q/A
============
Do a search with the personpicker (e.g. on launchpad.dev/evolution/+edit-people). If you search for a value with results (e.g. 'name') the extra buttons are not shown. If you search for a value without results (e.g. 'nobody') the buttons are displayed.

Lint
====
Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/app/javascript/widgets.js
  lib/lp/app/javascript/tests/test_personpicker.js
  lib/lp/app/javascript/tests/test_picker.js

./lib/lp/app/javascript/widgets.js
      14: 'Picker' has not been fully defined yet.
      79: 'PersonPicker' has not been fully defined yet.

The errors can be ignored as they're part of the javascript extension.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/app/javascript/tests/test_personpicker.js'
2--- lib/lp/app/javascript/tests/test_personpicker.js 2011-06-29 14:05:39 +0000
3+++ lib/lp/app/javascript/tests/test_personpicker.js 2011-06-30 13:58:58 +0000
4@@ -19,6 +19,22 @@
5 links: {me: '/~no-one'},
6 cache: {}
7 };
8+ this.vocabulary = [
9+ {
10+ "value": "fred",
11+ "title": "Fred",
12+ "css": "sprite-person",
13+ "description": "fred@example.com",
14+ "api_uri": "~/fred"
15+ },
16+ {
17+ "value": "frieda",
18+ "title": "Frieda",
19+ "css": "sprite-person",
20+ "description": "frieda@example.com",
21+ "api_uri": "~/frieda"
22+ }
23+ ];
24 },
25
26 test_render: function () {
27@@ -65,6 +81,7 @@
28 var assign_me = Y.one('.yui-picker-assign-me-button');
29 assign_me.simulate('click');
30 Y.Assert.areEqual('no-one', data);
31+ personpicker.destroy();
32 },
33
34 test_buttons_config: function () {
35@@ -81,6 +98,27 @@
36 Y.Assert.isUndefined(personpicker.remove_button);
37 Y.Assert.isUndefined(personpicker.assign_me_button);
38 personpicker.destroy();
39+ },
40+
41+ _change_results: function (picker, no_result) {
42+ // simulates search by setting a value and the result
43+ picker._search_input.set('value', 'foo');
44+ if (no_result) {
45+ picker.set('results', []);
46+ } else {
47+ picker.set('results', this.vocabulary);
48+ }
49+ },
50+
51+ test_buttons_vanish: function () {
52+ personpicker = new Y.lp.app.widgets.PersonPicker(cfg);
53+ personpicker.render();
54+ this._change_results(personpicker, false);
55+ Y.Assert.isTrue(personpicker._extra_buttons.hasClass('unseen'));
56+
57+ this._change_results(personpicker, true);
58+ Y.Assert.isFalse(personpicker._extra_buttons.hasClass('unseen'));
59+ personpicker.destroy();
60 }
61 }));
62
63
64=== modified file 'lib/lp/app/javascript/widgets.js'
65--- lib/lp/app/javascript/widgets.js 2011-06-30 08:31:37 +0000
66+++ lib/lp/app/javascript/widgets.js 2011-06-30 13:58:58 +0000
67@@ -78,6 +78,8 @@
68 var PersonPicker = function() {
69 PersonPicker.superclass.constructor.apply(this, arguments);
70 this._extra_buttons = Y.Node.create('<div class="extra-form-buttons"/>');
71+ Y.after(this._renderPersonPickerUI, this, 'renderUI');
72+ Y.after(this._syncPersonPickerResultsUI, this, 'resultsChange');
73 };
74
75 Y.extend(PersonPicker, namespace.Picker, {
76@@ -128,8 +130,7 @@
77 this.fire('save', {value: name});
78 },
79
80- renderUI: function() {
81- this.constructor.superclass.renderUI.call(this);
82+ _renderPersonPickerUI: function() {
83 var remove_button, assign_me_button;
84
85 if (this._show_remove_button) {
86@@ -157,9 +158,21 @@
87
88 syncUI: function() {
89 // call Picker's sync
90- this.constructor.superclass.syncUI.call(this);
91+ this.constructor.superclass.syncUI.apply(this, arguments);
92 footer_slot = Y.one(footer_label);
93 footer_slot.appendChild(this._extra_buttons);
94+ },
95+
96+ bindUI: function() {
97+ this.constructor.superclass.bindUI.apply(this, arguments);
98+ this.after('resultsChange', function(e) {
99+ var results = this.get('results');
100+ if (this._search_input.get('value') && !results.length) {
101+ this._extra_buttons.removeClass('unseen');
102+ } else {
103+ this._extra_buttons.addClass('unseen');
104+ }
105+ });
106 }
107 });
108 PersonPicker.NAME = 'person-picker';