Skip to content

Commit

Permalink
Make render method private
Browse files Browse the repository at this point in the history
  • Loading branch information
jshjohnson committed Oct 9, 2018
1 parent 49c6a64 commit 4824958
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 176 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ Or include Choices directly:

```html
<!-- Include base CSS (optional) -->
<link rel="stylesheet" href="public/styles/base.min.css">
<link rel="stylesheet" href="public/assets/styles/base.min.css">
<!-- Include Choices CSS -->
<link rel="stylesheet" href="public/styles/choices.min.css">
<link rel="stylesheet" href="public/assets/styles/choices.min.css">
<!-- Include Choices JavaScript -->
<script src="/public/scripts/choices.min.js"></script>
<script src="/public/assets/scripts/choices.min.js"></script>
```
## Setup

Expand Down
289 changes: 145 additions & 144 deletions src/scripts/choices.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ class Choices {
this.passedElement.value.split(this.config.delimiter),
);
}
this.render = this.render.bind(this);

this._render = this._render.bind(this);
this._onFocus = this._onFocus.bind(this);
this._onBlur = this._onBlur.bind(this);
this._onKeyUp = this._onKeyUp.bind(this);
Expand Down Expand Up @@ -169,8 +170,8 @@ class Choices {
// Set initial state (We need to clone the state because some reducers
// modify the inner objects properties in the state) 🤢
this._initialState = cloneObject(this._store.state);
this._store.subscribe(this.render);
this.render();
this._store.subscribe(this._render);
this._render();
this._addEventListeners();
this.initialised = true;

Expand Down Expand Up @@ -232,32 +233,6 @@ class Choices {
return this;
}

render() {
this._currentState = this._store.state;

const stateChanged =
this._currentState.choices !== this._prevState.choices ||
this._currentState.groups !== this._prevState.groups ||
this._currentState.items !== this._prevState.items;
const shouldRenderChoices = this._isSelectElement;
const shouldRenderItems =
this._currentState.items !== this._prevState.items;

if (!stateChanged) {
return;
}

if (shouldRenderChoices) {
this._renderChoices();
}

if (shouldRenderItems) {
this._renderItems();
}

this._prevState = this._currentState;
}

highlightItem(item, runEvent = true) {
if (!item) {
return this;
Expand Down Expand Up @@ -485,6 +460,123 @@ class Choices {
= Private functions =
============================================= */

_render() {
this._currentState = this._store.state;

const stateChanged =
this._currentState.choices !== this._prevState.choices ||
this._currentState.groups !== this._prevState.groups ||
this._currentState.items !== this._prevState.items;
const shouldRenderChoices = this._isSelectElement;
const shouldRenderItems =
this._currentState.items !== this._prevState.items;

if (!stateChanged) {
return;
}

if (shouldRenderChoices) {
this._renderChoices();
}

if (shouldRenderItems) {
this._renderItems();
}

this._prevState = this._currentState;
}

_renderChoices() {
const { activeGroups, activeChoices } = this._store;
let choiceListFragment = document.createDocumentFragment();

this.choiceList.clear();

if (this.config.resetScrollPosition) {
requestAnimationFrame(() => this.choiceList.scrollToTop());
}

// If we have grouped options
if (activeGroups.length >= 1 && !this._isSearching) {
// If we have a placeholder choice along with groups
const activePlaceholders = activeChoices.filter(
activeChoice =>
activeChoice.placeholder === true && activeChoice.groupId === -1,
);
if (activePlaceholders.length >= 1) {
choiceListFragment = this._createChoicesFragment(
activePlaceholders,
choiceListFragment,
);
}
choiceListFragment = this._createGroupsFragment(
activeGroups,
activeChoices,
choiceListFragment,
);
} else if (activeChoices.length >= 1) {
choiceListFragment = this._createChoicesFragment(
activeChoices,
choiceListFragment,
);
}

// If we have choices to show
if (
choiceListFragment.childNodes &&
choiceListFragment.childNodes.length > 0
) {
const activeItems = this._store.activeItems;
const canAddItem = this._canAddItem(activeItems, this.input.value);

// ...and we can select them
if (canAddItem.response) {
// ...append them and highlight the first choice
this.choiceList.append(choiceListFragment);
this._highlightChoice();
} else {
// ...otherwise show a notice
this.choiceList.append(this._getTemplate('notice', canAddItem.notice));
}
} else {
// Otherwise show a notice
let dropdownItem;
let notice;

if (this._isSearching) {
notice = isType('Function', this.config.noResultsText)
? this.config.noResultsText()
: this.config.noResultsText;

dropdownItem = this._getTemplate('notice', notice, 'no-results');
} else {
notice = isType('Function', this.config.noChoicesText)
? this.config.noChoicesText()
: this.config.noChoicesText;

dropdownItem = this._getTemplate('notice', notice, 'no-choices');
}

this.choiceList.append(dropdownItem);
}
}

_renderItems() {
const activeItems = this._store.activeItems || [];
this.itemList.clear();

if (activeItems.length) {
// Create a fragment to store our list items
// (so we don't have to update the DOM for each item)
const itemListFragment = this._createItemsFragment(activeItems);

// If we have items to add, append them
if (itemListFragment.childNodes) {
this.itemList.append(itemListFragment);
}
}
}

_createGroupsFragment(groups, choices, fragment) {
const groupFragment = fragment || document.createDocumentFragment();
const getGroupChoices = group =>
Expand Down Expand Up @@ -793,6 +885,30 @@ class Choices {
}
}

_handleSearch(value) {
if (!value || !this.input.isFocussed) {
return;
}

const choices = this._store.choices;
const { searchFloor, searchChoices } = this.config;
const hasUnactiveChoices = choices.some(option => !option.active);

// Check that we have a value to search and the input was an alphanumeric character
if (value && value.length >= searchFloor) {
const resultCount = searchChoices ? this._searchChoices(value) : 0;
// Trigger search event
this.passedElement.triggerEvent(EVENTS.search, {
value,
resultCount,
});
} else if (hasUnactiveChoices) {
// Otherwise reset choices to active
this._isSearching = false;
this._store.dispatch(activateChoices(true));
}
}

_canAddItem(activeItems, value) {
let canAddItem = true;
let notice = isType('Function', this.config.addItemText)
Expand Down Expand Up @@ -916,30 +1032,6 @@ class Choices {
return results.length;
}

_handleSearch(value) {
if (!value || !this.input.isFocussed) {
return;
}

const choices = this._store.choices;
const { searchFloor, searchChoices } = this.config;
const hasUnactiveChoices = choices.some(option => !option.active);

// Check that we have a value to search and the input was an alphanumeric character
if (value && value.length >= searchFloor) {
const resultCount = searchChoices ? this._searchChoices(value) : 0;
// Trigger search event
this.passedElement.triggerEvent(EVENTS.search, {
value,
resultCount,
});
} else if (hasUnactiveChoices) {
// Otherwise reset choices to active
this._isSearching = false;
this._store.dispatch(activateChoices(true));
}
}

_addEventListeners() {
document.addEventListener('keyup', this._onKeyUp);
document.addEventListener('keydown', this._onKeyDown);
Expand Down Expand Up @@ -1960,97 +2052,6 @@ class Choices {
: false;
}

_renderChoices() {
const { activeGroups, activeChoices } = this._store;
let choiceListFragment = document.createDocumentFragment();

this.choiceList.clear();

if (this.config.resetScrollPosition) {
requestAnimationFrame(() => this.choiceList.scrollToTop());
}

// If we have grouped options
if (activeGroups.length >= 1 && !this._isSearching) {
// If we have a placeholder choice along with groups
const activePlaceholders = activeChoices.filter(
activeChoice =>
activeChoice.placeholder === true && activeChoice.groupId === -1,
);
if (activePlaceholders.length >= 1) {
choiceListFragment = this._createChoicesFragment(
activePlaceholders,
choiceListFragment,
);
}
choiceListFragment = this._createGroupsFragment(
activeGroups,
activeChoices,
choiceListFragment,
);
} else if (activeChoices.length >= 1) {
choiceListFragment = this._createChoicesFragment(
activeChoices,
choiceListFragment,
);
}

// If we have choices to show
if (
choiceListFragment.childNodes &&
choiceListFragment.childNodes.length > 0
) {
const activeItems = this._store.activeItems;
const canAddItem = this._canAddItem(activeItems, this.input.value);

// ...and we can select them
if (canAddItem.response) {
// ...append them and highlight the first choice
this.choiceList.append(choiceListFragment);
this._highlightChoice();
} else {
// ...otherwise show a notice
this.choiceList.append(this._getTemplate('notice', canAddItem.notice));
}
} else {
// Otherwise show a notice
let dropdownItem;
let notice;

if (this._isSearching) {
notice = isType('Function', this.config.noResultsText)
? this.config.noResultsText()
: this.config.noResultsText;

dropdownItem = this._getTemplate('notice', notice, 'no-results');
} else {
notice = isType('Function', this.config.noChoicesText)
? this.config.noChoicesText()
: this.config.noChoicesText;

dropdownItem = this._getTemplate('notice', notice, 'no-choices');
}

this.choiceList.append(dropdownItem);
}
}

_renderItems() {
const activeItems = this._store.activeItems || [];
this.itemList.clear();

if (activeItems.length) {
// Create a fragment to store our list items
// (so we don't have to update the DOM for each item)
const itemListFragment = this._createItemsFragment(activeItems);

// If we have items to add, append them
if (itemListFragment.childNodes) {
this.itemList.append(itemListFragment);
}
}
}

/* ===== End of Private functions ====== */
}

Expand Down
Loading

0 comments on commit 4824958

Please sign in to comment.