ecshop 之 smarty的 {html_select_date} 与input联动

好坑,现在被拉过来搞PHP,基于ecshop的开发,不会啊,只能按源码学呗,我使用ecshop开发的时候,我需要做一个生日填写并且联动一个input显示,

按照模板里的原码是这样写的

 <tr>
    <td class="label">{$lang.birthday}:</td>
    <td>{html_select_date field_order="YMD" prefix="birthday" time=$user.birthday start_year="-60" end_year="+1" display_days=true month_format="%m"}</td>
  </tr>

原来它用了smarty的封装好的方法“html_select_date ”在实现运行界面后,打开浏览器调试模式后,发现它转换后的结果是这样的

<tr>
  <td class="label">出生日期:</td>
  <td>
    <select name="birthdayYear">
      <option value="1959">1959</option>
      <option value="1960">1960</option>
      <option value="1961">1961</option>
      <option value="1962">1962</option>
      <option value="1963">1963</option>
      <option value="1964">1964</option>
      <option value="1965">1965</option>
      <option value="1966">1966</option>
      <option value="1967">1967</option>
      <option value="1968">1968</option>
      <option value="1969">1969</option>
      <option value="1970">1970</option>
      <option value="1971">1971</option>
      <option value="1972">1972</option>
      <option value="1973">1973</option>
      <option value="1974">1974</option>
      <option value="1975">1975</option>
      <option value="1976">1976</option>
      <option value="1977">1977</option>
      <option value="1978">1978</option>
      <option value="1979">1979</option>
      <option value="1980">1980</option>
      <option value="1981">1981</option>
      <option value="1982">1982</option>
      <option value="1983">1983</option>
      <option value="1984">1984</option>
      <option value="1985">1985</option>
      <option value="1986">1986</option>
      <option value="1987">1987</option>
      <option value="1988">1988</option>
      <option value="1989">1989</option>
      <option value="1990">1990</option>
      <option value="1991">1991</option>
      <option value="1992">1992</option>
      <option value="1993">1993</option>
      <option value="1994">1994</option>
      <option value="1995">1995</option>
      <option value="1996">1996</option>
      <option value="1997">1997</option>
      <option value="1998">1998</option>
      <option value="1999">1999</option>
      <option value="2000">2000</option>
      <option value="2001">2001</option>
      <option value="2002">2002</option>
      <option value="2003">2003</option>
      <option value="2004">2004</option>
      <option value="2005">2005</option>
      <option value="2006">2006</option>
      <option value="2007">2007</option>
      <option value="2008">2008</option>
      <option value="2009">2009</option>
      <option value="2010">2010</option>
      <option value="2011">2011</option>
      <option value="2012">2012</option>
      <option value="2013">2013</option>
      <option value="2014">2014</option>
      <option value="2015">2015</option>
      <option value="2016">2016</option>
      <option value="2017">2017</option>
      <option value="2018">2018</option>
      <option value="2019">2019</option>
      <option value="2020">2020</option></select>&nbsp;
    <select name="birthdayMonth">
      <option value="1">01</option>
      <option value="2">02</option>
      <option value="3">03</option>
      <option value="4">04</option>
      <option value="5">05</option>
      <option value="6">06</option>
      <option value="7">07</option>
      <option value="8">08</option>
      <option value="9">09</option>
      <option value="10">10</option>
      <option value="11">11</option>
      <option value="12">12</option></select>&nbsp;
    <select name="birthdayDay">
      <option value="1">01</option>
      <option value="2">02</option>
      <option value="3">03</option>
      <option value="4">04</option>
      <option value="5">05</option>
      <option value="6">06</option>
      <option value="7">07</option>
      <option value="8">08</option>
      <option value="9">09</option>
      <option value="10">10</option>
      <option value="11">11</option>
      <option value="12">12</option>
      <option value="13">13</option>
      <option value="14">14</option>
      <option value="15">15</option>
      <option value="16">16</option>
      <option value="17">17</option>
      <option value="18">18</option>
      <option value="19">19</option>
      <option value="20">20</option>
      <option value="21">21</option>
      <option value="22">22</option>
      <option value="23">23</option>
      <option value="24">24</option>
      <option value="25">25</option>
      <option value="26">26</option>
      <option value="27">27</option>
      <option value="28">28</option>
      <option value="29">29</option>
      <option value="30">30</option>
      <option value="31">31</option></select>
  </td>
</tr>

我们知道如果要实现联动,得通过在JS 使用id绑定<select>的change事件,来改变<input>的值。

可是从上而的代码中我发现转化出来没有生成<select>的id属性,这是为什么呢,所以我查询smarty的文档,看到“html_select_date”的说明

Attribute NameTypeRequiredDefaultDescription
prefixstringNoDate_what to prefix the var name with
timetimestamp/YYYY-MM-DDNocurrent time in unix timestamp or YYYY-MM-DD formatwhat date/time to use
start_yearstringNocurrent yearthe first year in the dropdown, either year number, or relative to current year (+/- N)
end_yearstringNosame as start_yearthe last year in the dropdown, either year number, or relative to current year (+/- N)
display_daysbooleanNotruewhether to display days or not
display_monthsbooleanNotruewhether to display months or not
display_yearsbooleanNotruewhether to display years or not
month_formatstringNo%Bwhat format the month should be in (strftime)
day_formatstringNo%02dwhat format the day output should be in (sprintf)
day_value_formatstringNo%dwhat format the day value should be in (sprintf)
year_as_textbooleanNofalsewhether or not to display the year as text
reverse_yearsbooleanNofalsedisplay years in reverse order
field_arraystringNonullif a name is given, the select boxes will be drawn such that the results will be returned to PHP in the form of name[Day], name[Year], name[Month].
day_sizestringNonulladds size attribute to select tag if given
month_sizestringNonulladds size attribute to select tag if given
year_sizestringNonulladds size attribute to select tag if given
all_extrastringNonulladds extra attributes to all select/input tags if given
day_extrastringNonulladds extra attributes to select/input tags if given
month_extrastringNonulladds extra attributes to select/input tags if given
year_extrastringNonulladds extra attributes to select/input tags if given
field_orderstringNoMDYthe order in which to display the fields
field_separatorstringNo\nstring printed between different fields
month_value_formatstringNo%mstrftime format of the month values, default is %m for month numbers.

