1
0
Fork 0
feedizer-php/htdocs/libraries/formsgeneration/form_auto_complete.php

452 lines
17 KiB
PHP
Raw Permalink Normal View History

2015-11-13 23:51:46 +01:00
<?php
/*
*
* @(#) $Id: form_auto_complete.php,v 1.24 2012/06/22 02:51:44 mlemos Exp $
*
*/
class form_auto_complete_class extends form_custom_class
{
var $text='';
var $complete='';
var $ajax='';
var $minimum_complete=3;
var $dynamic=1;
var $complete_delay=500;
var $complete_values=array();
var $menu_style='background-color: #ffffff; border-width: 1px; border-color: #000000; border-style: solid; padding: 1px;';
var $menu_class='';
var $item_style='padding: 1px; color: #000000;';
var $item_class='';
var $selected_item_style='padding: 1px; color: #ffffff; background-color: #000080;';
var $selected_item_class='';
var $button='';
var $server_validate=0;
var $item_style_attributes='';
Function SerializeItems(&$form, $items)
{
Reset($items);
for($results='[', $f = 0; $f<count($items); Next($items), $f++)
{
if($f>0)
$results.=', ';
$v=Key($items);
$results.='{ "v": '.$form->EncodeJavascriptString($v).', "e": '.$form->EncodeJavascriptString($form->EncodeJavascriptString(HtmlSpecialChars($v))).', "d": '.$form->EncodeJavascriptString($items[$v]).' }';
}
return($results.']');
}
Function GetCompleteValues(&$form, $arguments)
{
if(!IsSet($arguments['CompleteValues'])
|| GetType($complete_values=$arguments['CompleteValues'])!='array'
|| count($complete_values)==0)
return('it were not specified valid complete values');
$this->complete_values=$complete_values;
return('');
}
Function SearchCompleteValues(&$form, $text, &$found)
{
if(strlen($text)==0)
$found=$this->complete_values;
else
{
$t=strtolower($text);
for($found=array(), Reset($this->complete_values), $v=0; $v<count($this->complete_values); $v++, Next($this->complete_values))
{
$c=Key($this->complete_values);
if(!strcmp($t, strtolower(substr($c, 0, strlen($t)))))
$found[$c]=$this->complete_values[$c];
}
}
return('');
}
Function AddInput(&$form, $arguments)
{
if(!IsSet($arguments['CompleteInput'])
|| strlen($arguments['CompleteInput'])==0)
return('it was not specified a valid text input to complete');
$this->text=$arguments['CompleteInput'];
if(IsSet($arguments['CompleteMinimumLength']))
{
$minimum_complete=intval($arguments['CompleteMinimumLength']);
if($minimum_complete<=0)
return('it was not specified a valid minimum length to complete the text');
$this->minimum_complete=$minimum_complete;
}
if(IsSet($arguments['CompleteDelay']))
{
$complete_delay=intval($arguments['CompleteDelay']*1000);
if($complete_delay<=0)
return('it was not specified a valid complete delay period');
$this->complete_delay=$complete_delay;
}
if(IsSet($arguments['ShowButton']))
{
$button=$arguments['ShowButton'];
if(strlen($button)==0)
return('it was not specified a valid button input to show all options');
$this->button=$button;
}
if(IsSet($arguments['Dynamic'])
&& !$arguments['Dynamic'])
$this->dynamic=0;
if(IsSet($arguments['MenuClass']))
$this->menu_class=$arguments['MenuClass'];
if(IsSet($arguments['MenuStyle']))
$this->menu_style=$arguments['MenuStyle'];
if(IsSet($arguments['ItemClass']))
$this->item_class=$arguments['ItemClass'];
if(IsSet($arguments['ItemStyle']))
$this->item_style=$arguments['ItemStyle'];
if(IsSet($arguments['SelectedItemClass']))
$this->selected_item_class=$arguments['SelectedItemClass'];
if(IsSet($arguments['SelectedItemStyle']))
$this->selected_item_style=$arguments['SelectedItemStyle'];
$this->complete=$this->GenerateInputID($form, $this->input, '_');
if($this->dynamic)
{
$this->ajax=$this->complete.'ajax';
$ajax_arguments=array(
'TYPE'=>'custom',
'NAME'=>$this->ajax,
'ID'=>$this->ajax,
'CustomClass'=>'form_ajax_submit_class',
'TargetInput'=>$this->input
);
if(IsSet($arguments['Timeout']))
$ajax_arguments['Timeout']=intval($arguments['Timeout']);
if(IsSet($arguments['FeedbackElement']))
{
$ajax_arguments['FeedbackElement']=$arguments['FeedbackElement'];
if(IsSet($arguments['SubmitFeedback']))
$ajax_arguments['SubmitFeedback']=$arguments['SubmitFeedback'];
if(IsSet($arguments['TimeoutFeedback']))
{
$ajax_arguments['TimeoutFeedback']=$arguments['TimeoutFeedback'];
$ajax_arguments['ONTIMEOUT']='';
}
if(IsSet($arguments['CompleteFeedback']))
$ajax_arguments['CompleteFeedback']=$arguments['CompleteFeedback'];
}
}
if(strlen($error=$this->GetCompleteValues($form, $arguments)))
return($error);
if((!$this->dynamic
|| (strlen($error=$form->AddInput($ajax_arguments))==0
&& strlen($error=$form->Connect($this->ajax, $this->input, 'ONCOMPLETE', 'Reposition', array()))==0))
&& (strlen($this->button)==0
|| ((!$this->dynamic
|| strlen($error=$form->AddInput(array(
'TYPE'=>'hidden',
'NAME'=>$this->complete.'t',
'ID'=>$this->complete.'t',
'VALUE'=>''
)))==0)
&& strlen($error=$form->Connect($this->button, $this->input, 'ONCLICK', 'Show', array()))==0))
&& strlen($error=$form->Connect($this->text, $this->input, 'ONBLUR', 'Hide', array('Delay'=>0.2)))==0
&& strlen($error=$form->Connect($this->text, $this->input, 'ONKEYDOWN', 'ControlKeys', array()))==0)
$error=$form->Connect($this->text, $this->input, 'ONKEYUP', 'Complete', array());
return($error);
}
Function GetJavascriptConnectionAction(&$form, $form_object, $from, $event, $action, &$context, &$javascript)
{
switch($action)
{
case 'Complete':
$value=$form->GetJavascriptInputValue($form_object, $this->text);
if(strlen($value)==0)
return('it was not possible to determine how to retrieve value of '.$this->text);
$javascript='if('.(strcmp($event,'ONKEYUP') ? '' : 'event.keyCode!=40 && event.keyCode!=38 && event.keyCode!=27 && event.keyCode!=13 && ').$value.'.length>='.$this->minimum_complete.'){ '.$this->complete.'w++; '.$this->complete.'f='.$form_object.'; setTimeout('."'".$this->complete."()',".$this->complete_delay.'); return false;};';
break;
case 'Hide':
$javascript=$this->complete.'h();';
$delay=(IsSet($context['Delay']) ? intval($context['Delay']*1000) : 0);
if($delay)
$javascript='setTimeout('.$form->EncodeJavascriptString($javascript).', '.$delay.');';
break;
case 'Show':
if($this->dynamic)
{
$submit_context=array('Validate'=>0);
if(strlen($error=$form->GetJavascriptConnectionAction($form_object, $this->input, $this->ajax, 'ONSHOW', 'Submit', $submit_context, $complete_javascript)))
return($error);
$javascript=$this->complete.'f='.$form_object.'; '.$form->GetJavascriptSetInputValue($this->complete.'f', $this->complete.'t', $form->EncodeJavascriptString('a')).' '.$complete_javascript.';';
}
else
$javascript=$this->complete.'f='.$form_object.'; '.$this->complete.'bm('.$this->complete.'i, false); '.$form->GetJavascriptInputObject($form_object, $this->text).'.focus();';
$javascript='if(!'.$this->complete.'o) {'.$javascript.'} return false;';
break;
case 'Reposition':
$javascript=$this->complete.'rp(document.getElementById('.$form->EncodeJavascriptString($this->complete.'m').'), '.$form->GetJavascriptInputObject($form_object, $this->text).');';
break;
case 'ControlKeys':
$javascript='if('.$this->complete.'o) { if(event.keyCode==40 && '.$this->complete.'is<'.$this->complete.'co.length-1) { '.$this->complete.'si('.$this->complete.'is+1); '.$this->complete.'so(t,'.$this->complete.'is); return false; } if(event.keyCode==38 && '.$this->complete.'is>0) { '.$this->complete.'si('.$this->complete.'is-1);'.$this->complete.'so(t,'.$this->complete.'is); return false; } if(event.keyCode==27) { '.$this->complete.'h(); return false; } if(event.keyCode==13) { '.$this->complete.'h(); return true; } };';
break;
default:
return($this->DefaultGetJavascriptConnectionAction($form, $form_object, $from, $event, $action, $context, $javascript));
}
return('');
}
Function AddInputPart(&$form)
{
if($this->dynamic)
{
$submit_context=array('Validate'=>0);
if(strlen($error=$form->GetJavascriptConnectionAction($this->complete.'f', $this->input, $this->ajax, 'ONCOMPLETE', 'Submit', $submit_context, $complete_javascript)))
return($error);
}
$eol=$form->end_of_line;
$b="\n";
$item_style=(strlen($this->item_style) ? $this->item_style : ';');
$selected_item_style=(strlen($this->selected_item_style) ? $this->selected_item_style : ';');
if(strlen($this->item_style_attributes)==0)
{
$this->item_style_attributes=(strlen($this->item_class) ? ' class="'.HtmlSpecialChars($this->item_class).'"' : '').((strlen($this->item_style) || strlen($this->selected_item_style)) ? ' style="'.HtmlSpecialChars($item_style).'"' : '');
}
$menu=$form->EncodeJavascriptString($this->complete.'m');
$text_object = $form->GetJavascriptInputObject($this->complete.'f', $this->text);
$html='<div id="'.HtmlSpecialChars($this->complete.'m').'"'.(strlen($this->menu_class) ? ' class="'.HtmlSpecialChars($this->menu_class).'"' : '').' style="display: block; position: absolute; overflow: auto; visibility: hidden;'.HtmlSpecialChars($this->menu_style).'"></div>'.$b.
'<script type="text/javascript" defer="defer">'.$eol.'<!--'."\n".
'var '.$this->complete.'w=0;'.$b.
'var '.$this->complete.'s=\'\';'.$b.
'var '.$this->complete.'f;'.$b.
'var '.$this->complete.'i'.($this->dynamic ? '' : '='.$this->SerializeItems($form, $this->complete_values)).';'.$b.
'var '.$this->complete.'is=-1;'.$b.
'var '.$this->complete.'o=false;'.$b.
'var '.$this->complete.'co=[];'.$b.
'var '.$this->complete.'l=0;'.$b.
(
$this->dynamic
?
'var '.$this->complete.'c={};'.$b
:
''
).
$eol.
'function '.$this->complete.'()'.$b.
'{'.$b.
'if(--'.$this->complete.'w==0)'.$b.
'{'.$b.
's='.$form->GetJavascriptInputValue($this->complete.'f', $this->text).'.toLowerCase();'.$b.
'if('.$this->complete.'s!=s)'.$b.
'{'.$b.
'm=document.getElementById('.$menu.');'.$b.
'm.style.visibility=\'hidden\'; '.$b.
$this->complete.'o=false;'.$b.
$this->complete.'is=-1;'.$b.
'if(s.length>='.$this->minimum_complete.')'.$b.
'{'.$b.
(
$this->dynamic
?
'if('.$this->complete.'c[s])'.$b.
'{'.$b.
$this->complete.'s=s;'.$b.
$this->complete.'bm('.$this->complete.'c[s], true);'.$b.
'}'.$b.
'else'.$b.
'{'.$b.
$this->complete.'s=s;'.$b.
(
strlen($this->button)
?
$form->GetJavascriptSetInputValue($this->complete.'f', $this->complete.'t', $form->EncodeJavascriptString('')).$b
:
''
).
$complete_javascript.
'}'.$b
:
'o=[];'.$b.
'for (var i=0; i<'.$this->complete.'i.length; i++)'.$b.
'{'.$b.
'if('.$this->complete.'i[i].v.toLowerCase().substr(0,s.length)==s)'.$b.
'o[o.length]='.$this->complete.'i[i];'.$b.
'}'.$b.
'if(o.length)'.$b.
''.$this->complete.'bm(o, true);'.$b
).
'}'.$b.
'}'.$b.
'}'.$b.
'}'.$eol.
'function '.$this->complete.'ss(e,s)'.$b.
'{'.$b.
'if(e.currentStyle)'.$b.
'{'.$b.
'e.style.cssText=s;'.$b.
'}'.$b.
'else'.$b.
'{'.$b.
'e.setAttribute(\'style\', s);'.$b.
'}'.$b.
'}'.$eol.
'function '.$this->complete.'rp(m,t)'.$b.
'{'.$b.
'if(document.getBoxObjectFor)'.$b.
'{'.$b.
'b=document.getBoxObjectFor(t);'.$b.
'x=b.x;'.$b.
'y=b.y+b.height;'.$b.
'w=b.width;'.$b.
'if(window.getComputedStyle)'.$b.
'{'.$b.
's=window.getComputedStyle(t,null);'.$b.
'x-=parseInt(s.borderLeftWidth);'.$b.
'y-=parseInt(s.borderTopWidth);'.$b.
'w-=parseInt(s.borderLeftWidth)+parseInt(s.borderRightWidth);'.$b.
's=window.getComputedStyle(m,null);'.$b.
'w+=parseInt(s.borderLeftWidth)+parseInt(s.borderRightWidth)-parseInt(s.paddingLeft)-parseInt(s.paddingRight);'.$b.
'}'.$b.
'}'.$b.
'else'.$b.
'{'.$b.
'p=t.style.position;'.$b.
't.style.position="relative";'.$b.
'x=t.offsetLeft;'.$b.
'y=t.offsetTop+t.offsetHeight;'.$b.
'w=t.offsetWidth;'.$b.
't.style.position=p;'.$b.
'}'.$b.
'm.style.left=x+"px";'.$b.
'm.style.top=y+"px";'.$b.
'm.style.width=w+"px";'.$b.
'}'.$eol.
'function '.$this->complete.'si(i)'.$b.
'{'.$b.
'if('.$this->complete.'is!=-1)'.$b.
'{'.$b.
's=document.getElementById('.$form->EncodeJavascriptString($this->complete.'m').' + '.$this->complete.'is);'.$b.
((strlen($this->item_class) || strlen($this->selected_item_class)) ? 's.className='.$form->EncodeJavascriptString($this->item_class).';'.$b : '').
((strlen($this->item_style) || strlen($this->selected_item_style)) ? $this->complete.'ss(s, '.$form->EncodeJavascriptString($item_style).');'.$b : '').
'}'.$b.
'if(i!=-1)'.$b.
'{'.$b.
's=document.getElementById('.$form->EncodeJavascriptString($this->complete.'m').' + i);'.$b.
((strlen($this->selected_item_class) || strlen($this->item_class)) ? 's.className='.$form->EncodeJavascriptString($this->selected_item_class).';'.$b : '').
((strlen($this->selected_item_style) || strlen($this->item_style)) ? $this->complete.'ss(s, '.$form->EncodeJavascriptString($selected_item_style).');'.$b : '').
'}'.$b.
$this->complete.'is=i;'.$b.
'}'.$eol.
'function '.$this->complete.'so(t,i)'.$b.
'{'.$b.
'o='.$this->complete.'co;'.$b.
$this->complete.'si(i);'.$b.
'var b=t.value;'.$b.
't.value=o[i].v;'.$b.
'if(b != t.value && t.onchange)'.$b.
' t.onchange()'.$b.
'if(t.createTextRange)'.$b.
'{'.$b.
'if(r=t.createTextRange())'.$b.
'{'.$b.
'r.collapse(true);'.$b.
'r.moveEnd(\'character\', o[i].v.length);'.$b.
'r.moveStart(\'character\', '.$this->complete.'l);'.$b.
'r.select();'.$b.
'}'.$b.
'}'.$b.
'else'.$b.
'{'.$b.
'if(t.setSelectionRange)'.$b.
't.setSelectionRange('.$this->complete.'l,o[i].v.length);'.$b.
'else'.$b.
'{'.$b.
't.selectionStart='.$this->complete.'l;'.$b.
't.selectionEnd=o[i].v.length;'.$b.
'}'.$b.
'}'.$b.
'}'.$eol.
'function '.$this->complete.'bm(o, sv)'.$b.
'{'.$b.
'for(d=\'\',i=0; i<o.length; i++)'.$b.
'{'.$b.
'd+='.$form->EncodeJavascriptString('<div id="'.$this->complete.'m').' + i + '.$form->EncodeJavascriptString('"'.$this->item_style_attributes.' onmouseover="'.$this->complete.'si(').' + i +'.$form->EncodeJavascriptString(');" onmouseout="'.$this->complete.'si(-1);" onmousedown="'.$this->complete.'s=\'\'; var b='.$text_object.'.value;'.$text_object.'.value=').'+o[i].e+'.$form->EncodeJavascriptString('; document.getElementById('.$menu.').style.visibility=\'hidden\';'.$this->complete.'o=false; '.$this->complete.'is=-1; if('.$text_object.'.value != b && '.$text_object.'.onchange) '.$text_object.'.onchange();">').'+o[i].d+'.$form->EncodeJavascriptString('</div>'.$b).';'.$b.
'}'.$b.
'm=document.getElementById('.$menu.');'.$b.
'm.innerHTML=d;'.$b.
't='.$text_object.';'.$b.
$this->complete.'rp(m,t);'.$b.
'm.style.visibility=\'visible\';'.$b.
$this->complete.'o=true;'.$b.
$this->complete.'co=o;'.$b.
'if(sv)'.$b.
'{'.$b.
$this->complete.'l=t.value.length'.$b.
$this->complete.'so(t,0);'.$b.
'}'.$b.
'else'.$b.
'{'.$b.
$this->complete.'l=0'.$b.
$this->complete.'is=-1;'.$b.
'}'.$b.
'}'.$eol.
'function '.$this->complete.'h()'.$b.
'{'.$b.
$this->complete.'s=\'\';'.$b.
'm=document.getElementById('.$form->EncodeJavascriptString($this->complete.'m').');'.$b.
'm.style.visibility=\'hidden\';'.$b.
$this->complete.'o=false;'.$b.
$this->complete.'is=-1;'.$b.
'}'.$eol.
'// -->'.$eol.'</script>';
if(strlen($error=$form->AddDataPart($html))
|| ($this->dynamic
&& strlen($error=$form->AddInputPart($this->ajax)))
|| (strlen($this->button)
&& (strlen($error=$form->AddInputPart($this->button))
|| ($this->dynamic
&& strlen($error=$form->AddInputPart($this->complete.'t'))))))
return($error);
return('');
}
Function Connect(&$form, $to, $event, $action, &$context)
{
switch($action)
{
case 'Complete':
case 'Hide':
case 'Show':
case 'ControlKeys':
return('');
default:
return($this->DefaultConnect($form, $to, $event, $action, $context));
}
}
Function PostMessage(&$form, $message, &$processed)
{
if(strlen($error = $form->LoadInputValues()))
return($error);
$text=$form->GetInputValue($this->text);
$all=(strlen($this->button) && !strcmp($form->GetInputValue($this->complete.'t'), 'a'));
$found=array();
if(($all
|| strlen($text)>=$this->minimum_complete)
&& strlen($error=$this->SearchCompleteValues($form, $s=($all ? '' : strtolower($text)), $found)))
$form->OutputError($error, $this->input);
elseif(count($found))
{
$results=$this->SerializeItems($form, $found);
$s=$form->EncodeJavascriptString($s);
$command=$message['Window'].'.'.$this->complete.'i='.$message['Window'].'.'.$this->complete.'c['.$s.']='.$results.'; if('.$message['Window'].'.'.$this->complete.'s.toLowerCase()=='.$s.') {'.$message['Window'].'.'.$this->complete.'bm('.$message['Window'].'.'.$this->complete.'i, '.($all ? 'false' : 'true').'); '.$form->GetJavascriptInputObject($message['Form'], $this->text).'.focus();}';
$message['Actions']=array(
array(
'Action'=>'Command',
'Command'=>$command
)
);
}
return($form->ReplyMessage($message, $processed));
}
};
?>