Giter Club home page Giter Club logo

searchable_dropdown's People

Contributors

icemanbsi avatar lcuis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

searchable_dropdown's Issues

Return old value after first select.

Current API Version
searchable_dropdown: ^1.1.3

Flutter Doctor

[✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Mac OS X 10.15.3 19D76, locale en-KH)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4)
[✓] Android Studio (version 3.4)
[✓] VS Code (version 1.44.2)
[✓] Connected device (2 available)

• No issues found!

[Note: The problem is not 100% occurred, but mostly it happens on iOS below 13 and also Android Emulator (API R)]

The problem is

  1. when we first launch the app and selected the value from the dropdown, it returns the correct value back. (exp: Select A and it return A)
  2. But when I try to select a new value [B] from dropdown again, it returns the old value of [A] instead.

It sounds weird, but the problem sometimes disappears when I tried to clean the project a few times.

My BaseDropDownTextField class.
BaseDropDownTextField.log

Error After update ver to 1.1.2

after updating ver to 1.1.2, i can't run the app, because this error :

e: Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
class io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding, unresolved supertypes: androidx.lifecycle.LifecycleOwner
class io.flutter.embedding.engine.FlutterEngine, unresolved supertypes: androidx.lifecycle.LifecycleOwner

e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (3, 28): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (19, 36): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 30): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 57): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (49, 38): Unresolved reference: NonNull

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':searchable_dropdown:compileDebugKotlin'.

Compilation error. See log for more details

how to solve this ? thank you for your hard work

Case insensitivity

Currently, the search widget is case sensitive. It would be better if all searches by default are case insensitive.

Should be able to implement queryBuilder

Instead of filter value from DropdownMenuItem, I think it is better to add query builder which allow user to customize any filter list. For example:

        SearchableDropdown(
              dataList: operators,
              queryBuilder: (String keyword, List<OperatorModel> list) {
                List<int> shownIndexes = [];
                int i = 0;
                list.forEach((item) {
                  if(keyword.isEmpty || item.opeCode.toLowerCase().contains(keyword.trim().toLowerCase())
                      || item.opeName.toLowerCase().contains(keyword.trim().toLowerCase())
                      || item.opeNameEn.toLowerCase().contains(keyword.trim().toLowerCase())){
                    shownIndexes.add(i);
                  }
                  i++;
                });
                return shownIndexes;
              },
              items: operators.map((operator) {
                return DropdownMenuItem<int>(
                  child: Text(operator.opeCode + "-" + operator.opeName),
                  value: operator.opeId
                ); 
              }).toList(),
              value: selectedOperatorId,
              hint: new Text('Select One'),
              searchHint: new Text('Select One', style: new TextStyle(fontSize: 20)),
              onChanged: (value) {
                setState(() {
                  selectedOperatorId = value;
                });
              },
              isExpanded: true,
            )

Searchable dropDown value is changing only once in stateful widget in flutter

Hi, my problem is when i try to select value in searchable dropdown second time then it is not changing remaining same as that in case of ist change , but i can select different value after clearing the value .

code:

SearchableDropdown.single(
items: widget.projectList.cast()

                                      .map<DropdownMenuItem<String>>((String value) {
                                    return DropdownMenuItem<String>(
                                      value: value,
                                      child: Text(value),

                                    );
                                  })
                                      .toList(),
                                  value: dropDownValue,
                                  hint: "Select one",
                                  searchHint: "Select one",
                                  onChanged: (value) {
                                    setState(() {
                                      dropDownValue = value;
                                    });
                                  },
                                  isExpanded: true,
                                  // label: "Select Project",
                                  selectedValueWidgetFn: (item) {
                                    return Container(
                                        transform: Matrix4.translationValues(-10,0,0),
                                        alignment: Alignment.centerLeft,
                                        child: (Text(item.toString())));
                                  },


                                  // style: Theme.of(context).textTheme.title,
                               //   displayClearIcon: false,

                                );

and this code is working perfect in stateless widget but problem coming in stateful widget.

i will be thankful for your solution

Error if removing from `items` the currently selected `value`

If attempting to remove from the items the currently selected value, a RangeError will be thrown.
A very small app to demonstrate this is the following. If you select the last item and then attempt to remove it from the items (clicking the remove last item button) the RangeError will be thrown.

import 'package:flutter/material.dart';
import 'package:searchable_dropdown/searchable_dropdown.dart';

void main() {
  runApp(App());
}

class App extends StatefulWidget {
  App();

  @override
  AppState createState() => AppState();
}

