我在这里面对一件奇怪的事情。我正在开发一个OpenCart,注册表单(index.php?route=checkout/register
)
我有这样的表格和2个字段:
<span class="required">*</span> <?php echo $entry_email; ?><br />
<input type="text" name="email" value="" class="large-field" /><br />
<br />
<span class="required">*</span> <?php echo $entry_telephone; ?><br />
<input type="text" name="telephone" value="" class="large-field" />
现在:浏览器将这两个字段解释为:
<input type="email" name="email" value="" class="large-field">
和
<input type="tel" name="telephone" value="" class="large-field">
但是,如果我更改电子邮件字段属性顺序如下:
<input type="text" value="" class="large-field" name="email" />
然后这些字段是真正的文本类型,它们不会被转换 注意:我只修改第一个(电子邮件),然后正确解析电子邮件和电话。
我在Firefox,Chrome和Opera上看到了这种意想不到的行为 但是,如果我用简单的html复制输入并查看它,它们就可以了..
有关正在发生的事情的想法,当然还有为什么?
修改
发送到浏览器的完整HTML(使用web-sniffer.net检索)位于此pastebin中:http://pastebin.com/bCXab6Kb
这意味着当php将HTML发送到浏览器时,<input type="text"
字段已经更改
那么,什么(为什么/如何)将<input type="text">
转换为类型email
/ tel
(看似基于name属性),为什么在输入字段的属性顺序发生变化时会失败?
答案 0 :(得分:2)
OpenCart直到当前稳定的version 1.5.6(以及当前的version 1.5.6.1,)默认情况下不使用任何HTML5(输入字段等)(或在其默认主题中)。
这符合:When will opencart start to use html5?(apr。&#39; 12):&#34;人们仍在抱怨IE6支持。当人们不再抱怨时,我们就可以开始专注于HTML5过渡&#34; 。
例如,文件checkout/register.tpl(来自v 1.5.6)(您修改过的)默认包含:
<span class="required">*</span> <?php echo $entry_email; ?><br />
<input type="text" name="email" value="" class="large-field" />
<br />
<br />
<span class="required">*</span> <?php echo $entry_telephone; ?><br />
<input type="text" name="telephone" value="" class="large-field" />
但是,在当前的master-branch(12月13日)中,我在不一致使用HTML5输入字段>一些页面(例如:account/register.tpl
和account/edit.tpl
):
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-email"><?php echo $entry_email; ?></label>
<div class="col-sm-10">
<input type="email" name="email" value="<?php echo $email; ?>" placeholder="<?php echo $entry_email; ?>" id="input-email" class="form-control" />
<?php if ($error_email) { ?>
<div class="text-danger"><?php echo $error_email; ?></div>
<?php } ?>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-telephone"><?php echo $entry_telephone; ?></label>
<div class="col-sm-10">
<input type="tel" name="telephone" value="<?php echo $telephone; ?>" placeholder="<?php echo $entry_telephone; ?>" id="input-telephone" class="form-control" />
<?php if ($error_telephone) { ?>
<div class="text-danger"><?php echo $error_telephone; ?></div>
<?php } ?>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input-fax"><?php echo $entry_fax; ?></label>
<div class="col-sm-10">
<input type="text" name="fax" value="<?php echo $fax; ?>" placeholder="<?php echo $entry_fax; ?>" id="input-fax" class="form-control" />
</div>
</div>
注意传真字段有type="text"
和缺少表格(有利于div)以及最后不同的类名。
这将我们带到了您问题中最有趣的部分:将<input type="text"
转换为email
/ tel
的内容(为什么/如何)(看似基于名称属性) )当输入字段的属性顺序发生变化时,为什么会失败?
正如我们在PHP发送到浏览器(http://pastebin.com/bCXab6Kb)的HTML代码中所看到的,输入字段的类型属性已经更改。因此,浏览器或javascript不会改变这一点
因此,假设PHP本身不会更改代码,那么在运行PHP之前,PHP必须运行一些内容来更改存储在硬盘上的文件中的代码,然后再将其发送到浏览器:OpenCart和/或(其中一个)主题&#39;,&#39; modules&#39;,&#39; extensions&#39;等
由于某种html-parser可能不会搞砸这么简单的任务,最有可能的候选者是某种基本搜索和替换的脚本。
恰好有两个(高度相关的)脚本,OpenCart常见的,完全符合这个法案。
OpenCart&#39;修改系统&#39;
如果您不小心下载/安装了最新的&#39; (开发)master-branch(或者是一个贡献者),然后你会找到一些文件,比如system/engine/modification.php(以及一些相关的文件和数据库表),它们可以搜索和添加/追加/替换php / tpl文件中的代码(硬编码限制),根据xml文件(system/modification.xml)中指定的规则解析目标php / tpl文件和而不修改原始文件。
这个相当不言自明的xml文件基本上包含&#39;操作&#39;每个要动态修改的文件,例如:
<file name="system/engine/front.php">
<operation>
<search>
<![CDATA[$action->getFile()]]>
</search>
<add position="replace">
<![CDATA[$this->registry->get('modification')->getFile($action->getFile())]]>
</add>
</operation>
</file>
在解析文件$action->getFile()
之前$this->registry->get('modification')->getFile($action->getFile())
替换为system/engine/front.php
!
&#34; vQmod™&#34; (又名Virtual Quick Mod)
vQmod是一个单独开发的软件包,基本上是OpenCart修改系统(上图)的精美版本,从中originated。它常用于附加组件&#39;修改文件夹vqmod
(位于OpenCart的根目录中)的OpenCart和installed的生产版本(默认情况下不包含在OpenCart中)。在此文件夹中,您可以找到包含缓存的已修改文件的文件夹vqcache
和包含xml
的文件夹xml search/replace files
。
与OpenCart的修改系统(上图)相比,这些xml文件的syntax(最明显的是position
属性)略有不同:
<file name="catalog/view/theme/default/template/checkout/register.tpl">
<operation>
<search position="replace">
<![CDATA[<input type="text" name="email" value="" class="large-field" />]]>
</search>
<add>
<![CDATA[<input type="email" name="email" value="" class="large-field" />]]>
</add>
</operation>
<operation>
<search position="replace">
<![CDATA[<input type="text" name="telephone" value="" class="large-field" />]]>
</search>
<add>
<![CDATA[<input type="tel" name="telephone" value="" class="large-field" />]]>
</add>
</operation>
<operation>
<search position="replace">
<![CDATA[<input type="text" name="fax" value="" class="large-field" />]]>
</search>
<add>
<![CDATA[<input type="tel" name="fax" value="" class="large-field" />]]>
</add>
</operation>
</file>
注意:以上示例来自&#39; embermonkey响应主题&#39;并且是您正在体验的行为的一个很好的例子:它取代了输入属性。
这些修改脚本的目的是:
避免更改核心文件。这个概念非常简单......不是直接更改核心文件,而是将更改创建为xml搜索/替换脚本文件。这些脚本文件在页面加载期间被解析为每个&#34;源&#34;核心文件加载了&#34; include&#34;或&#34;要求&#34; php函数。然后使用脚本文件更改修补源,并保存到临时文件。然后在执行期间将该临时文件替换为原始文件。原始源文件永远不会更改。这导致了一个虚拟的&#34;在执行期间更改为核心,而不对核心文件进行任何实际修改。
这使得可以实际改变OpenCart中的任何php或tpl文件(主要的index.php除外)&#34;这样,更新OpenCart的核心文件和添加/删除模板等将变得更容易,更可靠。
最后,有效的电子邮件地址(letters@gmail.com)在输入的类型设置为email
而不是text
时无法验证...
这是一个相当普遍的问题(破碎/过时/部分安装)&#39;响应&#39; /&#39;移动&#39;主题等(通常也影响电话领域) 1,2 。
问题不在于浏览器拒绝有效的电子邮件地址(当输入字段的类型设置为email
而不是text
时);相反,它是OpenCart的JSON验证器,默认情况下不会获得输入类型email
(以及tel
等)(当您或主题离开此未修补时) :
$('#button-guest').live('click', function() {
$.ajax({
url: 'index.php?route=checkout/guest/validate',
type: 'post',
data: $('#payment-address input[type=\'text\'], #payment-address input[type=\'checkbox\']:checked, #payment-address input[type=\'radio\']:checked, #payment-address input[type=\'hidden\'], #payment-address select'),
dataType: 'json',
因此,显然,solution是将这些输入类型添加到AJAX调用中:
$('#button-guest').live('click', function() {
$.ajax({
url: 'index.php?route=checkout/guest/validate',
type: 'post',
data: $('#payment-address input[type=\'text\']
, #payment-address input[type=\'email\'] // added
// , #payment-address input[type=\'tel\'] // added
, #payment-address input[type=\'checkbox\']:checked
, #payment-address input[type=\'radio\']:checked
, #payment-address input[type=\'hidden\']
, #payment-address select'
),
dataType: 'json',
总之,使用上面解释的内容:
<input type="email"
的字符串(例如)进行文本搜索(从OpenCart目录开始并包含子目录),并首先使用文件类型xml调查结果。 PS:现在你知道了vQmod,你最好使用它(而不是修改核心文件),因为&#34;性能令人惊讶地看起来根本不是一个因素&#34;,给你的将来可以获得更可靠的升级途径!
答案 1 :(得分:0)
实际上,您所描述的行为根本不是来自OpenCart - 至少不是来自默认主题的默认安装。
您可以关闭JS并直接访问此页面:http://your.ocinstall.com/index.php?route=account/register
- 它将打开注册页面。
无论如何,在默认安装(和默认主题)中都有这个HTML:
<tr>
<td><span class="required">*</span> <?php echo $entry_email; ?></td>
<td><input type="text" name="email" value="<?php echo $email; ?>" />
<?php if ($error_email) { ?>
<span class="error"><?php echo $error_email; ?></span>
<?php } ?></td>
</tr>
<tr>
<td><span class="required">*</span> <?php echo $entry_telephone; ?></td>
<td><input type="text" name="telephone" value="<?php echo $telephone; ?>" />
<?php if ($error_telephone) { ?>
<span class="error"><?php echo $error_telephone; ?></span>
<?php } ?></td>
</tr>
但在Firefox中仍然会更改属性的顺序(但不是属性值!):
<input type="text" value="" name="email" />
Chrome中相同 - 未更改任何属性值。唯一的原因可能是JavaScript库和/或正在使用的其他主题。
虽然OpenCart的默认主题的HTML文档类型被定义为为HTML5,但OpenCart实际上并不使用任何HTML5功能。
无论如何,如果有一些东西在你的模板中真正使用HTML5,那么不要害怕并享受这些功能。例如,在您的问题的示例中,如果输入的类型为email
或tel
,则用户无法提交表单,直到email
字段包含语义正确的电子邮件地址且他甚至是无法在tel
字段中填写任何文字(非数字)字符...(是的,直到用户通过开发人员工具修改HTML ...)