好坑,現在被拉過來搞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>
<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>
<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> <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> <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> <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> <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>