class AppState extends State<App> {
  List<String> _items = ['1', '2', '3'];
  String _selected = '3';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'TestApp',
        home: Material(child: Column(
          children: <Widget>[
            RaisedButton(child: Text('Remove last Item'),onPressed: () => setState(() => _items.removeLast())),
            SearchableDropdown(items: _items.map((e) => DropdownMenuItem(value: e, child: Text(e))).toList(),
            value: _selected, onChanged: (e) => setState(() => _selected = e))
          ],
        )
      )
    );
  }
}

whenever i select the dropdown value in this code cursor(pointer) move to the upper textfield . How to solve this problem??

Column(
children: [

            Padding(
              padding: const EdgeInsets.only(top: 14),
              child: new TextField(

                // maxLengthEnforced: true,
                keyboardType: TextInputType.multiline,
                controller: controller1,
                decoration: new InputDecoration(
                  // contentPadding: EdgeInsets.symmetric(vertical: 26,horizontal: 10),
                    border: OutlineInputBorder(),
                    hintText: "Add Task name Only",
                    labelText: "Add Task name only"
                ),
              ),
            ),
            new SizedBox(
                height:6
            ),

            Column(
              children: <Widget>[

                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    new Text("Select Product:", style: new TextStyle(fontSize: 12),),
                  ],
                ),

                Container(

                  height: 50,
                  width: MediaQuery.of(context).size.width,
                  decoration: ShapeDecoration(

                    shape: RoundedRectangleBorder(

                      side: BorderSide(width: 1.0, style: BorderStyle.solid, color: Colors.blue),
                      borderRadius: BorderRadius.all(Radius.circular(5.0)),
                    ),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal:10.0),
                    child: StatefulBuilder(
                      //stream: null,
                        builder: (BuildContext context, StateSetter setState) {
                          /*  return  DropdownButton<String>(
                            //  hint: Text('Project'),
                              value:applicationDropDown,
                              isExpanded: true,

                              // style: Theme.of(context).textTheme.title,
                              //  icon: Icon(Icons.arrow_drop_down,color: Colors.lightBlue,),

                              onChanged: (String newValue) {
                                setState(() {
                                  applicationDropDown = newValue;
                                });


                              },
                              items: applicationList.cast<String>()

                                  .map<DropdownMenuItem<String>>((String value) {
                                return DropdownMenuItem<String>(
                                  value: value,
                                  child: Text(value),

                                );
                              })
                                  .toList()
                          );        */

                          return SearchableDropdown.single(
                            items: applicationList.cast<String>()

                                .map<DropdownMenuItem<String>>((String value) {
                              return DropdownMenuItem<String>(
                                value: value,
                                child: Text(value, ),

                              );
                            })
                                .toList(),
                            value: applicationDropDown,
                            hint: "Select one",
                            searchHint: "Select one",
                            onChanged: (value) {
                              setState(() {
                                applicationDropDown = value;
                              });
                            },
                            isExpanded: true,
                            // label: "Select Project",

                            selectedValueWidgetFn: (item) {
                              return Container(
                                  transform: Matrix4.translationValues(-10,0,0),
                                  alignment: Alignment.centerLeft,
                                  child: (Text(item.toString())));
                            },

                            // style: Theme.of(context).textTheme.title,
                            displayClearIcon: false,

                          );
                        }
                    ),
                  ),
                ),
              ],
            ),


            Padding(
              padding: const EdgeInsets.only(top:7.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Column(
                    //  mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      new Text("Select Customer:", style: new TextStyle(fontSize: 12),),

                      Container(

                        height: 50,
                        width: MediaQuery.of(context).size.width/2,
                        decoration: ShapeDecoration(

                          shape: RoundedRectangleBorder(

                            side: BorderSide(width: 1.0, style: BorderStyle.solid, color: Colors.blue),
                            borderRadius: BorderRadius.all(Radius.circular(5.0)),
                          ),
                        ),
                        child: Padding(
                          padding: const EdgeInsets.symmetric(horizontal:10.0),
                          child: StatefulBuilder(
                            //stream: null,
                              builder: (BuildContext context, StateSetter setState) {
                                return SearchableDropdown.single(
                                  items: projectList.cast<String>()

                                      .map<DropdownMenuItem<String>>((String value) {
                                    return DropdownMenuItem<String>(
                                      value: value,
                                      child: Text(value, ),

                                    );
                                  })
                                      .toList(),
                                  value: projectDropDown,
                                  hint: "Select one",
                                  searchHint: "Select one",
                                  onChanged: (value) {
                                    setState(() {
                                      projectDropDown = value;
                                    });
                                  },
                                  isExpanded: true,
                                  // label: "Select Project",

                                  selectedValueWidgetFn: (item) {
                                    return Container(
                                        transform: Matrix4.translationValues(-10,0,0),
                                        alignment: Alignment.centerLeft,
                                        child: (Text(item.toString())));
                                  },


                                  // style: Theme.of(context).textTheme.title,
                                  displayClearIcon: false,

                                );
                              }
                          ),
                        ),
                      ),
                    ],

in this code whenever i select any dropdown value cursor move to the add task textfiled. Is there any way to solve this problem. SO that cursor do not move to the textfiled again and again.

will be thankful for your help

Triggering the Selection Dialog from another widget

I'd loved how this widget works but would need the option to trigger the Selection Dialog from a button from my own layout. I could use the callOnPop to handle the selected behavior but I'm not sure how to trigger the Dialog with the SearchableDropdown visibility set to false.
Is there any suggestion in order to use just the Dialog, without the Search field?

Search not working

I have using searchable_dropdown lib, every thing working but searching option not working properly.I am sharing code with some screenshots, lease check help me.

Container(
padding: EdgeInsets.all(10.0),
child: SearchableDropdown.single(
items: _dropdownMenuItemsCamp,
value: selectCamp,
displayClearIcon: false,
isCaseSensitiveSearch: true,
hint: "Select Compaign Type *",
label: Text(
"Select Compaign Type *",
style: TextStyle(color: Colors.black54),
),
searchHint: "Select Compaign Type *",
onChanged: (value) {
setState(() {
selectCamp = value;
});
campType = selectCamp.generalID;
},
underline: Container(
height: 1.0,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.black38, width: 1.0))),
),
searchFn: (String keyword, items) {
List ret = List();
if (keyword != null &&
items != null &&
keyword.isNotEmpty) {
keyword.split(" ").forEach((k) {
int i = 0;
items.forEach((item) {
if (k.isNotEmpty &&
(item.value
.toString()
.toLowerCase()
.contains(k.toLowerCase()))) {
ret.add(i);
}
i++;
});
});
}
if (keyword.isEmpty) {
ret = Iterable.generate(items.length).toList();
}
return (ret);
},
isExpanded: true,
),
)