按理说其中all_extra或者year_extra,month_extra,day_extra它们表示给<select>/<input>添加附加属性,应该可以加上id属性的,可是通过添加并不能加上去。这是为什么呢?

所以我找到了ecshop的smarty库文件cls_template.php ,它是通过改了smarty源码后的库,本质上还是smarty;

从找到“html_select_date”方法,在开始处打一个断点进行调试,我发现值都可以正常传进来,然后我一步一步往下看,果然找到这样一些代码

 $out = "<select name=\"{$pre}Year\">";
        for ($i = $startyear; $i <= $endyear; $i++)
        {
            $out .= $i == $year ? "<option value=\"$i\" selected>$i</option>" : "<option value=\"$i\">$i</option>";
        }
        if ($arr['display_months'] != 'false')
        {
            $out .= "</select>&nbsp;<select name=\"{$pre}Month\">";
            for ($i = 1; $i <= 12; $i++)
            {
                $out .= $i == $month ? "<option value=\"$i\" selected>" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>" : "<option value=\"$i\">" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>";
            }
        }
        if ($arr['display_days'] != 'false')
        {
            $out .= "</select>&nbsp;<select name=\"{$pre}Day\">";
            for ($i = 1; $i <= 31; $i++)
            {
                $out .= $i == $day ? "<option value=\"$i\" selected>" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>" : "<option value=\"$i\">" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>";
            }
        }

原来它没有使用到扩展的属性,不管怎么设置都没有用,我简单的给<select>加上了id,代码如下


        $out = "<select id=\"{$pre}Year\" name=\"{$pre}Year\">";
        for ($i = $startyear; $i <= $endyear; $i++)
        {
            $out .= $i == $year ? "<option value=\"$i\" selected>$i</option>" : "<option value=\"$i\">$i</option>";
        }
        if ($arr['display_months'] != 'false')
        {
            $out .= "</select>&nbsp;<select id=\"{$pre}Month\" name=\"{$pre}Month\">";
            for ($i = 1; $i <= 12; $i++)
            {
                $out .= $i == $month ? "<option value=\"$i\" selected>" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>" : "<option value=\"$i\">" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>";
            }
        }
        if ($arr['display_days'] != 'false')
        {
            $out .= "</select>&nbsp;<select id=\"{$pre}Day\"name=\"{$pre}Day\">";
            for ($i = 1; $i <= 31; $i++)
            {
                $out .= $i == $day ? "<option value=\"$i\" selected>" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>" : "<option value=\"$i\">" . str_pad($i, 2, '0', STR_PAD_LEFT) . "</option>";
            }
        }

然后再次运行,在浏览器中打开调试,会看到都加上了id,接下来得关联<input>

在模板里再添加一个<input>,用来显示计算后的值,

<tr>
    <td class="label">{$lang.student_age}:</td>
    <td><input id="student_age" name="student_age" type="text" value="{$student.student_age}" size="10" /></td>
</tr>

在js中添加如下代码,实现在更改出生日期时,同时计算出年龄并显示出来。

<script language="JavaScript">

    setAge();

    document.getElementById("birthdayYear").onchange = function(e)
    {
        setAge();
    }

    document.getElementById("birthdayMonth").onchange = function(e)
    {
        setAge();
    }

    document.getElementById("birthdayDay").onchange = function(e)
    {
        setAge();
    }

    function  setAge() {
        var mObj = document.getElementById("birthdayMonth");
        var mIndex = mObj.selectedIndex; // 选中索引
        var m = mObj.options[mIndex].value; // 选中值

        var dObj = document.getElementById("birthdayDay");
        var dIndex = dObj.selectedIndex; // 选中索引
        var d = dObj.options[dIndex].value; // 选中值

        var yObj = document.getElementById("birthdayYear");
        var yIndex = yObj.selectedIndex;
        var y = yObj.options[yIndex].value;
        var age = GetAge(y,m,d);

        document.getElementById("student_age").value = age;
    }
    function GetAge(birthYear,birthMonth,birthDay){
        var returnAge,
            d = new Date(),
            nowYear = d.getFullYear(),
            nowMonth = d.getMonth() + 1,
            nowDay = d.getDate();
        if(nowYear == birthYear){
            returnAge = 0;//同年 则为0周岁
        }
        else{
            var ageDiff = nowYear - birthYear ; //年之差
            if(ageDiff > 0){
                if(nowMonth == birthMonth) {
                    var dayDiff = nowDay - birthDay;//日之差
                    if(dayDiff < 0) {
                        returnAge = ageDiff - 1;
                    }else {
                        returnAge = ageDiff;
                    }
                }else {
                    var monthDiff = nowMonth - birthMonth;//月之差
                    if(monthDiff < 0) {
                        returnAge = ageDiff - 1;
                    }
                    else {
                        returnAge = ageDiff ;
                    }
                }
            }else {
                returnAge = -1;//返回-1 表示出生日期输入错误 晚于今天
            }
        }
        return returnAge;//返回周岁年龄
    }
</script>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值