junny_form 0.0.19 copy "junny_form: ^0.0.19" to clipboard
junny_form: ^0.0.19 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' as 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: (Iterable<Map<String, dynamic>>? attachments) {
      return attachments?.isNotEmpty ?? false
          ? '${attachments?.length ?? 0} 个附件'
          : null;
    },
    // 演示全局配置子表保存按钮文本
    subtableSaveButtonTextBuilder: (context) => '完成',
    // getAttachmentsData: (attachment, cancelToken) async {
    //   final attachmentIds = attachment.splitIterable<int>();
    //   if (attachmentIds.isEmpty) {
    //     return [];
    //   } else {
    //     // 做一个模拟数据
    //     return List.generate(
    //       attachmentIds.length,
    //       (index) => {
    //         'id': attachmentIds.elementAt(index),
    //         'sysFileMetadataId': attachmentIds.elementAt(index),
    //         'originalName': '附件${attachmentIds.elementAt(index)}.pdf',
    //         'fileSize': (attachmentIds.elementAt(index) * 100 * 1024),
    //       },
    //     );
    //   }
    // },
    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;
      }

      // v3版本的模拟数据:包含完整的附件信息
      final List<Map<String, dynamic>> result = [
        {
          'id': 1,
          'sysFileMetadataId': 'file_1',
          'originalName': '合同附件1.pdf',
          'fileSize': 102400,
          'pageUniqueCode': 'CONTRACT_REG_INCOME',
          'columnCode': params.title ?? 'attachment',
        },
        {
          'id': 2,
          'sysFileMetadataId': 'file_2',
          'originalName': '合同附件2.jpg',
          'fileSize': 204800,
          'pageUniqueCode': 'CONTRACT_REG_INCOME',
          'columnCode': params.title ?? 'attachment',
        },
        {
          'id': 3,
          'sysFileMetadataId': 'file_3',
          'originalName': '合同附件3.docx',
          'fileSize': 307200,
          'pageUniqueCode': 'CONTRACT_REG_INCOME',
          'columnCode': params.title ?? 'attachment',
        },
        {
          'id': 4,
          'sysFileMetadataId': 'file_4',
          'originalName': '合同附件4.xlsx',
          'fileSize': 409600,
          'pageUniqueCode': 'CONTRACT_REG_INCOME',
          'columnCode': params.title ?? 'attachment',
        },
        {
          'id': 5,
          'sysFileMetadataId': 'file_5',
          'originalName': '合同附件5.png',
          'fileSize': 512000,
          'pageUniqueCode': 'CONTRACT_REG_INCOME',
          'columnCode': params.title ?? 'attachment',
        },
      ];

      // 修复:确保随机选择的起始位置加上 maxCount 不会超出数组长度
      final int availableCount = math.min(maxCount, result.length);
      final int startIndex =
          math.Random().nextInt(result.length - availableCount + 1);
      // 选择不超过 maxCount 个附件
      return result.sublist(
        startIndex,
        startIndex + math.Random().nextInt(availableCount) + 1,
      );
    },
    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