Screenshot_2020-04-11-08-50-56-080_worldjobsnews com flutter_app
Screenshot_2020-04-11-08-50-49-921_worldjobsnews com flutter_app

Build failed when using searchable_dropdown

I have used the searchable dropdown in one of my pages. My application is working fine in debug mode so I can run it on an emulator. But I'm getting my build failed when trying to build the apk using "flutter build apk" command.

Here is the error log I'm getting.

e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (3, 28): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (19, 36): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 30): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 57): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (49, 38): Unresolved reference: NonNull

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':compileReleaseKotlin'.

Compilation error. See log for more details

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 2s

The plugin searchable_dropdown could not be built due to the issue above.

flutter doctor -v output

[√] Flutter (Channel stable, v1.12.13+hotfix.8, on Microsoft Windows [Version 10.0.18363.752], locale en-US)
• Flutter version 1.12.13+hotfix.8 at C:\flutter
• Framework revision 0b8abb4724 (8 weeks ago), 2020-02-11 11:44:36 -0800
• Engine revision e1e6ced81d
• Dart version 2.7.0

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at C:\Users\tharindu.s.GEVEO\AppData\Local\Android\Sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 29.0.3
• ANDROID_HOME = C:\Users\tharindu.s.GEVEO\AppData\Local\Android\Sdk
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
• All Android licenses accepted.

[!] Android Studio (version 3.6)
• Android Studio at C:\Program Files\Android\Android Studio
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] VS Code (version 1.43.2)
• VS Code at C:\Users\tharindu.s.GEVEO\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.9.1

[√] VS Code, 64-bit edition
• VS Code at C:\Program Files\Microsoft VS Code
• Flutter extension version 3.9.1

[√] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

! Doctor found issues in 1 category.

Search Box fails to render screen in landscape mode

  • I've encountered a problem to render my search box in landscape mode.
  • I believe this occur because the keyboard fills the whole space that should belong to the list of items.
  • How can I fix this?
  • Is there any way to set a minimum height to search box with the list of items?

Screenshot

How to Search data from api list

here is my data list from api


  Future<String> getSWData() async {
    var res = await http .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    var resBody = json.decode(res.body);

    setState(() {
      data = resBody;
    });

    return "Sucess";
  }
