مشاوره و آموزش تحصیلی ریسمونک
0

طراحی و کدنویسی فرم در فلاتر چگونه است ؟

در این مقاله با شیوه به کارگیری مؤثر فرم در فلاتر آشنا خواهیم شد. در این راهنما موضوعات زیادی مانند اعتبارسنجی، ذخیره‌سازی، جابجایی کرسر به فیلدهای دیگر و ارسال فرم با زدن return روی کیبورد موبایل مطرح می‌شوند. در انتها شما می‌توانید یک صفحه لاگین کامل را بسازید. با ما همراه باشید تا با روش کار کردن با فرم‌ها در فلاتر آشنا شوید

 

گام اول: ساخت لی‌آوت

یک پروژه جدید فلاتر بسازید و کد زیر را برای شروع کار در آن قرار دهید:

import 'package:flutter/material.dart';

main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Form Demo',
      home: FormDemo(),
    );
  }
}
class FormDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _FormDemoState();
  }
}

class _FormDemoState extends State<FormDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Form Demo'),
      ),
      body: _buildForm(),
    );
  }
}

این یک اپلیکیشن ساده با یک AppBar و یک Form است. فعلاً بخش مهم برای ما متد ()buildForm_ است.

این فرم قرار است حاوی یک Column همراستا با مرکز صفحه و دو TextFormField و یک RaisedButton باشد. توجه داشته باشید که فیلدهای متنی ما باید از نوع From باشند: TextFormField و نه TextField. این قرار است مهم باشد، زیرا می‌خواهیم از Form widget استفاده کنیم:

Widget _buildForm() {
  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      _buildEmailField(),
      _buildPasswordField(),
      _buildSubmitButton(),
    ],
  );
}

Widget _buildEmailField() {
  return TextFormField(
    decoration: InputDecoration(labelText: 'Email'),
  );
}

Widget _buildPasswordField() {
  return TextFormField(
    decoration: InputDecoration(labelText: 'Password'),
  );
}

Widget _buildSubmitButton() {
  return RaisedButton(
    onPressed: () {},
    child: Text('SEND'),
  );
}
+ همچنین در ریسمونک بخوانید:

گام دوم: ساخت فرم و افزودن کلید

سؤالی که اینجا مطرح می‌شود باید به فلاتر اعلام کنیم که این دو فیلد و دکمه یک فرم هستند که باید داده‌ها را ذخیره کرده و اعتبارسنجی کنند. قبل از هر چیز باید ویجت Column را درون یک Form قرار دهیم:

Widget _buildForm() {
  return Form(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          _buildEmailField(),
          _buildPasswordField(),
          _buildSubmitButton(),
        ],
      ));
}

تصور کنید بیش از یک فرم روی صفحه داشته باشید، در این صورت برای ردگیری آن‌ها باید از مشخصه key در Form استفاده کنیم. کلید خود را ایجاد کرده و آن را به فرم اضافه کنید تا یکتا شود:

class _FormDemoState extends State<FormDemo> {
  final _formKey = GlobalKey<FormState>();

  Widget _buildForm() {
    return Form(
        key: _formKey,
        ...);
  }
}

گام سوم: اعتبارسنجی

زمانی که TextFormField دارید، می‌توانید پیش از ارسال آن را اعتبارسنجی کنید. فرض کنید می‌خواهیم بررسی کنیم آیا فیلد خالی است یا یک ایمیل معتبر در آن وجود دارد.

مشخصه validator این وظیفه را بر عهده دارد. کافی است قاعده خود را بگویید و در مواردی که خطایی وجود دارد یک string بازگشت دهید.

