Merge lp:~rvb/maas/all-js-select into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 1509
Proposed branch: lp:~rvb/maas/all-js-select
Merge into: lp:~maas-committers/maas/trunk
Prerequisite: lp:~rvb/maas/api-commission
Diff against target: 46 lines (+21/-2)
2 files modified
src/maasserver/templates/maasserver/node_list.html (+19/-0)
src/maasserver/templates/maasserver/nodes_listing.html (+2/-2)
To merge this branch: bzr merge lp:~rvb/maas/all-js-select
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+167019@code.launchpad.net

Commit message

Add a way to select/deselect all the nodes on the node listing page with just one click.

Description of the change

As discussed this morning, there is no test for this because putting this into a YUI widget does not make sense (it's too heavyweight) and we currently don't have a clean way to test this (it would require a level of unit-testing capability we currently don't have).

I'm currently researching into how we can test this: the poor man's solution is to check that the selectors in the JS code match the HTML code. I /think/ using Django 1.4 Selenium integration would be much better but I need to make sure it's possible.

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

I think #2 needs consideration.

[1]

+      Y.one('#all_system_id_control').on('click', function(e) {

I think it would make sense to respond to 'change' here instead of
'click'.

[2]

+        <th><input type="checkbox" id="all_system_id_control" /></th>

What happens if this is checked, then someone deselects one of the row
checkboxes? This will stay checked. That's counter to the behaviour
I'm used to for these things.

review: Needs Information
Revision history for this message
Raphaël Badin (rvb) wrote :

> I think #2 needs consideration.
>
>
> [1]
>
> +      Y.one('#all_system_id_control').on('click', function(e) {
>
> I think it would make sense to respond to 'change' here instead of
> 'click'.

Good idea. Probably equivalent in this case, but 'change' is clearer.

> [2]
>
> +        <th><input type="checkbox" id="all_system_id_control" /></th>
>
> What happens if this is checked, then someone deselects one of the row
> checkboxes? This will stay checked. That's counter to the behaviour
> I'm used to for these things.

Hum, that's a good point but what kind of behavior do you suggest instead?

Revision history for this message
Gavin Panella (allenap) wrote :

>> [2]
>>
>> +        <th><input type="checkbox" id="all_system_id_control" /></th>
>>
>> What happens if this is checked, then someone deselects one of the row
>> checkboxes? This will stay checked. That's counter to the behaviour
>> I'm used to for these things.
>
> Hum, that's a good point but what kind of behavior do you suggest instead?

I suggest: the select-all checkbox should only be checked if all the
row checkboxes are selected too. Something like:

      var selectAll = Y.one('#all_system_id_control');
      var checkboxes = Y.all('#node_list>input[type=checkbox]');
      checkboxes.on('change', function(e) {
        var notChecked = checkboxes.filter('input:not(:checked)');
        selectAll.set('checked', notChecked.size() == 0);
      });

perhaps?

Revision history for this message
Raphaël Badin (rvb) wrote :

> >> [2]
> >>
> >> +        <th><input type="checkbox" id="all_system_id_control" /></th>
> >>
> >> What happens if this is checked, then someone deselects one of the row
> >> checkboxes? This will stay checked. That's counter to the behaviour
> >> I'm used to for these things.
> >
> > Hum, that's a good point but what kind of behavior do you suggest instead?
>
> I suggest: the select-all checkbox should only be checked if all the
> row checkboxes are selected too. Something like:
>
>      var selectAll = Y.one('#all_system_id_control');
>      var checkboxes = Y.all('#node_list>input[type=checkbox]');
>      checkboxes.on('change', function(e) {
>        var notChecked = checkboxes.filter('input:not(:checked)');
>        selectAll.set('checked', notChecked.size() == 0);
>      });
>
> perhaps?

Makes sense… it's sort of what gmail does (although the control in JS is much more fancy). Done.

Revision history for this message
Gavin Panella (allenap) wrote :

Niiiice :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/templates/maasserver/node_list.html'
2--- src/maasserver/templates/maasserver/node_list.html 2013-06-04 07:46:27 +0000
3+++ src/maasserver/templates/maasserver/node_list.html 2013-06-04 07:46:27 +0000
4@@ -25,6 +25,25 @@
5 });
6 });
7 });
8+ // Connect the 'select all' checkbox to all the node checkboxes.
9+ YUI().use('node', function (Y) {
10+ Y.on('load', function() {
11+ var master = Y.one('#all_system_id_control');
12+ var checkboxes = Y.one('table#node_list').all('input[name="system_id"]');
13+ // Uncheck the master checkbox if one of the row checkboxes gets
14+ // unchecked
15+ checkboxes.on('change', function(e) {
16+ var notChecked = checkboxes.filter('input:not(:checked)');
17+ master.set('checked', (notChecked.size() == 0));
18+ });
19+ // Check/uncheck all the row checkboxes if the master checkbox gets
20+ // checked/unchecked.
21+ master.on('change', function(e) {
22+ var checked = e.target.get('checked');
23+ checkboxes.set('checked', checked);
24+ });
25+ });
26+ });
27 // -->
28 </script>
29 {% endblock %}
30
31=== modified file 'src/maasserver/templates/maasserver/nodes_listing.html'
32--- src/maasserver/templates/maasserver/nodes_listing.html 2013-06-04 07:46:27 +0000
33+++ src/maasserver/templates/maasserver/nodes_listing.html 2013-06-04 07:46:27 +0000
34@@ -1,10 +1,10 @@
35 {% if node_list|length %}
36- <table class="list">
37+ <table class="list" id="node_list">
38 <thead>
39 <tr>
40 {% if sorting == "true" %}
41 {% if actions == "true" %}
42- <th></th>
43+ <th><input type="checkbox" id="all_system_id_control" /></th>
44 {% endif %}
45 <th><a href="{{ sort_links.hostname }}"
46 class="{{ sort_classes.hostname }}">