`
```
and here is my dropdown 

 ```
 children: <Widget>[
             SearchableDropdown.single(
             hint:Text("Select Country"),
              isExpanded: true,
          items: data.map((item) {
            return  DropdownMenuItem(
             
              child:  Text(item['name']),
              value: item['id'].toString(),
            );
      
          }).toList(),
          onChanged: (newVal) {
            setState(() {
              _countryname = newVal;
              city.clear();
              _myState=null;
              this.getCity(int.parse(_countryname));
            });
          },
          value:_countryname,
        ),
         ],
```

it's load data from api but when i search i m not getting search data is there is any extra step for search? the package should be dynamic like jquery select2

Overflow with long text

Hi,

I tried using your dropdown in my app (two side-by-side), but both of them are overflowing if the text is too long (this was not happening with the DropdownButtonFormField, etc. that I was using before). Here is a screenshot:

searchableDropDownOverflowIssue

Attached is a modified version of your main.dart sample file (renamed to main.txt so that I could attach it).

If you could fix this, it would be great - this is the best drop-down component that I have found so far, apart from this issue.

main.txt

Disabled/Read Only Functionality

Is there any way to disable the dropdown? I noticed the disabled hint but no way to disable the dropdown itself.

Case:
I have a screen with several dropdowns thats reused in multiple places. Sometimes, I need to show whats selected in one dropdown and maintain that value without letting the user change it.

keyboard always show up.

Hi,
first of all, let me thank the developer for this great and useful flutter package.

The keyboard seems to always show up when the dropdownMenu button is pressed. Can it be possible to only show the keyboard when the user presses the search input TextField?

I took a look at the package's code and it seems that autofocus: true is calling the keyboard, right? How to avoid this?

Thanks,
Ricardo

TextStyle does not apply to searchbox

Supplied a text style however this is not being passed through and picked up in the searchbox leading to large dropdown items but a tiny searchbox.
Screenshot 2020-03-31 at 09 34 34

Dropdown not working after deploy

Hi, I was working in local and worked perfectly, but I deployed my app to Firebase Hosting and the dropdown stopped working in all browsers. I have no idea what could be the problem.

Thanks in advance,

Error updating subsequent component

Dear sirs, I have a component that, after selecting an item of type object, loads a list into another subsequent component. The problem occurs when I change the top component and it does not clear the selected item in the subsequent component. How do I clean this selected item? Or is it really a bug?

Here is an excerpt from the code to exemplify

Top component

Container _buildTipoVeiculo() {
    return Container(
      transform: Matrix4.translationValues(0.0, -10.0, -10.0),
      child: Container(
        child: SearchableDropdown.single(
          items: tipoVeiculos,
          value: _anuncioData.tipoVeiculo,
          doneButton: "OK",
          label: _anuncioData.tipoVeiculo != null
              ? Container(
                  child: Text("Tipo de Veículo",
                      style:
                          TextStyle(color: Colors.teal[900], fontSize: 12.0)),
                  transform: Matrix4.translationValues(10.0, 20.0, 0.0))
              : null,
          hint: Padding(
            padding: const EdgeInsets.only(top: 4.0, bottom: 16.0),
            child: Text("Tipo de Veículo"),
          ),
          searchHint: "Selecione um item",
          closeButton: null,
          onChanged: (value) {
            setState(() {
              if (value != _anuncioData.tipoVeiculo) {
                _anuncioData.tipoVeiculo = value;
                _anuncioData.marca = null;
                initMarcas();
              }
            });
          },
          validator: _validateCampoObrigatorio,
          displayItem: (item, selected) {
            return (Row(children: [
              selected
                  ? Icon(
                      Icons.radio_button_checked,
                      color: Colors.grey,
                    )
                  : Icon(
                      Icons.radio_button_unchecked,
                      color: Colors.grey,
                    ),
              SizedBox(width: 7),
              Expanded(
                child: item,
              ),
            ]));
          },
          isExpanded: true,
        ),
      ),
    );
  }

Subsequent component

Container _buildMarca() {
    return Container(
      transform: Matrix4.translationValues(0.0, -10.0, -10.0),
      child: FutureBuilder<List<Marca>>(
          future: _futureMarcas,
          builder: (context, snapshot) {
            if (snapshot.hasError) print(snapshot.error);
            if (_anuncioData == null ||
                _anuncioData.tipoVeiculo == null ||
                snapshot.hasData) {
              return SearchableDropdown.single(
                items: convertDropDownMenuItemMarcas(snapshot),
                value: _anuncioData.marca,
                doneButton: "OK",
                label: _anuncioData.marca != null
                    ? Container(
                        child: Text("Marca",
                            style: TextStyle(
                                color: Colors.teal[900], fontSize: 12.0)),
                        transform: Matrix4.translationValues(10.0, 20.0, 0.0))
                    : null,
                hint: Padding(
                  padding: const EdgeInsets.only(bottom: 10.0),
                  child: Container(
                      child: Text("Marca"),
                      transform: Matrix4.translationValues(0.0, -2.0, 0.0)),
                ),
                searchHint: "Selecione um item",
                closeButton: null,
                onChanged: (value) {
                  if (value != _anuncioData.marca) {
                    setState(() {
                      _anuncioData.marca = value;
                      _anuncioData.modelo = null;
                      initModelos();
                    });
                  }
                },
                validator: _validateCampoObrigatorio,
                displayItem: (item, selected) {
                  return (Row(children: [
                    selected
                        ? Icon(
                            Icons.radio_button_checked,
                            color: Colors.grey,
                          )
                        : Icon(
                            Icons.radio_button_unchecked,
                            color: Colors.grey,
                          ),
                    SizedBox(width: 7),
                    Expanded(
                      child: item,
                    ),
                  ]));
                },
                isExpanded: true,
              );
            } else {
              return CircularProgressIndicator();
            }
          }),
    );
  }

Thanks.

Flutter fails to build (Bad State Element) when using validator method of SearchableDropdown.single widget

Flutter doesn't build my application when I run. It returns the following:-
Error waiting for a debug connection: Bad state: No element

Flutter doctor:-

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.12.13+hotfix.9, on Microsoft Windows [Version 10.0.18362.720], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.6)
[√] VS Code, 64-bit edition (version 1.43.1)
[√] Connected device (1 available)

• No issues found!

The application fails to build only when I add the 'validator:' attribute to the SearchableDropdown.single() widget. I guess the problem is that the SearchableDropdown is validating on the build and not when the validate() method of fomKey.currentState is called. Is there any workaround for this. Please help as this is for a time-sensitive project.

To help anyone reading this issue understand the code that is causing an issue, I've included the widget inside which I'm calling the SearchableDropdown. It is wrapped in a FutureBuilder widget as I call an API to return a list of all countries and to consequently build a List<DropdownMenuItem>, which is passed into the 'items:' attribute of SearchableDropdown.single().

FutureBuilder<List<dynamic>>(
  future: _fetchCountries,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      List<String> countrylist = [];
      List<DropdownMenuItem<String>> countries;
      for (var i = 0; i < snapshot.data.length; i++) {
        countrylist.add(snapshot.data[i]['name']);
      }
      countries = countrylist.map((String value) {
        return new DropdownMenuItem<String>(
          value: value,
          child: Text(
            value,
            style: TextStyle(fontSize: 16),
          ),
        );
      }).toList();
      return SearchableDropdown.single(
          //menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
          dialogBox: true,
          menuBackgroundColor: Colors.white,
          icon: Icon(
            Icons.arrow_drop_down,
            size: 25,
            color: Colors.white,
          ),
          items: countries,
          style: TextStyle(color: Colors.white),
          hint: Padding(
            padding: const EdgeInsets.only(left: 0, right: 0, top: 0, bottom: 15),
            child: Text(
              "Country",
              style: TextStyle(color: Colors.white, fontSize: 16),
            ),
          ),
          value: _country,
          searchHint: "Select a country",
          onChanged: (value) {
            setState(() {
              _country = value;
            });
          },
          isExpanded: true,
          validator: (value) {
            if (value == null) {
              return 'Select a country';
            }
            return null;
          });
    } else if (snapshot.hasError) {
      return Text("${snapshot.error}");
    }
    return CircularProgressIndicator();
  },
),

If anybody can suggest any other methods of validating the SearchableDropdown.single without running into the error, it would be well appreciated.

Check Box select

Hello,

I want in some check box selected by default.

I am getting some data from api, i want to match list data and api data, and those are matched, those are selected other are unselected

using doneButton, selecting Items does not close the menu dropdown

Hi, I was using the SearchableDropdown single menu variant and had some questions.

I'd like to add a button that closes the menu and activates a callback (to open a dialog that enables the user to add a new option to the dropdown list), but passing a widget to the closeButton field in the constructor made it so that clicking the button no longer closed the menu dropdown.

I thought that using the doneButton for closing the menu dropdown might be an answer, but then clicking on an item did not close the dropdown anymore (which makes sense, that looks like the whole point of the doneButton anyway)

I'd like to know if and how I could achieve having two buttons on the dropdown menu, one that closes without needing to select an option (for when there is no option to be selected yet) and another that fires a callback passed on the constructor (and closes the dropdown menu also)

Related code below:

