2011-02-15 5 views
3

Я искал метод проверки полей формы в symfony через jquery и ajax. Я видел, что ppl предлагает использовать проверку jquery и другие внешние библиотеки, но я просто понял, что есть более быстрый способ.Symfony ajax field validation

Вы можете, например, настроить прослушиватель событий на каждое поле с помощью функции .each() jquery и отправить ajax-запрос в symfony с помощью json-объекта, содержащего соответствующее поле, и значение, предоставленное пользователем.

На симфони стороне может быть такой:

$jsonValues = $request->getParameter('json_values'); 
$field = array_keys($jsonValues); 
$field = $field[0]; 
$this->form = new $this->formName(); 
$vs = $this->form->getValidatorSchema(); 
try { 
    $toValidate = $vs[$field]->clean($jsonValues[$field]); 
} catch (sfValidatorError $e) { 
    return $this->renderText($e->getMessage()); 
} 
return $this->renderText('ok'); 

Что вы думаете об этой идее? Есть ли лучший?

+0

Это похоже на хорошее решение для меня, тем более, что вы DRY-ly используете валидаторы, уже определенные в symfony. – yitznewton

ответ

3

Хорошо этот метод работает, но каждый раз, когда вы посылаете в запросе Symfony создает всю форму, так что я создал абстрактный класс между классом формы и классом Base формой:

abstract class wsExtensionForm extends BaseForm { 

    protected $widgetClass = 'input-widget'; 

    public function configure() { 
    $user = sfContext::getInstance()->getUser(); 
    $ftw = $user->hasAttribute('fieldToValidate') ? $user->getAttribute('fieldToValidate') : false; 

    if ($ftw) { 
     $this->generateValidator($ftw, $this->validatorsConfig[$ftw]); 
     $user->getAttributeHolder()->remove('fieldToValidate'); 
    } else { 
     $this->generateWidgets($this->widgetsConfig, $this->widgetClass); 
     $this->generateValidators($this->validatorsConfig); 
     $this->generateLabels($this->labelsConfig); 
    } 
    } 

    protected function generateWidget($wConfig) { 

    } 

    protected function generateValidator($id, $vConfig) { 
    if (!is_array($vConfig)){ 
     if ($vConfig == 'sfValidatorChoice') { 
     $methodName = 'get'.ucfirst($id).'Choices'; 
     $this->validatorSchema[$id] = new $vConfig(array('choices' => array_keys($this->$methodName()), 'multiple' => false), array()); 
     } else { 
     $this->validatorSchema[$id] = new $vConfig(); 
     } 
    } 
    } 

    protected function generateHelp($hConfig) { 

    } 

    protected function generateWidgets($wsConfig, $class) { 
    foreach($wsConfig as $id => $widget) { 
     if (!is_array($widget)) { 
     if ($widget == 'sfWidgetFormInputText') { 
      $this->widgetSchema[$id] = new $widget(array(), array('class' => $class)); 
     } elseif($widget == 'sfWidgetFormChoice') { 
      $methodName = 'get'.ucfirst($id).'Choices'; 
      $this->widgetSchema[$id] = new $widget(array('choices' => $this->$methodName(), 'multiple' => false, 'expanded' => false), array('class' => $class)); 
     } 
     } 
    } 
    } 

    protected function generateValidators($vsConfig) { 
    foreach ($vsConfig as $id => $validator) { 
     if (!is_array($validator)){ 
     if ($validator == 'sfValidatorChoice') { 
      $methodName = 'get'.ucfirst($id).'Choices'; 
      $this->validatorSchema[$id] = new $validator(array('choices' => array_keys($this->$methodName()), 'multiple' => false), array()); 
     } else { 
      $this->validatorSchema[$id] = new $validator(); 
     } 
     } 
    } 
    } 

    protected function generateLabels($lsConfig) { 
    $this->widgetSchema->setLabels($lsConfig); 
    } 

    protected function generateHelps($hsConfig) { 

    } 
} 

После этого вы может сделать это в вашем контроллере:

public function executeProc(sfWebRequest $request) { 
// checking if request parameters are OK 
$this->initAction($request->getParameter('form_category'), $request->getParameter('form_id')); 
if ($request->isXmlHttpRequest()) { 
    $field = $request->getParameter('field'); 
    $field = explode('_', $field); 
    $field = array_reverse($field); 
    $field = $field[0]; 
    $fieldValue = $request->getParameter('fieldValue'); 
    $this->getUser()->setAttribute('fieldToValidate', $field); 
    $this->form = new $this->formName(); 
    $vs = $this->form->getValidatorSchema(); 
    try { 
    $toValidate = $vs[$field]->clean($fieldValue); 
    } catch (sfValidatorError $e) { 
    return $this->renderText($e->getMessage()); 
    } 
    return $this->renderText('ok'); 
} else { 
    $this->form = new $this->formName(); 
    if ($request->isMethod('post')) { 
    $this->form->bind($request->getParameter($this->nameFormat)); 
    if ($this->form->isValid()) { 
    exit('valid'); 
    } 
    } else { 
    $this->forward404(); 
    } 
    $this->form->getWidgetSchema()->setNameFormat($this->nameFormat.'[%s]'); 
    $this->setTemplate('show'); 
} 

}

и Symfony не генерирует всю форму, так что вы можете сохранить несколько циклов центрального процессора.