involve-digital/phone-control

为 Nette 表单添加带有 "libphonenumber" 库验证的联系电话输入的扩展。

v1.0.0 2022-02-12 17:08 UTC

This package is auto-updated.

Last update: 2024-09-09 09:36:11 UTC


README

简介

InvolveDigital 为您提供 Nette 表单中电话号码的完整解决方案。功能包括

  • 通过 "giggsey/libphonenumber-for-php" 库进行后端验证和 "libphonenumber-js" 库进行前端验证
  • 输入电话号码格式的自由度
  • 输出电话号码格式的统一
  • 完整的区域代码解决方案

安装

推荐的安装方式是通过 Composer

composer require involve-digital/phone-control

最低要求的 PHP 版本是 7.1 和 Nette 2.4

客户端支持可以使用 npm 或 yarn 安装

npm install phone-control

使用方法

后端

配置

注册扩展并在配置文件中进行配置。

  • 在示例中您可以查看默认配置
  • 如果您不需要其他配置,则无需配置
extensions:
        forms.phoneControl: Involve\Forms\Controls\PhoneControl\DI\PhoneControlExtension
        
forms.phoneControl:
    allowedRegions: [] # only allowed regions
    expectedRegions: [CZ, SK] # regions that we expect will be typed, but other regions are not restricted
    outputFormat: constant(libphonenumber\PhoneNumberFormat::E164) # output format
    outputFormatWhitespaces: true # set to false, if you want to trim whitespaces in output phone number
    regex: constant(Involve\Forms\Controls\PhoneControl::DEFAULT_REGEX) # first degree of protection, you can specify your own regex here

注意:在旧版 Nette 中使用 ::constant() 代替 constant()

让我们以号码 +420 608 343 634 为例。
outputFormat 字段的允许值是

Nette 表单

$form->addPhone('phone', 'Phone:')
    ->setAllowedRegions('CZ');
//  ->setExpectedRegions(string|array $expectedRegions)
//  ->setOutputFormat(int $outputFormat) - see table above
//  ->setOutputFormatWhitespaces(bool $whitespaces)

不使用客户端脚本

您当然可以使用此扩展仅作为服务器端。用户将被强制输入区号,因此您可能希望将此信息放在输入附近。

或者您可以选择预设默认区号。此组件实际上在表单中添加了两个输入;TextInput 用于实际电话号码和 HiddenInput 用于区号,主要用于客户端脚本。您可以使用隐藏的输入来设置默认区号

$form->addPhone('phone', 'Phone:')
    ->setAllowedRegions('CZ');

$form['phoneRegionCode']->setValue('+420'); // hidden input is created by adding postfix "RegionCode" to the name of the parent input

前端

真正的美在于客户端脚本。脚本依赖于 netteForms.js 库。使用 libphonenumber-js 库是可选的,因为您可以在不使用此库的情况下编写自己的验证。

它是如何工作的?

  1. 在输入的开始处附加一个下拉列表
  2. 下拉列表包含指定的国家/地区选项
  3. 选择时,区域代码值将保存到隐藏输入
  4. 选择 "其他" 选项时,将添加用于其他区域代码的额外输入
  5. 在电话输入中键入 "+" 符号时,下拉列表将隐藏,因为它假设用户将在主要输入中输入区域代码号码

所有内容都是用原生 JS 编写的。

<script src="netteForms.js"></script>
<script src="phone-control.js"></script>

全局对象 Nette 被更新并创建了一个 Nette.PhoneControl 对象,其中包含所有功能。

有一些选项,您可以修改。

配置

<script>
    Nette.PhoneControl.options = {
        'flag': true, // shows country flags in dropdown
        'otherText': '-jiné-', // you might want to pass translated text here
        'singleOptionPaddingOffset': 15, // padding-left of input that dropdown is in
        'multiOptionsPaddingOffset': 20, // padding-left of input that dropdown is in
        'dropdownChevronTopOffset': 8 // top offset of dropdown chevron icon
    };
</script>

有用的函数

您可以通过 PhoneControl.validateControl 函数验证控件

var valid = Nette.PhoneControl.validateControl(
  document.getElementById('test-phone-control')
);

您也可以编写自己的验证

Nette.PhoneControl.validateControl = function (phoneControl) {
    //... your validation
  };

当调用 Nette.validateForm() 时(例如,在提交时)会自动验证输入。如果出于某种原因您不希望这样做,您可以取消设置验证器

delete Nette.validators['InvolveFormsControlsPhoneControl_validateNumber'];

您可能希望重新初始化电话控件,尤其是在片段重绘后

$.nette.ajax({
  url: '...',
  complete: function () {
    Nette.PhoneControl.initControl(
      document.getElementById('test-phone-control')
    );
  }
});

CSS

当前的 CSS 已针对 Bootstrap 框架准备就绪,您很可能需要在项目中做一些 CSS 调整才能使此组件工作。您也可以从头开始设计组件样式。
请参阅 .css.scss 文件,将内容复制到您的项目中并根据需要进行修改。

需要修改的最重要样式是

/* positioning of dropdown in input */
.phone-control-region-code {
    margin-top: 8px !important;
    margin-left: 10px !important;
}

/* hover over dropdown options */
.phone-control-region-code li:not(:first-child):hover {
    background-color: rgb(184, 233, 134) !important;
    color: white;
}

/* input for other region code */
.phone-control-region-code li.phone-control-selected input[type="tel"] {
    height: 16px !important;
    width: 30px !important;
}