SearchableDropdown.single(
            hint: 'Selecione seu paciente',
            dialogBox: false,
            isExpanded: true,
            menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
            items: optionsList,
            onChanged: (value) {
              BlocProvider.of<NewSchedulingBloc>(context).add(SchedulingFormChanged(value));
            },
            searchHint: 'Digite o nome do seu paciente',
            closeButton: (selectedItemsClose){
              return Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  FlatButton(
                    onPressed: () => newPatientCallback(),
                    child: Text('Novo Paciente'),
                  ),
                  FlatButton(
                    onPressed: () => pop(), // =>Does not pop or close the dropdown menu at all...
                    child: Text('Novo Paciente'),
                  ),
                ],
              );
            },
           doneButton: 'Fechar'
          )

Thanks

The dropdown value is not updating since the lasts updates

I used to have a flutter application with this searchable dropdown and when the value was changed to null and setState() was called the dropdown would show the hint text. This is not happening any more.

So the problem is that even if I set value: null; the value still shows the previous selected value... sounds crazy.

Any guesses why? Could I downgrade somehow to the 1.1.0 version to it back working as it did?

Huge thanks!

Pere

widget.value == null

I use your demo,i had this problen,
family: Roboto, size: 15.0, weight: 400, baseline: ideographic, decoration: TextDecoration.none, softWrap: wrapping at box width, overflow: clip):
'package:searchable_dropdown/searchable_dropdown.dart': Failed assertion: line 90 pos 12: 'widget.value == null ||
widget.items.where((DropdownMenuItem item) => item.value == widget.value).length == 1': is not true.

Model Class Support

I tried to use the package with a model class, but when I search, it doesn't appear in the list. Do you have a model example? Or does this plugin really not support it?

My code:

class FabricanteOleo {
  String nome;
  int id;

  FabricanteOleo({this.nome, this.id});

  FabricanteOleo.fromJson(json) {
    nome = json['nome'];
    id = json['id'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['nome'] = this.nome;
    data['id'] = this.id;
    return data;
  }
}

