Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding check-box component #11550

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/core_plugins/testbed/public/testbed.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,37 @@
<!-- All markup within the CONTENT section below can be deleted and replaced with whatever markup
you need to demonstate your functionality. Nothing need be preserved. -->
<!-- CONTENT START -->
<table class="kuiTable kuiVerticalRhythm">
<thead>
<tr class="kuiTableRow">
<th class="kuiTableHeaderCell kuiTableHeaderCell--checkBox"></th>
<th class="kuiTableHeaderCell">Item</th>
</tr>
</thead>
<tr
ng-repeat="item in testbed.myItems"
class="kuiTableRow"
>
<td class="kuiTableRowCell kuiTableRowCell--checkBox">
<div class="kuiTableRowCell__liner">
<selectable-row
id="item.id"
is-selected="item.isSelected"
on-select-change="testbed.onSelectChange"
></selectable-row>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thought tbh, from looking at the interface and implementation, wouldn't it make more sense to just call this directive check-box or kui-check-box? I think we'll end up implementing a React component that does the same thing, and we'll probably just call it KuiCheckBox because that's pretty much all it's concerned with. It could be used in a table row, a form, etc.

Copy link
Contributor Author

@ycombinator ycombinator May 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm good with your proposal. It also eliminates the need for another component that I was about to promote into OSS Kibana: selectable-column, which is intended to be used for a "select all" functionality. It makes sense to me that there should be a generic check box component that could be used in various contexts.

So I'm +1 for calling this component check-box (looking through other Angular directives in Kibana, we don't have the kui prefix convention anywhere so I don't want to introduce it now).

@BigFunger Your thoughts before I make this broad change affecting multiple places in this PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not have a problem with it. Don't remember if there was a solid reason for making this two components initially, but the functionality of them does seem to have converged. Let me/us know if you find any weirdness as you implement the change.

</div>
</td>
<td class="kuiTableRowCell">
<div class="kuiTableRowCell__liner">
{{ item.name }}
</div>
</td>
</tr>
</table>

<p class="kuiVerticalRhythm kuiText kuiSubduedText">
{{ testbed.message }}
</p>
<!-- CONTENT END -->

</div>
Expand Down
16 changes: 16 additions & 0 deletions src/core_plugins/testbed/public/testbed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@ import uiRoutes from 'ui/routes';
import template from './testbed.html';
import './testbed.less';

import 'ui/selectable_row';

uiRoutes.when('/testbed', {
template: template,
controllerAs: 'testbed',
controller: class TestbedController {
constructor() {
this.myItems = [
{ id: 1, name: 'foo', isSelected: false },
{ id: 17, name: 'bar', isSelected: true },
{ id: 23, name: 'baz', isSelected: false }
];
}

onSelectChange = (itemId, newIsSelected) => {
const foundItem = this.myItems.find((item) => item.id === itemId);
if (!foundItem) {
return;
}

this.message = `Setting isSelected = ${newIsSelected} for ${foundItem.name}`;
}
}
});
1 change: 1 addition & 0 deletions src/ui/public/selectable_row/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './selectable_row';
6 changes: 6 additions & 0 deletions src/ui/public/selectable_row/selectable_row.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<input
type="checkbox"
class="kuiCheckBox"
ng-click="selectableRow.onSelectChange(selectableRow.id, selectableRow.isSelected)"
ng-model="selectableRow.isSelected"
>
22 changes: 22 additions & 0 deletions src/ui/public/selectable_row/selectable_row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { uiModules } from 'ui/modules';
import template from './selectable_row.html';

const app = uiModules.get('kibana');

app.directive('selectableRow', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this property, do we?

template: template,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could just be template, since the variable assigned as the value is the same name as the property.

scope: {
id: '=',
isSelected: '=',
onSelectChange: '=',
},
controllerAs: 'selectableRow',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may have already settled on a convention about this, but my 2c are that this may not be necessary. IMO the template is just as readable (if not slightly more so) like this:

<input
  type="checkbox"
  class="kuiCheckBox"
  ng-click="this.onSelectChange(this.id, this.isSelected)"
  ng-model="this.isSelected"
>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have an established convention around this in Kibana at the moment.

I think the main pattern we are trying to avoid here is hanging properties directly of $scope in the controller JS code (e.g. $scope.isSelected) and referring to them with their bare names (e.g. isSelected) in the corresponding template. As long as that principle is followed, I'm good with either using this or a named controller via controllerAs in the template.

@BigFunger Do you have a strong opinion either way on this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had received direction from @spalger a while ago to implement controllerAs, and we have consistently applied it across all of the Watcher UI. So all things being equal, I would like to continue down that path unless there is a strong reason not to.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of like the way that this.isSelected mirrors the way it's accessed within the context of the controller, but this in templates normally references $scope, so we would have to use controllerAs: 'this' and that might cause more confusion (especially for people used to accessing $scope with this) than it's worth...

That said, naming is hard. My preference, in order, is:

  1. controllerAs: 'selectableRow'
  2. controllerAs: 'controller'
  3. controllerAs: 'this'

Copy link
Contributor Author

@ycombinator ycombinator May 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Moving @cjcenizal's comment into this thread to keep the discussion flow)

Ah I see. I agree with you Spencer. I think "controllerAs: this" is really
confusing. So I'd be happy with either 1 or 2, or not using controllerAs in
this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the discussion, folks. I'm going with option 1, which means keeping the code in this PR as-is.

bindToController: true,
controller: class SelectableRowController {
}
};
});