如何在D7中创建类似密码字段的隐藏字符输入文本字段?
嘿,这个需求我之前折腾过,在Drupal 7里要做一个像密码框那样隐藏输入的文本字段(比如你说的社会保障号码),有两种实用的路子:要么用现成模块省事儿,要么自己写点代码定制实现。
方法一:用现成模块快速实现
如果不想碰代码,这几个模块能直接满足需求:
- Field Password:这个模块专门提供了密码类型的字段,创建字段时选择它的字段类型,输入框就会自动变成密码框,完全隐藏用户输入的内容。而且可以配置存储选项(比如是否加密存储敏感数据),还能控制编辑时的显示行为(比如是否显示掩码而非空框)。
- Masked Input:这个模块基于jQuery Mask插件,不仅能隐藏输入内容(比如显示星号或圆点),还能给字段加输入格式限制(比如社保号的
***-**-****格式),用户输入时自动匹配格式,同时隐藏真实字符。
安装流程很简单:下载模块后启用,然后去字段管理页面(比如admin/structure/types/manage/[内容类型]/fields)创建新字段,选择对应的模块提供的字段类型即可。
方法二:手动代码定制实现
如果需要更灵活的控制(比如自定义显示掩码、加密存储逻辑),可以自己写点代码实现,步骤如下:
1. 修改输入框为密码类型(或加JS掩码)
假设你的字段机器名是field_ssn,可以在自定义模块里用hook_field_widget_form_alter修改表单元素:
function my_custom_module_field_widget_form_alter(&$element, &$form_state, $context) { // 定位到目标字段 if ($context['field']['field_name'] === 'field_ssn') { // 方案A:直接改成密码输入框 $element['#type'] = 'password'; // 注意:密码框默认编辑时不会显示原有内容,如果需要用户看到掩码(比如*******),可以用方案B // 方案B:保留文本框,用JS实现输入掩码(隐藏真实字符) // 先给字段加个类,方便JS定位 $element['#attributes']['class'][] = 'ssn-masked-field'; } }
如果选方案B,需要添加JS代码实现掩码:
(function ($) { Drupal.behaviors.ssnMask = { attach: function (context, settings) { // 给目标字段绑定输入事件,隐藏真实字符 $('.ssn-masked-field', context).once('ssn-mask').each(function () { var $field = $(this); // 存储真实输入值 var actualValue = $field.val() || ''; // 初始化显示掩码 $field.val(str_repeat('*', actualValue.length)); $field.on('input', function () { var inputVal = $field.val(); // 提取新输入的字符(因为用户输入的是星号,所以需要对比长度变化) var newChars = inputVal.substr(actualValue.length); actualValue += newChars; // 更新显示为全星号 $field.val(str_repeat('*', actualValue.length)); // 存储真实值到data属性 $field.data('actual-value', actualValue); }); // 表单提交时,把真实值放回字段,确保能正确保存 $field.closest('form').submit(function () { $field.val($field.data('actual-value') || actualValue); }); }); } }; // 辅助函数:生成重复字符串 function str_repeat(str, count) { return new Array(count + 1).join(str); } })(jQuery);
2. 处理字段显示(隐藏敏感内容)
如果不想在前端显示完整的社保号,可以用hook_field_formatter_view自定义显示格式:
function my_custom_module_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); foreach ($items as $delta => $item) { // 示例:只显示最后4位,前面用星号代替 $ssn = $item['value']; if (!empty($ssn)) { $maskedSsn = str_repeat('*', strlen($ssn) - 4) . substr($ssn, -4); $element[$delta] = array('#markup' => $maskedSsn); } } return $element; }
3. 加密存储敏感数据(可选但推荐)
社保号属于敏感数据,最好加密存储在数据库里,你可以先启用Encrypt contrib模块,然后用以下代码处理:
// 保存字段时加密 function my_custom_module_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { if ($field['field_name'] === 'field_ssn') { foreach ($items as &$item) { if (!empty($item['value'])) { $item['value'] = encrypt($item['value']); } } } } // 加载字段时解密 function my_custom_module_field_load($entity_type, $entities, $field, $instances, $langcode, &$items) { if ($field['field_name'] === 'field_ssn') { foreach ($entities as $id => $entity) { foreach ($items[$id] as &$item) { if (!empty($item['value'])) { $item['value'] = decrypt($item['value']); } } } } }
内容的提问来源于stack exchange,提问作者and93hil
相关产品推荐
相关产品推荐

