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

set limitation to select #9

Open
pishguy opened this issue Apr 19, 2020 · 11 comments
Open

set limitation to select #9

pishguy opened this issue Apr 19, 2020 · 11 comments

Comments

@pishguy
Copy link

pishguy commented Apr 19, 2020

in this library how can i set limited selected items? for example user can't select more than 10 items?

@hcbpassos
Copy link
Owner

Such feature is not supported yet, but we can work around that by undoing any changes that lead to selecting above the limit. Please take this example:

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  static const selectionLimit = 10;

  final controller = DragSelectGridViewController();
  Selection currentSelection;

  @override
  void initState() {
    super.initState();
    controller.addListener(handleSelectionChange);
  }

  @override
  void dispose() {
    controller.removeListener(handleSelectionChange);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: SelectionAppBar(
        selection: controller.selection,
        title: const Text('Grid Example'),
      ),
      body: DragSelectGridView(
        gridController: controller,
        padding: const EdgeInsets.all(8),
        itemCount: 90,
        itemBuilder: (context, index, selected) {
          return SelectableItem(
            index: index,
            color: Colors.blue,
            selected: selected,
          );
        },
        gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
          maxCrossAxisExtent: 150,
          crossAxisSpacing: 8,
          mainAxisSpacing: 8,
        ),
      ),
    );
  }

  void handleSelectionChange() {
    if (controller.selection.amount > selectionLimit) {
      setState(() => controller.selection = currentSelection);
    } else {
      setState(() {
        currentSelection = Selection(
          Set.of(controller.selection.selectedIndexes),
        );
      });
    }
  }
}

@Loopex2019
Copy link

Loopex2019 commented Apr 21, 2020

You can set a maximum parameter to your Grid Widget like that :
GridWidget( maximum: 15, ).
By creating the selected item Widget ( which you can find in the example ) , you can
then add a bool named parameter , which checks if your selection list reached the maximum like that :

 SelectableItem(
            isMaximum: _selectedList.length == widget.maximum,
            whenSelcted: () { },
            whenUnselected: ()  { },
)

Then in the SelectableItem Widget you can check this condition in the didUpdateWidget method like that :

@override
void didUpdateWidget(SelectableItem oldWidget) {
 super.didUpdateWidget(oldWidget);
 if (oldWidget.selected != widget.selected) {
   if (widget.selected) {
     if (widget.isMaximum == false) {
       _controller.forward();
       widget.whenSelcted();
     } else {
       Fluttertoast.showToast(msg: 'You\'ve reached the maximum');
     }
   } else {
     _controller.reverse();
     widget.whenUnselected();
   }
 }
}

@pishguy
Copy link
Author

pishguy commented Apr 21, 2020

@Loopex2019 could you reformat your code?

and GridWidget in library source? i should change that handly?

@Loopex2019
Copy link

No gridview is just an example. I mean it is the widget you created , which its build method return the DragSelectGridView widget

@ghost
Copy link

ghost commented Apr 21, 2020

@Loopex2019 I appreciate your suggestion, but it is not correct. Not calling _controller.forward(); only avoids the selection animation, it doesn't make the item in fact unselected.

The only way to unselect an item is through DragSelectGridViewController.selection, as I suggested above :)

@MahdiPishguy Have you tried that?

@Loopex2019
Copy link

@hugocbpassos thanks for explaining to me . This actually worked for me. Because in the whenSelected() Method it adds the selected item into a list . So by checking the maximum it doesn't only prevent the controller from animating but also prevents the whenSelected() Method from being fired . But of course you are right since the selection itself doesn't change .

@ghost
Copy link

ghost commented Apr 21, 2020

So by checking the maximum it doesn't only prevent the controller from animating but also prevents the whenSelected() Method from being fired .

The thing is, the item is already selected when State.didUpdateWidget() is called, so not firing whenSelected() won't actually help :)

By the way, those callbacks (whenSelected() and whenUnselected()) made me worry. DragSelectGridViewController should be able to handle selection by itself. There's no need to duplicate such logic.

Furthermore, for semantic purposes, the only information SelectableItem should receive is selected.

@Loopex2019
Copy link

@hugocbpassos don't worry it's just a callback when the item gets selected to add my custom logic for adding the selected items inside a List variable.

@ghost
Copy link

ghost commented Apr 21, 2020

@Loopex2019 You should be doing that with DragSelectGridViewController.addListener().

@Loopex2019
Copy link

Ah okay thanks for clarifying

@pishguy
Copy link
Author

pishguy commented Apr 21, 2020

@Loopex2019 I appreciate your suggestion, but it is not correct. Not calling _controller.forward(); only avoids the selection animation, it doesn't make the item in fact unselected.

The only way to unselect an item is through DragSelectGridViewController.selection, as I suggested above :)

@MahdiPishguy Have you tried that?

i test this source code which that is here #9 (comment)

its work fine :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants