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 Name Type Required Default Description
prefix string No Date_ what to prefix the var name with
time timestamp/YYYY-MM-DD No current time in unix timestamp or YYYY-MM-DD format what date/time to use
start_year string No current year the first year in the dropdown, either year number, or relative to current year (+/- N)
end_year string No same as start_year the last year in the dropdown, either year number, or relative to current year (+/- N)
display_days boolean No true whether to display days or not
display_months boolean No true whether to display months or not
display_years boolean No true whether to display years or not
month_format string No %B what format the month should be in (strftime)
day_format string No %02d what format the day output should be in (sprintf)
day_value_format string No %d what format the day value should be in (sprintf)
year_as_text boolean No false whether or not to display the year as text
reverse_years boolean No false display years in reverse order
field_array string No null if 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_size string No null adds size attribute to select tag if given
month_size string No null adds size attribute to select tag if given
year_size string No null adds size attribute to select tag if given
all_extra string No null adds extra attributes to all select/input tags if given
day_extra string No null adds extra attributes to select/input tags if given
month_extra string No null adds extra attributes to select/input tags if given
year_extra string No null adds extra attributes to select/input tags if given
field_order string No MDY the order in which to display the fields
field_separator string No \n string printed between different fields
month_value_format string No %m strftime 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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章