 _dropSearch() {
    return new SearchableDropdown<FabricanteOleo>(
      isCaseSensitiveSearch: true,
      items: listaFabricantes.map((fab){
        return DropdownMenuItem<FabricanteOleo>(
          child: new Text(fab.nome),
          value: fab,
        );
      }).toList(),
      value: fabricanteOleoSelecionado,
      hint: new Text('Select One'),
      searchHint: new Text(
        'Select One',
        style: new TextStyle(fontSize: 20),
      ),
      onChanged: (FabricanteOleo value) {
        setState(() {
          this.fabricanteOleoSelecionado = value;
        });
      },
    );

Captura de Tela 2020-02-05 às 20 06 28

Hello Search option not working

Hello sir i have used your provided solution and the search still not working

import 'package:flutter/material.dart';
// import 'package:foodfromforeign1/models/country.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:searchable_dropdown/searchable_dropdown.dart';

void main() => runApp( MyApp());

class Country{
  String name;
  int id;
  Country(this.name,this.id);
  toString(){
    return(name);
  }
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      title: 'Flutter Demo',
      theme:  ThemeData(
        primarySwatch: Colors.red,
      ),
      home:  MyHomePage(title: 'Users'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() =>  _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

static final String countriesJson = '[{"id":0,"name":"Afghanistan"},{"id":1,"name":"Albania"},{"id":2,"name":"Algeria"},{"id":3,"name":"Angola"}]';
List<Country> countries;
List<DropdownMenuItem<Country>> countriesDropdownItems;
Country selectedCountry;


    @override
  void initState() {
    super.initState();
   countries=(jsonDecode(countriesJson) as List<dynamic>).map<Country>((e) => Country(e['name'],e['id'])).toList();
    countriesDropdownItems = countries.map<DropdownMenuItem<Country>>((e) => DropdownMenuItem(child:Text(e.name),value:e,)).toList();
    super.initState();
  }

@override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar:  AppBar(
        title:  Text(widget.title),
      ),
      body:Container(
          padding: EdgeInsets.symmetric(horizontal: 20, vertical: 30),
        child:Column(
         children: <Widget>[
            SearchableDropdown.single(
        items: countriesDropdownItems,
        value: selectedCountry,
        hint: "Select one country",
        searchHint: "Select one country",
        onChanged: (value) {
          setState(() {
            selectedCountry = value;
          });
        },
        isExpanded: true,
      )
         ],

        ),  
      


        
      ),
    );
  
  }
}


How do I change the style ?

I would like to standardize the style of the field with the other fields in the form.
How should I change the decoration properties?
'''
return TextFormField(
autofocus: false,
onChanged: controller.changeMaterialUnitId,
obscureText: false,
maxLines: 1,
//keyboardType: TextInputType.emailAddress,
cursorColor: Colors.orange,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Unidade',
prefixIcon:
Icon(Icons.face, color: Colors.orange, size: 20),
helperText: ' ',
errorText: controller.validateMaterialUnitId(),
),
)
'''

Adjust selected value padding.

I want to adjust the padding for selectedValue as when we selected the value, the padding between label, selectedValue, underline are way too big.

image

Issue when we define init value

when I set the value on value param then on change method returning me the same value instead of new value which I have selected.

Can't close the dropdown button in menu mode

Hi, first of all thank you por this plug in.

I'm not able to close de dropdown button in menu mode(dialogbox false) if I haven't chosen any item.
Could you please help me with some work around?

Asynchronous Search with API [FEATURE]

This is the best plugin I could find for searchable dropdowns in Flutter but I would like to suggest a feature in where the user search in the input, then the data on the items list changes as well base on the data from a backend / API. That would be great.

If this is available or there is a way to implement this I might need an example, I'm new to Flutter.

Thank you.

Arabic Not working

Hello
I have gone through arabic search issue in (#17 ) , but still arabic search is not working
what I missed in my code?

SearchableDropdown.single(
                  isCaseSensitiveSearch: true,
                  items: data.map((item) {
                    return new DropdownMenuItem(
                    child : Directionality(
                    textDirection: TextDirection.rtl,
                    child: new Text(item['countryNameAr'].toString(), textAlign: TextAlign.right, textDirection: TextDirection.rtl), ),
                    value: item['countryCode'].toString(),
                    );
                    }).toList(),
                   value: _mySelection,
                  hint: "Select one",
                  searchHint: "Select one",
                  onChanged: (value) {
                    setState(() {
                      _mySelection = value;
                    });
                  },
                  isExpanded: true,
                  searchFn: (String keyword,  List<DropdownMenuItem> items) {
                    List<int> ret = List<int>();
                    if (keyword != null && items != null) {
                      keyword.split(" ").forEach((k) {
                        int i = 0;
                        items.forEach((item) {
                          if (keyword.isEmpty || (k.isNotEmpty &&
                              (item.value.countryNameAr.toString().toLowerCase().contains(k.toLowerCase()) ||
                                  item.value.countryCode.toString().contains(k)))) {
                            ret.add(i);
                          }
                          i++;
                        });
                      });
                    }
                    if(keyword.isEmpty){
                      ret = Iterable<int>.generate(items.length).toList();
                    }
                    return (ret);
                  },

                ),

After selecting sropdown data, showing left side space

I used below code, but showing some garbage data/
Uploading Screenshot_2020-04-29-23-57-14-011_mahindra.com.btl.jpg…

SearchableDropdown.multiple(
items: _dropdownMenuItems,
disabledHint: "Select State*",
selectedItems: selectedState,
displayClearIcon: false,
//hint: Text("Select State *"),
searchHint: "Select State *",
label: Text(
"Select State *",
style: TextStyle(color: Colors.black54),
),
onChanged: (value) {
setState(() {
selectedState = value;
});
if (selectedState.length > 0)
getDealers(selectedState);
},
closeButton: (selectedItems) {
return ("Save");
},
underline: Container(
height: 1.0,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.black38,
width: 1.0))),
),
isExpanded: true,
selectedValueWidgetFn: (item) {
return Container(
transform:
Matrix4.translationValues(-10, 0, 0),
alignment: Alignment.centerLeft,
child: (Text(item.toString())));
},
)

Using "searchable_dropdown" causes application build to fail

I tested this library in flutter and it was working great yesterday. Today I opened the project to continue working on it, but the application no longer builds. I get the following error when I try to debug the project on simulator.

If I remove searchable_dropdown dependency and replace the code with dart Dropdown, application starts and everything works.

I have made no changes as of yesterday. I already tried clearing builds and restarting the machine.

Here is how i use the library

  List<String> _items = ['aaaaaaa', 'bbbbbbb', 'ccccccc', 'dddddd'];
  String _selectedItem;
.
.
.
  SearchableDropdown.single(
    items: _items.map((location) {
      return DropdownMenuItem(
        child: new Text(location),
        value: location,
      );
    }).toList(),
    value: _selectedItem,
    hint: Text('Please select an Item'),
    searchHint: "Select one",
    onChanged: (value) {
      setState(() {
        _selectedItem = value;
      });
    },
    isExpanded: true,
  ),
.
.
.

Here is the error log I'm seeing, while using the version -> searchable_dropdown: ^1.1.3

