mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
Looks like dropdown_search is the way to go!
This commit is contained in:
parent
ca4297ae6d
commit
d07b704014
@ -1,6 +1,12 @@
|
|||||||
## InvenTree App Release Notes
|
## InvenTree App Release Notes
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 0.3.0 - July 2021
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
- Updated translations
|
||||||
|
|
||||||
### 0.2.10 - July 2021
|
### 0.2.10 - July 2021
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class InvenTreeFileService extends FileService {
|
|||||||
class InvenTreeAPI {
|
class InvenTreeAPI {
|
||||||
|
|
||||||
// Minimum required API version for server
|
// Minimum required API version for server
|
||||||
static const _minApiVersion = 6;
|
static const _minApiVersion = 7;
|
||||||
|
|
||||||
// Endpoint for requesting an API token
|
// Endpoint for requesting an API token
|
||||||
static const _URL_GET_TOKEN = "user/token/";
|
static const _URL_GET_TOKEN = "user/token/";
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:dropdown_search/dropdown_search.dart';
|
||||||
|
|
||||||
import 'package:inventree/api.dart';
|
import 'package:inventree/api.dart';
|
||||||
import 'package:inventree/app_colors.dart';
|
import 'package:inventree/app_colors.dart';
|
||||||
import 'package:inventree/widget/dialogs.dart';
|
|
||||||
import 'package:inventree/widget/fields.dart';
|
import 'package:inventree/widget/fields.dart';
|
||||||
import 'package:inventree/l10.dart';
|
import 'package:inventree/l10.dart';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:inventree/widget/snacks.dart';
|
import 'package:inventree/widget/snacks.dart';
|
||||||
import 'package:one_context/one_context.dart';
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -18,6 +18,8 @@ import 'package:one_context/one_context.dart';
|
|||||||
*/
|
*/
|
||||||
class APIFormField {
|
class APIFormField {
|
||||||
|
|
||||||
|
final _controller = TextEditingController();
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
APIFormField(this.name, this.data);
|
APIFormField(this.name, this.data);
|
||||||
|
|
||||||
@ -96,16 +98,65 @@ class APIFormField {
|
|||||||
// Construct an input for a related field
|
// Construct an input for a related field
|
||||||
Widget _constructRelatedField() {
|
Widget _constructRelatedField() {
|
||||||
|
|
||||||
return AutocompleteFormField(
|
return DropdownSearch<dynamic>(
|
||||||
required ? label + "*" : label,
|
mode: Mode.BOTTOM_SHEET,
|
||||||
|
showSelectedItem: true,
|
||||||
|
onFind: (String filter) async {
|
||||||
|
|
||||||
|
Map<String, String> _filters = {};
|
||||||
|
|
||||||
|
if (filters != null) {
|
||||||
|
for (String key in filters) {
|
||||||
|
_filters[key] = filters[key].toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_filters["search"] = filter;
|
||||||
|
_filters["offset"] = "0";
|
||||||
|
_filters["limit"] = "25";
|
||||||
|
|
||||||
|
final APIResponse response = await InvenTreeAPI().get(
|
||||||
api_url,
|
api_url,
|
||||||
filters: filters,
|
params: _filters
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.isValid()) {
|
||||||
|
|
||||||
|
List<dynamic> results = [];
|
||||||
|
|
||||||
|
for (var result in response.data['results'] ?? []) {
|
||||||
|
results.add(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Results:");
|
||||||
|
print(results);
|
||||||
|
|
||||||
|
return results;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label: label,
|
||||||
hint: helpText,
|
hint: helpText,
|
||||||
renderer: null,
|
onChanged: print,
|
||||||
|
showClearButton: !required,
|
||||||
|
itemAsString: (dynamic item) {
|
||||||
|
return item['pathstring'];
|
||||||
|
},
|
||||||
|
isFilteredOnline: true,
|
||||||
|
showSearchBox: true,
|
||||||
|
compareFn: (dynamic item, dynamic selectedItem) {
|
||||||
|
|
||||||
|
if (item == null || selectedItem == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item['pk'] == selectedItem['pk'];
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consturct a string input element
|
// Construct a string input element
|
||||||
Widget _constructString() {
|
Widget _constructString() {
|
||||||
|
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
|
2
lib/l10n
2
lib/l10n
@ -1 +1 @@
|
|||||||
Subproject commit 73f9546016fa6796493462b03e13ae2386157b20
|
Subproject commit 94e1193ef17ad536afc92b3b071cb3335e7d828c
|
@ -116,82 +116,6 @@ class CheckBoxField extends FormField<bool> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AutocompleteFormField extends TypeAheadFormField {
|
|
||||||
|
|
||||||
final String label;
|
|
||||||
|
|
||||||
final _controller = TextEditingController();
|
|
||||||
|
|
||||||
final String url;
|
|
||||||
|
|
||||||
dynamic filters = {};
|
|
||||||
|
|
||||||
AutocompleteFormField(
|
|
||||||
this.label,
|
|
||||||
this.url,
|
|
||||||
{
|
|
||||||
this.filters,
|
|
||||||
Widget Function(dynamic)? renderer,
|
|
||||||
String? hint,
|
|
||||||
}) :
|
|
||||||
super(
|
|
||||||
textFieldConfiguration: TextFieldConfiguration(
|
|
||||||
autofocus: true,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: hint,
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
suggestionsCallback: (String pattern) async {
|
|
||||||
|
|
||||||
Map<String, String> _filters = {};
|
|
||||||
|
|
||||||
if (filters != null) {
|
|
||||||
for (String key in filters) {
|
|
||||||
_filters[key] = filters[key].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_filters["search"] = pattern;
|
|
||||||
_filters["offset"] = "0";
|
|
||||||
_filters["limit"] = "25";
|
|
||||||
|
|
||||||
final APIResponse response = await InvenTreeAPI().get(
|
|
||||||
url,
|
|
||||||
params: _filters
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.isValid()) {
|
|
||||||
|
|
||||||
List<dynamic> results = [];
|
|
||||||
|
|
||||||
for (var result in response.data['results'] ?? []) {
|
|
||||||
results.add(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
itemBuilder: (context, suggestion) {
|
|
||||||
print("item builder: " + suggestion.toString());
|
|
||||||
return ListTile(
|
|
||||||
title: Text(suggestion['name']),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onSuggestionSelected: (suggestion) {
|
|
||||||
// TODO
|
|
||||||
},
|
|
||||||
onSaved: (value) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class StringField extends TextFormField {
|
class StringField extends TextFormField {
|
||||||
|
|
||||||
StringField({String label = "", String? hint, String? initial, Function(String?)? onSaved, Function? validator, bool allowEmpty = false, bool isEnabled = true}) :
|
StringField({String label = "", String? hint, String? initial, Function(String?)? onSaved, Function? validator, bool allowEmpty = false, bool isEnabled = true}) :
|
||||||
|
28
pubspec.lock
28
pubspec.lock
@ -127,6 +127,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
dropdown_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dropdown_plus
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.9"
|
||||||
|
dropdown_search:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dropdown_search
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.3"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -148,6 +162,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.2"
|
||||||
|
find_dropdown:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: find_dropdown
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -490,6 +511,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.1"
|
version: "0.27.1"
|
||||||
|
select_dialog:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: select_dialog
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
sembast:
|
sembast:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -40,6 +40,7 @@ dependencies:
|
|||||||
one_context: ^1.1.0 # Dialogs without requiring context
|
one_context: ^1.1.0 # Dialogs without requiring context
|
||||||
infinite_scroll_pagination: ^3.1.0 # Let the server do all the work!
|
infinite_scroll_pagination: ^3.1.0 # Let the server do all the work!
|
||||||
audioplayers: ^0.19.0 # Play audio files
|
audioplayers: ^0.19.0 # Play audio files
|
||||||
|
dropdown_search: 0.6.3 # Dropdown autocomplete form fields
|
||||||
path:
|
path:
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user