daybrush / selecto

Selecto.js is a component that allows you to select elements in the drag area using the mouse or touch.
https://daybrush.com/selecto
MIT License
2.04k stars 82 forks source link

Support passing multiple containers for scroll selecting. #115

Closed shrihari-prakash closed 1 year ago

shrihari-prakash commented 1 year ago

Environments

Description

https://user-images.githubusercontent.com/35889246/209068367-b408c5f1-fe9a-4a4f-9fa9-a6e209b5bc67.mp4

I have a selecto object that spans across multiple containers. From the video, what it first looks like is that the first page of both the lists were selected when I selected across multiple divs. However, it looks like the hidden elements in the first list were also selected which is a little weird. If this is the case, it is good to have an option to pass multiple containers into scrollOptions of vue selecto so that when I scroll past the first set, the screen scrolls and when the scroll reaches the end, it selects the second set. Or is it possible to select only the ones that are not scrolled? Do you have other recommendations for such use cases?

daybrush commented 1 year ago

@Shrihari-Prakash

Let's consider it as a feature.

daybrush commented 1 year ago

@Shrihari-Prakash

selecto's new version is released.

use checkOverflow prop to true

shrihari-prakash commented 1 year ago

Hello @daybrush , Thanks for your very quick implementation. Appreciate the effort. I can confirm that this is working well and hidden items are not selected anymore. Do you suggest anything about having multiple containers supported on scrollable divs?That is, passing an array of containers in scrollOptions.container or something similar?

daybrush commented 1 year ago

@shrihari-prakash

Selecto's new version is released.

use innerScrollOptions prop and @innerScroll event

<Selecto
   :innerScrollOptions="true"
   @innerScroll="onInnerScroll"
  />
export default {
  methods: {
     onInnerScroll({ container, direction }) {
        console.log("inner");
        container.scrollBy(direction[0] * 10, direction[1] * 10);
    },
  },
}
jonlepage commented 1 year ago

@daybrush am also looking for this feature, but it seem not a fix on my side :( is it possible to use the dragcontainer for detect scroll ? image

because innerScroll seem log random child elements elements ! image

jonlepage commented 1 year ago

actualy this hack work image

jonlepage commented 1 year ago

@daybrush my bad something wrong and i really not understand !! just spend ~3hour to understand the issue without success. 9924t2g

current code:

/**
     * creer une Selecto instance attacher a un dom element
     * @param id - id de la selecto instance {SelectoId}
     * @param dragContainer - dom element qui sera le container de drag, le selecto fonctionera seulement si le mouse est dans ce container
     * @param options - options de la selecto instance
     */
    public create( id:SelectoId, dragContainer:HTMLDivElement, options?: Partial<SelectoOptions> ) {
        // test hack for allow scroll in fieldset element
        const dragContainer2 = [...dragContainer.querySelectorAll( 'fieldset' )];
        const { selectorsMap } = this;

        const counter = createCounterElement(); // just for ux design.
        const selecto = new Selecto({
            // The container to add a selection element
            container: document.body,
            dragContainer:dragContainer2,

            // Targets to select. You can register a queryselector or an Element.
            selectableTargets: [`.${CLASS_NAME_SELECTABLE}`],

            // Whether to select by click (default: true)
            selectByClick: true,

            // Whether to select from the target inside (default: true)
            selectFromInside: true,

            // After the select, whether to select the next target with the selected target (deselected if the target is selected again).
            continueSelect: true,

            // Determines which key to continue selecting the next target via keydown and keyup.
            toggleContinueSelect: 'shift',

            // The container for keydown and keyup events
            keyContainer: window,
            toggleContinueSelectWithoutDeselect: 'alt', // Determines which key to continue selecting the next target via keydown and keyup without deselecting.
            continueSelectWithoutDeselect: true, // After the select, whether to select the next target with the selected target (not deselected if the target is selected again).
            // The rate at which the target overlaps the drag area to be selected. (default: 100)
            hitRate: 10,
            ratio: 0,
            preventRightClick:false,

            checkOverflow : true,
            scrollOptions: {
                container: dragContainer,
                throttleTime: 30,
                threshold: 0,
                useScroll: true,
            },

            ...options,
        })
            .on( 'dragStart', ( e ) => {
                selecto.scrollOptions.container = e.inputEvent.currentTarget as HTMLElement;
                document.getElementsByClassName( 'selecto-selection' )[0].appendChild( counter );
            })
            .on( 'select', ( e ) => {
                counter.innerHTML = e.selected.length.toString();
                gsap.fromTo( counter, { scale: 2 }, { scale: 1, duration: .4, ease: 'back.out(1.7)' });
            })
            .on( 'scroll', ( e ) => {
                e.container.scrollBy( e.direction[0] * 20, e.direction[1] * 20 );
            });

        selectorsMap.set( id, selecto );
        return selecto;
    }