Launching lib/main.dart on iPhone 11 in debug mode...
Running Xcode build...
Xcode build done.                                           15.9s
Failed to build iOS app
Error output from Xcode build:
↳
    ** BUILD FAILED **


Xcode's output:
↳
    === BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Debug ===
    ld: warning: Could not find or use auto-linked library 'swiftCoreFoundation'
    ld: warning: Could not find or use auto-linked library 'swiftCompatibility50'
    ld: warning: Could not find or use auto-linked library 'swiftObjectiveC'
    ld: warning: Could not find or use auto-linked library 'swiftCore'
    ld: warning: Could not find or use auto-linked library 'swiftQuartzCore'
    ld: warning: Could not find or use auto-linked library 'swiftCoreGraphics'
    ld: warning: Could not find or use auto-linked library 'swiftDarwin'
    ld: warning: Could not find or use auto-linked library 'swiftUIKit'
    ld: warning: Could not find or use auto-linked library 'swiftFoundation'
    ld: warning: Could not find or use auto-linked library 'swiftCoreImage'
    ld: warning: Could not find or use auto-linked library 'swiftCompatibilityDynamicReplacements'
    ld: warning: Could not find or use auto-linked library 'swiftMetal'
    ld: warning: Could not find or use auto-linked library 'swiftDispatch'
    ld: warning: Could not find or use auto-linked library 'swiftCoreMedia'
    ld: warning: Could not find or use auto-linked library 'swiftCoreAudio'
    ld: warning: Could not find or use auto-linked library 'swiftSwiftOnoneSupport'
    Undefined symbols for architecture x86_64:
      "value witness table for Builtin.UnknownObject", referenced from:
          full type metadata for searchable_dropdown.SwiftSearchableDropdownPlugin in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "__swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements", referenced from:
          __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_searchable_dropdown in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
         (maybe you meant: __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_searchable_dropdown)
      "_swift_allocObject", referenced from:
          @objc searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "static (extension in Foundation):Swift.String._unconditionallyBridgeFromObjectiveC(__C.NSString?) -> Swift.String", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "static Swift.String.+ infix(Swift.String, Swift.String) -> Swift.String", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_unknownObjectRelease", referenced from:
          static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @objc static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          reabstraction thunk helper from @escaping @callee_unowned @convention(block) (@unowned Swift.AnyObject?) -> () to @escaping @callee_guaranteed (@in_guaranteed Any?) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_release", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          ___swift_destroy_boxed_opaque_existential_0 in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @objc searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_deallocObject", referenced from:
          l_objectdestroy in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_retain", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_unknownObjectRetain", referenced from:
          @objc static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "Swift._bridgeAnythingToObjectiveC<A>(A) -> Swift.AnyObject", referenced from:
          reabstraction thunk helper from @escaping @callee_unowned @convention(block) (@unowned Swift.AnyObject?) -> () to @escaping @callee_guaranteed (@in_guaranteed Any?) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "(extension in Foundation):Swift.String._bridgeToObjectiveC() -> __C.NSString", referenced from:
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_getObjCClassFromMetadata", referenced from:
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "type metadata for Swift.String", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "__swift_FORCE_LOAD_$_swiftCompatibility50", referenced from:
          __swift_FORCE_LOAD_$_swiftCompatibility50_$_searchable_dropdown in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
         (maybe you meant: __swift_FORCE_LOAD_$_swiftCompatibility50_$_searchable_dropdown)
      "_swift_getObjCClassMetadata", referenced from:
          type metadata accessor for __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @objc static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_bridgeObjectRelease", referenced from:
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_getObjectType", referenced from:
          static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_getInitializedObjCClass", referenced from:
          type metadata accessor for __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          type metadata accessor for searchable_dropdown.SwiftSearchableDropdownPlugin in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "Swift.String.init(_builtinStringLiteral: Builtin.RawPointer, utf8CodeUnitCount: Builtin.Word, isASCII: Builtin.Int1) -> Swift.String", referenced from:
          static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

Could not build the application for the simulator.
Error launching application on iPhone 11.

Any suggestions, how i could resolve this problem?

Can't clear selected value

How to clear the field in which the selected item is displayed, since it does not work through the “Tvalue” field, I do not know what to do? the field is cleared only by pressing the button the icon button into the widget.

Search not working with Arabic language

The search not working in Arabic and it's only searching by word.

I need to edit the search functionality to let it like this: ( as it's more accurate ) and working in Arabic words

_searchResults = items
            .where((faculty) => faculty.title.toLowerCase().indexOf(query) > -1)
            .toList();

instead of using contains() method

Update: It's working but it always searches in value field I need to let the search bar search in other fields instead of value

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.