Skip to content
14 changes: 7 additions & 7 deletions netbox/project-static/dist/netbox.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions netbox/project-static/dist/netbox.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions netbox/project-static/src/buttons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { initDepthToggle } from './depthToggle';
import { initMoveButtons } from './moveOptions';
import { initReslug } from './reslug';
import { initSelectAll } from './selectAll';
import { initSelectMultiple } from './selectMultiple';

export function initButtons(): void {
for (const func of [
initDepthToggle,
initConnectionToggle,
initReslug,
initSelectAll,
initSelectMultiple,
initMoveButtons,
]) {
func();
Expand Down
105 changes: 105 additions & 0 deletions netbox/project-static/src/buttons/selectMultiple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { getElements } from '../util';
import { StateManager } from 'src/state';
import { previousPkCheckState } from '../stores';

type PreviousPkCheckState = { element: Nullable<HTMLInputElement> };

/**
* If there is a text selection, removes it.
*/
function removeTextSelection(): void {
window.getSelection()?.removeAllRanges();
}

/**
* Sets the state object passed in to the eventTargetElement object passed in.
*
* @param eventTargetElement HTML Input Element, retrieved from getting the target of the
* event passed in from handlePkCheck()
* @param state PreviousPkCheckState object.
*/
function updatePreviousPkCheckState(
eventTargetElement: HTMLInputElement,
state: StateManager<PreviousPkCheckState>,
): void {
state.set('element', eventTargetElement);
}

/**
* For all checkboxes between eventTargetElement and previousStateElement in elementList, toggle
* "checked" value to eventTargetElement.checked
*
* @param eventTargetElement HTML Input Element, retrieved from getting the target of the
* event passed in from handlePkCheck()
* @param state PreviousPkCheckState object.
*/
function toggleCheckboxRange(
eventTargetElement: HTMLInputElement,
previousStateElement: HTMLInputElement,
elementList: Generator,
): void {
let changePkCheckboxState = false;
for (const element of elementList) {
const typedElement = element as HTMLInputElement;
//Change loop's current checkbox state to eventTargetElement checkbox state
if (changePkCheckboxState === true) {
typedElement.checked = eventTargetElement.checked;
}
//The previously clicked checkbox was above the shift clicked checkbox
if (element === previousStateElement) {
if (changePkCheckboxState === true) {
changePkCheckboxState = false;
return;
}
changePkCheckboxState = true;
typedElement.checked = eventTargetElement.checked;
}
//The previously clicked checkbox was below the shift clicked checkbox
if (element === eventTargetElement) {
if (changePkCheckboxState === true) {
changePkCheckboxState = false;
return;
}
changePkCheckboxState = true;
}
}
}

/**
* IF the shift key is pressed and there is state is not null, toggleCheckboxRange between the
* event target element and the state element.
*
* @param event Mouse event.
* @param state PreviousPkCheckState object.
*/
function handlePkCheck(event: MouseEvent, state: StateManager<PreviousPkCheckState>): void {
const eventTargetElement = event.target as HTMLInputElement;
const previousStateElement = state.get('element');
updatePreviousPkCheckState(eventTargetElement, state);
//Stop if user is not holding shift key
if (!event.shiftKey) {
return;
}
removeTextSelection();
//If no previous state, store event target element as previous state and return
if (previousStateElement === null) {
return updatePreviousPkCheckState(eventTargetElement, state);
}
const checkboxList = getElements<HTMLInputElement>('input[type="checkbox"][name="pk"]');
toggleCheckboxRange(eventTargetElement, previousStateElement, checkboxList);
}

/**
* Initialize table select all elements.
*/
export function initSelectMultiple(): void {
const checkboxElements = getElements<HTMLInputElement>('input[type="checkbox"][name="pk"]');
for (const element of checkboxElements) {
element.addEventListener('click', event => {
removeTextSelection();
//Stop propogation to avoid event firing multiple times
event.stopPropagation();
handlePkCheck(event, previousPkCheckState);
});
}
}
1 change: 1 addition & 0 deletions netbox/project-static/src/stores/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './objectDepth';
export * from './rackImages';
export * from './previousPkCheck';
6 changes: 6 additions & 0 deletions netbox/project-static/src/stores/previousPkCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createState } from '../state';

export const previousPkCheckState = createState<{ element: Nullable<HTMLInputElement> }>(
{ element: null },
{ persist: false },
);