Работа с формами
Суббота, 26 июля, 2008Работа с формами — одна из самых типинчых задач при Web-программировании. Чаще всего в форме требуется либо ввести новую информацию о каком-либо объекте, либо отредактировать уже существующую, причем для нового объекта есть значения полей по умолчанию. Существует много разных способов фомирования форм, но наиболее красивым решением является следующий: форма хранится в обычном HTML, в поля прописаны значения по умолчанию. Перед выводом формы в броузер скрипт формирует хеш со значениями полей, которые нужно показать пользователю, после чего вызывает функцию, которая парсит форму и заменяет значения по умолчанию на значения из этого хеша (имя поля в хеше должно совпадать с именем поля в форме).
Вот вариант реализации такой процедуры (параметры: первый параметр — html-код с формой, второй параметр — хеш с данными, третий параметр — хеш с дополнительными опциями для select’ов, которые будут дописаны к уже существующим в статике в процессе парсинга selectа, ключ соответствует имени select-поля, значение — хешу вида имя_опции=>значение_опции):
/** Функция установки значений полей форм в соответствии с параметрами в хеш-массиве data.
(Ключи массива должны соответствовать именам полей.)
Если ключ в массиве отсутствует, поле остается без изменений
(таким образом, имеет смысл прописывать в качестве значений полей значения по умолчанию).
**/
function cmsmain_html_set($html,$data,$params=false) {
$count = preg_match_all('|(<input[^>]+?>)|is',$html,$inputs);
for ($i=0; $i<$count; $i++) {
$name=_cmsmain_html_getparam($inputs[0][$i],'name');
if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
$newstr=false;
$value=_cmsmain_html_getparam($inputs[0][$i],'value');
$type=_cmsmain_html_getparam($inputs[0][$i],'type');
if ($type=="radio" || $type=="checkbox") {
if ($value==$newvalue) {
$newstr=$inputs[0][$i];
if (strrpos($newstr,'/>')===strlen($newstr)-2) $newstr=str_replace('/>',' checked="checked"/>',$newstr);
else $newstr=str_replace('>',' checked>',$newstr);
}
else {
$newstr=preg_replace('|\s+checked(=\S+?)?([\s/>])|s','$2',$inputs[0][$i]);
}
}
else {
if (preg_match('|\s+value=[\'"]?'.$value.'[\'"]?([\s/>])|is',$inputs[0][$i])) {
$newstr=preg_replace('|\s+value=[\'"]?'.$value.'[\'"]?([\s/>])|is',' value="'.htmlspecialchars($data[$name]).'"$1',$inputs[0][$i]);
}
else $newstr=preg_replace('|(/?>)$|s',' value="'.$newvalue.'"$1',$inputs[0][$i]);
}
if ($newstr) $html=str_replace($inputs[0][$i],$newstr,$html);
}
}
$count = preg_match_all('|(<textarea[^>]+?>)(.*?)</textarea>|is',$html,$textareas);
for ($i=0; $i<$count; $i++) {
$name=_cmsmain_html_getparam($textareas[1][$i],'name');
if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
$newstr=$textareas[1][$i].$newvalue.'</textarea>';
$html=str_replace($textareas[0][$i],$newstr,$html);
}
}
$count = preg_match_all('|(<select[^>]+?>)(.*?)</select>|is',$html,$selects);
for ($i=0; $i<$count; $i++) {
$name=_cmsmain_html_getparam($selects[1][$i],'name');
if (isset($params[$name]) && is_array($params[$name])) {
$newselects = '';
foreach ($params[$name] as $key=>$value) {
if ($value=='') $value=$key;
$newselects.='<option value="'.htmlspecialchars($key).'">'.htmlspecialchars($value).'</option>';
}
$newbigstr=str_replace($selects[2][$i],$selects[2][$i].$newselects,$selects[0][$i]);
$selects[2][$i].=$newselects;
}
else $newbigstr=$selects[0][$i];
if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
$optcount = preg_match_all('|<option([^>]+?)>(.*?)<|is',$selects[2][$i].'<',$options);
for ($j=0; $j<$optcount; $j++) {
$value=_cmsmain_html_getparam($options[1][$j],'value');
if ($value==$newvalue) {
$newstr=$options[0][$j];
$newstr=preg_replace('|(<option[^>]+?)>|s','$1 selected="selected">',$newstr);
}
else $newstr=preg_replace('|\s+selected(=\S+?)?([\s/>])|s','$2',$options[0][$j]);
$newbigstr=str_replace($options[0][$j],$newstr,$newbigstr);
}
$html=str_replace($selects[0][$i],$newbigstr,$html);
}
}
return $html;
}
/** Извлечение параметра из html-тега. **/
function _cmsmain_html_getparam($input,$param) {
if (!preg_match('|\s+'.$param.'="(.*?)"|is',$input,$matches)) {
if (!preg_match('|\s+'.$param.'=\'(.*?)\'|is',$input,$matches)) {
if (!preg_match('|\s+'.$param.'=(\S+?)|is',$input,$matches)) { $matches[1]=''; _dbg('Fuck!'); }
}
}
return $matches[1];
}
/** Извлекает данные из массива и применяет к ним htmlspecialchars.
На данный момент не поддерживается обработка спецсимволов (типа [] для вложенных массивов)
**/
function _cmsmain_html_data($data,$name) {
if (isset($data[$name])) return htmlspecialchars($data[$name]);
else return false;
}
Код обновлен 4 августа 2008 года.