junny_form 0.0.3 copy "junny_form: ^0.0.3" to clipboard
junny_form: ^0.0.3 copied to clipboard

A flexible Flutter form management library that supports centralized field management, async validation, and custom field types.

example/lib/main.dart

import 'dart:math';

import 'package:example/address/address_utils.dart';
import 'package:example/pages/dict_enum_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:junny_form/junny_form.dart';

import 'pages/home_page.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  JunnyFormGlobalConfig.instance.init(
    getDictByEnum: (enumValue, _) => [
      {
        'dataCode': '01',
        'dataName': '1%',
      },
      {
        'dataCode': '02',
        'dataName': '3%',
      },
      {
        'dataCode': '03',
        'dataName': '5%',
      },
    ],
    attachmentsFormatter: (attachments) {
      return attachments?.isNotEmpty ?? false
          ? '${attachments?.splitIterable<int>().nonNulls.length ?? 0} 个附件'
          : null;
    },
    getAttachmentsData: (attachment, cancelToken) async {
      final attachmentIds = attachment.splitIterable<int>();
      if (attachmentIds.isEmpty) {
        return [];
      } else {
        // 做一个模拟数据
        return List.generate(
          attachmentIds.length,
          (index) => {
            'id': attachmentIds.elementAt(index),
            'name': '附件${attachmentIds.elementAt(index)}',
          },
        );
      }
    },
    selectAttachments: (BuildContext context, AttachmentTapParams params) async {
      // 模拟选择, 结合maxCount 返回结果
      // 如果maxCount 为 3,则返回 3 个附件
      final int maxCount = params.maxCount;
      final bool enabled = params.enabled;
      final List<Map<String, dynamic>> attachments = params.attachments;
      if (!enabled) {
        if (attachments.isNotEmpty) {
          // toast提示
          JunnyToastUtils.instance.show('附件不可编辑, 但可以预览');
        }
        return attachments;
      }

      final List<Map<String, dynamic>> result = [
        {'id': 1, 'name': '附件1'},
        {'id': 2, 'name': '附件2'},
        {'id': 3, 'name': '附件3'},
        {'id': 4, 'name': '附件4'},
        {'id': 5, 'name': '附件5'},
        {'id': 6, 'name': '附件6'},
        {'id': 7, 'name': '附件7'},
        {'id': 8, 'name': '附件8'},
        {'id': 9, 'name': '附件9'},
        {'id': 10, 'name': '附件10'},
        {'id': 11, 'name': '附件11'},
        {'id': 12, 'name': '附件12'},
        {'id': 13, 'name': '附件13'},
        {'id': 14, 'name': '附件14'},
        {'id': 15, 'name': '附件15'},
      ];

      // 修复:确保随机选择的起始位置加上 maxCount 不会超出数组长度
      final int startIndex = Random().nextInt(result.length - maxCount + 1);
      // 选择不超过 maxCount 个附件
      return result.sublist(
        startIndex,
        startIndex + Random().nextInt(maxCount),
      );
    },
    isTaxRateEnum: (enumValue) => enumValue == ExampleEnum.taxRate,
  );

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late AddressUtils _addressUtils;

  @override
  void initState() {
    super.initState();

    init();
  }

  Future<void> init() async {
    _addressUtils = await AddressUtils.create();

    // 组件库初始化全局配置
    JunnyGlobalWidgetConfig.instance.initialize(
      addressChildrenDataQuery: ([int? parentId]) => _addressUtils
          .getChildrenAddresses(parentId ?? 0)
          .map((e) => e.toJson())
          .toList(),
      addressDataInitializer: () async {
        // 如果没有初始化地址数据
        if (_addressUtils.count() <= 0) {
          return _addressUtils.initAddressData();
        }
      },
      addressDataQuery: (int id) => _addressUtils.getAddress(id)?.toJson(),
      addressDataConverter: (String data) => _addressUtils.getAddressData(data),
      // emptyIconBuilder: (BuildContext context) =>
      //     JunnyKitAssets.images.common.noData.image(width: 50, height: 50),
      // emptyTextBuilder: (BuildContext context) =>
      //     'noData'.withTips.translate(context),
      // yearPickerPresenter: ({
      //   required BuildContext context,
      //   required Widget Function(ValueSetter<int?>? onYearChanged) picker,
      // }) async {
      //   int? selectedYear;

      //   void onYearChanged(int? year) {
      //     selectedYear = year;
      //   }

      //   final int? result =
      //       await JunnyDialogUtils.instance.showCommonDialog<int>(
      //     contentWidget: picker(onYearChanged),
      //     title: MaterialLocalizations.of(context).selectYearSemanticsLabel,
      //     onConfirm: () =>
      //         JunnyDialogUtils.instance.dismiss<int>(result: selectedYear),
      //   );

      //   return result;
      // },
    );
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blueAccent),
        useMaterial3: true,
      ),
      locale: const Locale.fromSubtags(languageCode: 'zh'),
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('zh', 'CN'),
      ],
      navigatorObservers: <NavigatorObserver>[
        FlutterSmartDialog.observer,
      ],
      home: const HomePage(),
      builder: FlutterSmartDialog.init(),
    );
  }
}
0
likes
0
points
341
downloads

Publisher

unverified uploader

Weekly Downloads

A flexible Flutter form management library that supports centralized field management, async validation, and custom field types.

Homepage

License

unknown (license)

Dependencies

dio, flutter, junny_utils, junny_widget, provider

More

Packages that depend on junny_form