FEATURE: improves select-box to support category selection on new topic

This commit is contained in:
Joffrey JAFFEUX 2017-08-23 15:08:19 +02:00 committed by GitHub
parent 7c15b27a90
commit 7b4e302677
18 changed files with 439 additions and 173 deletions

View File

@ -36,11 +36,11 @@
<h3>{{i18n "admin.customize.theme.color_scheme"}}</h3>
<p>{{i18n "admin.customize.theme.color_scheme_select"}}</p>
<p>{{d-select-box content=colorSchemes
textKey="name"
filterable=true
value=colorSchemeId
icon="paint-brush"}}
<p>{{select-box content=colorSchemes
textKey="name"
filterable=true
value=colorSchemeId
icon="paint-brush"}}
{{#if colorSchemeChanged}}
{{d-button action="changeScheme" class="btn-primary btn-small submit-edit" icon="check"}}
{{d-button action="cancelChangeScheme" class="btn-small cancel-edit" icon="times"}}

View File

@ -0,0 +1,107 @@
import SelectBoxComponent from "discourse/components/select-box";
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
import { observes, on } from 'ember-addons/ember-computed-decorators';
import PermissionType from 'discourse/models/permission-type';
import Category from 'discourse/models/category';
export default SelectBoxComponent.extend({
classNames: ["category-select-box"],
textKey: "name",
filterable: true,
castInteger: true,
width: '100%',
@on("willInsertElement")
@observes("selectedContent")
_setHeaderText: function() {
let headerText;
if (Ember.isNone(this.get("selectedContent"))) {
if (this.siteSettings.allow_uncategorized_topics) {
headerText = Ember.get(Category.findUncategorized(), this.get("textKey"));
} else {
headerText = I18n.t("category.choose");
}
} else {
headerText = this.get("selectedContent.text");
}
this.set("headerText", headerText);
},
// original method is kept for compatibility
selectBoxRowTemplate: function() {
return (rowComponent) => this.rowContentTemplate(rowComponent.get("content"));
}.property(),
@observes("scopedCategoryId", "categories")
_scopeCategories() {
let scopedCategoryId = this.get("scopedCategoryId");
const categories = this.get("categories");
// Always scope to the parent of a category, if present
if (scopedCategoryId) {
const scopedCat = Category.findById(scopedCategoryId);
scopedCategoryId = scopedCat.get("parent_category_id") || scopedCat.get("id");
}
const excludeCategoryId = this.get("excludeCategoryId");
const filteredCategories = categories.filter(c => {
const categoryId = c.get("id");
if (scopedCategoryId && categoryId !== scopedCategoryId && c.get("parent_category_id") !== scopedCategoryId) { return false; }
if (excludeCategoryId === categoryId) { return false; }
return c.get("permission") === PermissionType.FULL;
});
this.set("content", filteredCategories);
},
@on("init")
@observes("site.sortedCategories")
_updateCategories() {
if (!this.get("categories")) {
const categories = Discourse.SiteSettings.fixed_category_positions_on_create ?
Category.list() :
Category.listByActivity();
this.set("categories", categories);
}
},
rowContentTemplate(item) {
let category;
let result = '<div class="category-status">';
// If we have no id, but text with the uncategorized name, we can use that badge.
if (Ember.isEmpty(item.id)) {
const uncat = Category.findUncategorized();
if (uncat && uncat.get("name") === item.text) {
category = uncat;
}
} else {
category = Category.findById(parseInt(item.id,10));
}
if (!category) return item.text;
result += categoryBadgeHTML(category, {link: false, allowUncategorized: true, hideParent: true});
const parentCategoryId = category.get("parent_category_id");
if (parentCategoryId) {
result += categoryBadgeHTML(Category.findById(parentCategoryId), {link: false}) + "&nbsp;" + result;
}
result += ` <span class='topic-count'>&times; ${category.get("topic_count")}</span></div>`;
const description = category.get("description");
// TODO wtf how can this be null?;
if (description && description !== 'null') {
result += `<div class="category-desc">${description.substr(0, 200)}${description.length > 200 ? '&hellip;' : ''}</div>`;
}
return result;
}
});

View File

@ -1,7 +0,0 @@
import SelectBoxComponent from "discourse/components/select-box";
export default SelectBoxComponent.extend({
layoutName: "components/select-box",
classNames: "discourse"
});

View File

@ -1,17 +1,18 @@
import { on, observes } from "ember-addons/ember-computed-decorators";
import { iconHTML } from 'discourse-common/lib/icon-library';
export default Ember.Component.extend({
layoutName: "components/select-box",
classNames: "select-box",
width: 220,
classNameBindings: ["expanded:is-expanded"],
attributeBindings: ['componentStyle:style'],
componentStyle: function() {
return Ember.String.htmlSafe(`width: ${this.get("maxWidth")}px`);
}.property("maxWidth"),
expanded: false,
focused: false,
tabindex: 0,
caretUpIcon: "caret-up",
caretDownIcon: "caret-down",
@ -19,6 +20,7 @@ export default Ember.Component.extend({
icon: null,
value: null,
selectedContent: null,
noContentText: I18n.t("select_box.no_content"),
lastHoveredId: null,
@ -43,6 +45,31 @@ export default Ember.Component.extend({
renderBody: false,
castInteger: false,
filterFunction: function() {
return (selectBox) => {
const filter = selectBox.get("filter").toLowerCase();
return _.filter(selectBox.get("content"), (content) => {
return content[selectBox.get("textKey")].toLowerCase().indexOf(filter) > -1;
});
};
},
selectBoxRowTemplate: function() {
return (rowComponent) => {
let template = "";
if (rowComponent.get("content.icon")) {
template += iconHTML(Handlebars.escapeExpression(rowComponent.get("content.icon")));
}
template += `<p class="text">${Handlebars.escapeExpression(rowComponent.get("text"))}</p>`;
return template;
};
}.property(),
init() {
this._super();
@ -52,8 +79,7 @@ export default Ember.Component.extend({
this.setProperties({
componentId: this.elementId,
filteredContent: [],
selectedContent: {}
filteredContent: []
});
},
@ -71,9 +97,7 @@ export default Ember.Component.extend({
if (Ember.isEmpty(this.get("filter"))) {
this.set("filteredContent", this._remapContent(this.get("content")));
} else {
const filtered = _.filter(this.get("content"), (content) => {
return content[this.get("textKey")].toLowerCase().indexOf(this.get("filter")) > -1;
});
const filtered = this.filterFunction()(this);
this.set("filteredContent", this._remapContent(filtered));
}
},
@ -95,18 +119,26 @@ export default Ember.Component.extend({
$(document).off("keydown.select-box");
this.$(".select-box-offscreen").off("focusin.select-box");
this.$(".select-box-offscreen").off("focusout.select-box");
this.$(".select-box-offscreen").off("keydown.select-box");
$(window).off("resize.select-box");
},
@on("didRender")
_configureSelectBoxDOM: function() {
this.$().css("width", this.get("width"));
this.$(".select-box-header").css("height", this.$().height());
this.$(".select-box-filter").css("height", this.$().height());
if (this.get("expanded")) {
this.$(".select-box-body").css('width', this.get("maxWidth"));
this.$(".select-box-filter .filter-query").focus();
this.$(".select-box-body").css('width', this.$().width());
this.$(".select-box-collection").css("max-height", this.get("maxCollectionHeight"));
this._bindTab();
this._applyDirection();
this._positionSelectBoxWrapper();
Ember.run.schedule('afterRender', () => {
this._applyDirection();
this._positionSelectBoxWrapper();
});
} else {
$(document).off("keydown.select-box");
this.$(".select-box-wrapper").hide();
@ -124,7 +156,10 @@ export default Ember.Component.extend({
this.set("filteredContent", this._remapContent(this.get("content")));
this._setSelectedContent(this.get("content"));
this.set("headerText", this.get("defaultHeaderText") || this.get("selectedContent.text"));
if (Ember.isNone(this.get("headerText"))) {
this.set("headerText", this.get("selectedContent.text"));
}
},
@on("didInsertElement")
@ -143,9 +178,27 @@ export default Ember.Component.extend({
this.set("focused", true);
});
this.$(".select-box-offscreen").on("keydown.select-box", (event) => {
const keyCode = event.keyCode || event.which;
if(keyCode === 13 || keyCode === 40) {
this.setProperties({expanded: true, focused: false});
return false;
}
if(keyCode === 27) {
this.$(".select-box-offscreen").blur();
return false;
}
});
this.$(".select-box-offscreen").on("focusout.select-box", () => {
this.set("focused", false);
});
$(window).on("resize.select-box", () => {
this.set("expanded", false);
});
},
actions: {
@ -158,6 +211,10 @@ export default Ember.Component.extend({
},
onSelectRow(id) {
if(this.get("castInteger") === true) {
id = parseInt(id, 10);
}
this.setProperties({
value: id,
expanded: false
@ -184,8 +241,13 @@ export default Ember.Component.extend({
},
_normalizeContent(content) {
let id = content[this.get("idKey")];
if(this.get("castInteger") === true) {
id = parseInt(id, 10);
}
return {
id: content[this.get("idKey")],
id,
text: content[this.get("textKey")],
icon: content[this.get("iconKey")]
};
@ -204,7 +266,7 @@ export default Ember.Component.extend({
const headerHeight = this.$(".select-box-header").outerHeight();
this.$(".select-box-wrapper").css({
width: this.get("maxWidth"),
width: this.$().width(),
display: "block",
height: headerHeight + this.$(".select-box-body").outerHeight()
});

View File

@ -1,3 +1,5 @@
import { on, observes } from 'ember-addons/ember-computed-decorators';
export default Ember.Component.extend({
classNames: "select-box-row",
@ -9,6 +11,14 @@ export default Ember.Component.extend({
lastHoveredId: null,
@on("init")
@observes("content", "lastHoveredId", "selectedId", "selectBoxRowTemplate")
_updateTemplate: function() {
this.set("isHighlighted", this._isHighlighted());
this.set("text", this.get("content.text"));
this.set("template", this.get("selectBoxRowTemplate")(this));
},
mouseEnter() {
this.sendAction("onHover", this.get("content.id"));
},

View File

@ -1,13 +1,16 @@
import { observes } from 'ember-addons/ember-computed-decorators';
import DiscourseSelectBoxComponent from "discourse/components/d-select-box";
import SelectBoxComponent from "discourse/components/select-box";
export default SelectBoxComponent.extend({
textKey: "name",
headerText: I18n.t("topic.controls"),
maxCollectionHeight: 300,
export default DiscourseSelectBoxComponent.extend({
init() {
this._super();
this.set("textKey", "name");
this.set("defaultHeaderText", I18n.t("topic.controls"));
this.set("maxCollectionHeight", 300);
this._createContent();
},

View File

@ -99,7 +99,7 @@ function positioningWorkaround($fixedElement) {
fixedElement.style.top = '0px';
composingTopic = $('#reply-control select.category-combobox').length > 0;
composingTopic = $('#reply-control .category-select-box').length > 0;
const height = calcHeight(composingTopic);

View File

@ -4,6 +4,7 @@
aria-haspopup="true"
role="button"
aria-labelledby="select-box-input-{{componentId}}"
tabindex={{tabindex}}
/>
{{component selectBoxHeaderComponent
@ -29,6 +30,7 @@
{{component selectBoxCollectionComponent
filteredContent=filteredContent
selectBoxRowComponent=selectBoxRowComponent
selectBoxRowTemplate=selectBoxRowTemplate
lastHoveredId=lastHoveredId
onSelectRow=(action "onSelectRow")
onHoverRow=(action "onHoverRow")

View File

@ -2,6 +2,7 @@
{{#each filteredContent as |content|}}
{{component selectBoxRowComponent
content=content
selectBoxRowTemplate=selectBoxRowTemplate
lastHoveredId=lastHoveredId
onSelect=onSelectRow
onHover=onHoverRow

View File

@ -1,14 +1,10 @@
<div class="wrapper">
{{input
tabindex="-1"
class="filter-query"
placeholder=filterPlaceholder
key-up=onFilterChange
}}
{{input
tabindex="-1"
class="filter-query"
placeholder=filterPlaceholder
key-up=onFilterChange
}}
{{#if filterIcon}}
<div class="filter-icon">
{{d-icon filterIcon}}
</div>
{{/if}}
</div>
{{#if filterIcon}}
{{d-icon filterIcon}}
{{/if}}

View File

@ -1,7 +1 @@
{{#if content.icon}}
{{d-icon content.icon}}
{{/if}}
<p class="text">
{{content.text}}
</p>
{{{template}}}

View File

@ -72,7 +72,7 @@
{{#if model.showCategoryChooser}}
<div class="category-input">
{{category-chooser valueAttribute="id" value=model.categoryId scopedCategoryId=scopedCategoryId tabindex="3"}}
{{category-select-box valueAttribute="id" value=model.categoryId scopedCategoryId=scopedCategoryId tabindex="3"}}
{{popup-input-tip validation=categoryValidation}}
</div>
{{#if model.archetype.hasOptions}}

View File

@ -0,0 +1,34 @@
.category-select-box.select-box {
height: 34px;
.select-box-row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
line-height: 14px;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
.topic-count {
font-size: 11px;
color: $primary;
}
.category-status {
-webkit-box-flex: 0;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
}
.category-desc {
-webkit-box-flex: 0;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
color: $primary;
font-size: 0.857em;
line-height: 16px;
}
}
}

View File

@ -1,21 +1,53 @@
.select-box {
border-radius: 3px;
box-sizing: border-box;
display: inline-block;
flex-direction: column;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
position: relative;
z-index: 998;
height: 34px;
&.is-expanded {
z-index: 999;
.select-box-wrapper {
border: 1px solid $tertiary;
border-radius: 3px;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
}
.select-box-body {
border-radius: 3px 3px 0 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
left: 0;
position: absolute;
top: 0;
}
.collection, {
border-radius: 0 0 3px 3px;
}
}
&.is-highlighted {
.select-box-header {
border: 1px solid $tertiary;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
}
}
&.is-reversed {
@ -37,35 +69,52 @@
.select-box-header {
background: $secondary;
border: 1px solid transparent;
box-sizing: border-box;
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
border-radius: 3px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
cursor: pointer;
height: 32px;
outline: none;
&.is-focused {
border: 1px solid $tertiary;
border-radius: 3px;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
}
}
.select-box-body {
display: none;
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.select-box-row {
cursor: pointer;
outline: none;
padding: 5px;
height: 28px;
min-height: 28px;
line-height: 28px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
align-items: center;
justify-content: flex-start;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.select-box-collection {
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex: 1;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
background: $secondary;
overflow-x: hidden;
overflow-y: auto;
@ -86,7 +135,8 @@
left: 0;
background: none;
display: none;
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
pointer-events: none;
border: 1px solid transparent;
}
@ -95,17 +145,28 @@
.select-box .select-box-header {
.wrapper {
height: inherit;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
padding-left: 10px;
padding-right: 10px;
}
.current-selection {
text-align: left;
flex: 1;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
@ -128,7 +189,9 @@
}
.select-box .select-box-collection {
flex: 0 1 auto;
-webkit-box-flex: 0;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
.collection {
padding: 0;
@ -144,8 +207,6 @@
cursor: pointer;
border-radius: 5px;
background: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%));
-webkit-transition: color .2s ease;
transition: color .2s ease;
}
&::-webkit-scrollbar-track {
@ -155,6 +216,9 @@
}
.select-box .select-box-row {
margin: 5px;
min-height: 1px;
.d-icon {
margin-right: 5px;
}
@ -171,26 +235,30 @@
}
.select-box .select-box-filter {
.wrapper {
display: flex;
align-items: center;
justify-content: space-between;
margin: 5px 10px;
}
background: $secondary;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
padding: 0 10px;
input, input:focus {
margin: 0;
flex: 1;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
outline: none;
border: 0;
box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
width: 100%;
padding: 5px 0;
}
.icon {
margin-right: 5px;
}
}
.select-box .select-box-offscreen, .select-box .select-box-offscreen:focus {

View File

@ -162,7 +162,7 @@
padding-left: 7px;
}
.control-row {
margin: 0 0 0 5px;
margin: 0 5px 0 5px;
}
.saving-text {
display: none;
@ -221,14 +221,9 @@
.contents {
input#reply-title {
padding: 7px 10px;
margin: 6px 10px 3px 0;
margin-bottom: 0;
color: $primary;
}
input#reply-title {
width: 400px;
color: $primary;
}
.wmd-controls {
transition: top 0.3s ease;
@ -242,34 +237,13 @@
min-width: 1280px;
.form-element {
position: relative;
display: inline-block;
.select2-container {
width: 400px;
margin-top: 5px;
a {
padding-top: 4px;
height: 28px;
}
b {
margin-top: 4px;
}
}
.category-combobox {
display: flex;
.category-input {
width: 430px;
@include medium-width { width: 285px; }
@include small-width { width: 220px; }
.select2-drop {
left: -9000px;
width: 428px;
@include medium-width { width: 283px; }
@include small-width { width: 218px; }
}
.select2-search input {
width: 378px;
@include medium-width { width: 233px; }
@include small-width { width: 168px; }
}
}
}
.edit-reason-input {
@ -286,7 +260,7 @@
}
#reply-title {
color: $primary;
margin-right: 10px;
margin-right: 5px;
float: left;
&:disabled {
background-color: $primary-low;

View File

@ -19,7 +19,7 @@ input {
padding: 4px;
border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(0,0,0, .3);
border: 1px solid $primary-low;
border: 1px solid $primary-low;
}
input[type=radio], input[type=checkbox] {
box-shadow: none;
@ -38,7 +38,7 @@ input[type=radio], input[type=checkbox] {
width: 100%;
z-index: 1039;
height: 0;
background-color: $primary-low;
background-color: $primary-low;
bottom: 0;
font-size: 1em;
position: fixed;
@ -58,7 +58,7 @@ input[type=radio], input[type=checkbox] {
line-height: 30px;
}
.control-row {
margin: 0 0 0 5px;
margin: 0 5px 0 5px;
.reply-to {
overflow: hidden;
max-width: 80%;
@ -88,7 +88,7 @@ input[type=radio], input[type=checkbox] {
&.draft {
height: 35px !important;
cursor: pointer;
border-top: 1px solid $primary-low;
border-top: 1px solid $primary-low;
.draft-text {
display: block;
position: absolute;
@ -122,10 +122,17 @@ input[type=radio], input[type=checkbox] {
input#reply-title {
padding: 5px;
margin-top: 6px;
width: 99%;
width: 100%;
box-sizing: border-box;
border: 1px solid $secondary;
}
.category-input {
margin-top: 3px;
.category-select-box {
height: 28px;
}
}
.wmd-controls {
transition: top 0.3s ease;
top: 110px;
@ -134,20 +141,7 @@ input[type=radio], input[type=checkbox] {
}
.contents {
padding: 8px 5px 0 5px;
.form-element {
.select2-container {
width: 99%;
margin-top: 6px;
a {
padding-top: 4px;
height: 28px;
}
b {
margin-top: 4px;
}
}
}
.edit-reason-input, .display-edit-reason {
display: none;
}
@ -194,12 +188,6 @@ input[type=radio], input[type=checkbox] {
}
}
}
.category-input {
// hack, select2 is using inline styles
.select2-container {
width: 99% !important;
}
}
.popup-tip .close {
padding: 0 2px 2px 8px; // so my fingers can touch the little x
}

View File

@ -99,7 +99,7 @@ QUnit.test("Reply as new topic", assert => {
"it fills composer with the ring string"
);
assert.equal(
find('.category-combobox').select2('data').text, "feature",
find('.category-select-box .select-box-header .current-selection').html().trim(), "feature",
"it fills category selector with the right category"
);
});

View File

@ -33,7 +33,7 @@ componentTest('accepts a value by reference', {
andThen(() => {
assert.equal(
this.$(".select-box-row.is-highlighted .text").html().trim(), "robin",
find(".select-box-row.is-highlighted .text").html().trim(), "robin",
"it highlights the row corresponding to the value"
);
});
@ -79,7 +79,7 @@ componentTest('no default icon', {
template: '{{select-box}}',
test(assert) {
assert.equal(this.$(".select-box-header .icon").length, 0, "it doesnt have an icon if not specified");
assert.equal(find(".select-box-header .icon").length, 0, "it doesnt have an icon if not specified");
}
});
@ -87,7 +87,7 @@ componentTest('customisable icon', {
template: '{{select-box icon="shower"}}',
test(assert) {
assert.equal(this.$(".select-box-header .icon").html().trim(), "<i class=\"fa fa-shower d-icon d-icon-shower\"></i>", "it has a the correct icon");
assert.equal(find(".select-box-header .icon").html().trim(), "<i class=\"fa fa-shower d-icon d-icon-shower\"></i>", "it has a the correct icon");
}
});
@ -98,7 +98,7 @@ componentTest('default search icon', {
click(".select-box-header");
andThen(() => {
assert.equal(find(".select-box-filter .filter-icon").html().trim(), "<i class=\"fa fa-search d-icon d-icon-search\"></i>", "it has a the correct icon");
assert.equal(find(".select-box-filter .d-icon-search").length, 1, "it has a the correct icon");
});
}
});
@ -122,7 +122,7 @@ componentTest('custom search icon', {
click(".select-box-header");
andThen(() => {
assert.equal(find(".select-box-filter .filter-icon").html().trim(), "<i class=\"fa fa-shower d-icon d-icon-shower\"></i>", "it has a the correct icon");
assert.equal(find(".select-box-filter .d-icon-shower").length, 1, "it has a the correct icon");
});
}
});
@ -145,13 +145,13 @@ componentTest('select-box is expandable', {
click(".select-box-header");
andThen(() => {
assert.equal(this.$(".select-box").hasClass("is-expanded"), true);
assert.equal(find(".select-box").hasClass("is-expanded"), true);
});
click(".select-box-header");
andThen(() => {
assert.equal(this.$(".select-box").hasClass("is-expanded"), false);
assert.equal(find(".select-box").hasClass("is-expanded"), false);
});
}
});
@ -165,10 +165,10 @@ componentTest('accepts custom id/text keys', {
},
test(assert) {
click(this.$(".select-box-header"));
click(".select-box-header");
andThen(() => {
assert.equal(this.$(".select-box-row.is-highlighted .text").html().trim(), "robin");
assert.equal(find(".select-box-row.is-highlighted .text").html().trim(), "robin");
});
}
});
@ -181,12 +181,12 @@ componentTest('doesnt render collection content before first expand', {
},
test(assert) {
assert.equal(this.$(".select-box-body .collection").length, 0);
assert.equal(find(".select-box-body .collection").length, 0);
click(this.$(".select-box-header"));
click(".select-box-header");
andThen(() => {
assert.equal(this.$(".select-box-body .collection").length, 1);
assert.equal(find(".select-box-body .collection").length, 1);
});
}
});
@ -199,42 +199,76 @@ componentTest('persists filter state when expandind/collapsing', {
},
test(assert) {
click(this.$(".select-box-header"));
click(".select-box-header");
fillIn('.filter-query', 'rob');
triggerEvent('.filter-query', 'keyup');
andThen(() => {
assert.equal(this.$(".select-box-row").length, 1);
assert.equal(find(".select-box-row").length, 1);
});
click(this.$(".select-box-header"));
click(".select-box-header");
andThen(() => {
assert.equal(this.$().hasClass("is-expanded"), false);
assert.equal(find(".select-box").hasClass("is-expanded"), false);
});
click(this.$(".select-box-header"));
click(".select-box-header");
andThen(() => {
assert.equal(this.$(".select-box-row").length, 1);
assert.equal(find(".select-box-row").length, 1);
});
}
});
componentTest('supports options to limit size', {
template: '{{select-box maxWidth=100 maxCollectionHeight=20 content=content}}',
template: '{{select-box width=50 maxCollectionHeight=20 content=content}}',
beforeEach() {
this.set("content", [{ id: 1, text: "robin" }]);
},
test(assert) {
assert.equal(this.$(".select-box-header").outerWidth(), 100, "it limits the width");
click(this.$(".select-box-header"));
click(".select-box-header");
andThen(() => {
assert.equal(this.$(".select-box-body").height(), 20, "it limits the height");
assert.equal(find(".select-box-body").height(), 20, "it limits the height");
assert.equal(find(".select-box").width(), 50, "it limits the width");
});
}
});
componentTest('supports custom row template', {
template: '{{select-box content=content selectBoxRowTemplate=selectBoxRowTemplate}}',
beforeEach() {
this.set("content", [{ id: 1, text: "robin" }]);
this.set("selectBoxRowTemplate", (rowComponent) => {
return `<b>${rowComponent.get("text")}</b>`;
});
},
test(assert) {
click(".select-box-header");
andThen(() => {
assert.equal(find(".select-box-row").html().trim(), "<b>robin</b>");
});
}
});
componentTest('supports converting select value to integer', {
template: '{{select-box value=2 content=content castInteger=true}}',
beforeEach() {
this.set("content", [{ id: "1", text: "robin"}, {id: "2", text: "régis" }]);
},
test(assert) {
click(".select-box-header");
andThen(() => {
assert.equal(find(".select-box-row.is-highlighted .text").text(), "régis");
});
}
});