Widget _buildEmailField() {
  return TextFormField(
    decoration: InputDecoration(labelText: 'Email'),
    validator: (String value) {
      if (!RegExp(
              r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
          .hasMatch(value)) {
        return 'This is not a valid email';
      }
    },
  );
}

Widget _buildPasswordField() {
  return TextFormField(
    decoration: InputDecoration(labelText: 'Password'),
    validator: (String value) {
      if (value.isEmpty) {
        return 'Preencha a senha';
      }
    },
  );
}

در فیلد رمز عبور مقدار درون فیلد را بررسی می‌کنیم تا خالی نباشد. در صورتی که این فیلد خالی باشد، یک پیام خطا زیر TextFormField نمایش می‌دهیم. فیلد ایمیل هم همین کار را انجام می‌دهد، اما از RegExp برای معتبر بودن ایمیل استفاده می‌کنیم.

اکنون زمانی که فرم را ذخیره می‌کنید باید معتبر بودن آن را بررسی کنید. در حالتی که فرم معتبر باشد می‌توانید داده‌ها را ذخیره کنید در این صورت پیام خطایی نمایش می‌یابد.

Widget _buildSubmitButton() {
  return RaisedButton(
    onPressed: () {
      _submitForm();
    },
    ... 
  );
}

void _submitForm() {
  print('Submitting form');
  if (_formKey.currentState.validate()) {
    print('Form was validated');
  }
}

پروژه را اجرا کرده و لاگ را بررسی کنید تا اجرای عملی آن را ملاحظه کنید.

گام چهارم: ذخیره‌سازی

احتمالاً می‌خواهید داده‌های فرم را ذخیره کنید تا کاری با آن انجام دهید. در این گام همان قواعد ذخیره‌سازی را برای فیلدها ایجاد می‌کنیم و سپس زمانی که متد save()‎ را فراخوانی کنیم، آن قواعد اجرا می‌شوند. ما قصد داریم ایمیل و رمز عبور را در یک Map ذخیره کنیم.

class _FormDemoState extends State<FormDemo> {
  final Map<String, dynamic> formData = {'email': null, 'password': null};

  Widget _buildEmailField() {
    return TextFormField(
      ...
      onSaved: (String value) {
        formData['email'] = value;
      },
    );
  }

  Widget _buildPasswordField() {
    return TextFormField(
      ...
      onSaved: (String value) {
        formData['password'] = value;
      },
    );
  }
  void _submitForm() {
    print('Submitting form');
    if (_formKey.currentState.validate()) {
      _formKey.currentState.save(); //onSaved is called!
      print(formData);
    }
  }
}

زمانی که ()formKey.currentState.save_ را فراخوانی می‌کنید در ادامه onSaved از فرم‌ها اجرا خواهد شد. پس از آن داده‌های نوشته شده روی لاگ‌ها پرینت خواهند شد. آن را خودتان اجرا و بررسی کنید.

گام پنجم: جابجا کردن نشانگر ماوس

یک قابلیت جالب فرم‌ها توانایی نوشتن چیزی در کیبورد است و سپس می‌توان با زدن کلید Next به فیلد بعدی رفت. در نهایت زمانی که کلید return زده شود فرم ارسال می‌شود. این وضعیت مناسبی است، زیرا کاربر می‌تواند بدون نیاز به پنهان کردن یا نمایان کردن کیبورد به بخش‌های مختلف اپلیکیشن برد و در هر حالی روی صفحه اسکرول کند. شاید متوجه شده باشید که فرم هنوز این قابلیت را ندارد. اما جای نگرانی نیست، ما آن را طراحی می‌کنیم. وقایعی که برای کاربر اتفاق می‌افتد به صورت زیر هستند:

  1. ایمیل را وارد کرده و کلید Next روی کیبورد را بزنید.
  2. فوکوس به طور خودکار به فیلد password می‌رود.
  3. فیلد password را پر کنید و کلید Return کیبورد را بزنید.
  4. فرم به صورت خودکار ارسال می‌شود.

ما از onFieldSubmitted استفاده خواهیم کرد. این متد هر زمان که کاربر فیلد را ارسال می‌کند فراخوانی خواهد شد.

Widget _buildEmailField() {
  return TextFormField(
    ...
    textInputAction: TextInputAction.next,
    onFieldSubmitted: (v) {
      FocusScope.of(context).requestFocus(focusPassword);
    },
  );
}

textInputAction مسئول نمایش دکمه Next به جای دکمه Return است. خط بعدی کد فوکوس را به password می‌برد. ما باید اعلام کنیم که focusPassword ارجاعی به فیلد رمز عبور ایجاد می‌کند.

Widget _buildPasswordField() {
  return TextFormField(
    ...
    focusNode: focusPassword,
    onFieldSubmitted: (v) {
      _submitForm();
    },
  );
}

خط اول نشان می‌دهد که focusPassword مسئول شناسایی فیلد رمز عبور است، در حالی که وقتی کاربر روی کلید Return می‌زند، خط دوم فرم را با فراخوانی ()submitForm_ ارسال می‌کند. focusPassword تنها یک وهله سراسری از FocusNode است.

class _FormDemoState extends State<FormDemo> {
  final focusPassword = FocusNode();
  ...
}

پروژه را اجرا کرده و بررسی کنید که آیا می‌توانید فرم را تنها با زدن کلید بازگشت ارسال کنید. برای مشاهده سورس کد کامل این پروژه به این ریپوی گیت‌هاب (+) بروید.

ارسال دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *