1
votes

I have table row I would like a user to be able to edit by populating a form with its record values (table name: Vendor) and then submit the edited data.

I have read and reread the Symfony 1.4 documentation but I am having trouble: 1.) Populating form fields with the existing record data. 2.) Saving the edited form.

The form below is the form used to create a vendor, which as I understand is acceptable for editing an existing record.

As for problem #1 I have tried carrying the existing record values (in the __construct() action) to the form and then setting them as the default values using the $this->setDefaults which works populating the form inputs when redirecting to the the form in the edit action but then the form doesn't work when a user tries to redirect to the form in the create action, which states the default values are not found.

It's also may be worth noting that this module has multiple forms within it. I have no problem creating records with forms, only editing their values once created.

Any direction or suggestions?

Code below.

Controller:

public function executeVendorEdit(sfWebRequest $request)
{
    $ind_vendor = VendorPeer::retrieveByPK(($request->getParameter('id')));
    $this->form = new VendorCreateForm(array('name' => $ind_vendor));

if ($request->isMethod('post')) {

    $this->form->bind($request->getParameter('vendor'));
    if ($this->form->isValid()) {
        $vendor = $this->form->save();

        $this->redirect('catalog/vendorEdit?id=' . $vendor->getId());
        }
}
$this->setTemplate('vendorEdit');
}

Form:

class VendorCreateForm extends SmartForm
{
    protected $is_authenticated = null;
    public function __construct($is_authenticated = false)
    {
        $this->is_authenticated = $is_authenticated;

        parent::__construct();
    }

    public function setup()
    {
        $this->setWidgets(array(
            'name' => new sfWidgetFormInput(array(),
                array('class' => 'form-control')),
            'contact_name' => new sfWidgetFormInput(array(),
                array('class' => 'form-control')),
            'contact_email' => new sfWidgetFormInput(array(),
                array('class' => 'form-control')),
            'contact_phone' => new sfWidgetFormInput(array(),
                array('class' => 'form-control')),
            'address1' => new sfWidgetFormInput(array(),
                array('class' => 'form-control')),
        ));

        $this->setValidators(array(
            'name' => new sfValidatorString(array('required' => true)),
            'contact_name' => new sfValidatorString(array('required' => true)),
            'contact_email'   => new sfValidatorEmail(array('required' => true)),
            'contact_phone' => new sfValidatorString(array('required' => true)),
            'address1' => new sfValidatorString(array('required' => true)),
       ));

        $this->widgetSchema->setNameFormat('vendor[%s]');

        $this->setDefaults(array(
        ));

        parent::setup();
    }
}

Error:

Fatal error: Call to undefined method VendorCreateForm::save() in /projects/fun-project/src/apps/operations/modules/catalog/actions/actions.class.php on line 72

1

1 Answers

0
votes

After much time and frustration I solved both problems. Populating the form with values takes place within the form. It requires passing vendor values to the form in the construct action and then setting default values in the setup action if vendor values exist: if ($this->vendor).

Note: the $is_authenticated declaration and construction is not necessary (check the form I included in the question).

Form:

class VendorCreateForm extends SmartForm
{

protected $vendor = null;

public function __construct($vendor = false)
{
    $this->vendor = $vendor;

    parent::__construct();
}

public function setup()
{
    $this->setWidgets(array(
        'name' => new sfWidgetFormInput(array(),
            array('class' => 'form-control')),
        'contact_name' => new sfWidgetFormInput(array(),
            array('class' => 'form-control')),
        'contact_email' => new sfWidgetFormInput(array(),
            array('class' => 'form-control')),
        'contact_phone' => new sfWidgetFormInput(array(),
            array('class' => 'form-control')),
        'address1' => new sfWidgetFormInput(array(),
            array('class' => 'form-control')),
    ));

    $this->setValidators(array(
        'name' => new sfValidatorString(array('required' => true)),
        'contact_name' => new sfValidatorString(array('required' => true)),
        'contact_email'   => new sfValidatorEmail(array('required' => true)),
        'contact_phone' => new sfValidatorString(array('required' => true)),
        'address1' => new sfValidatorString(array('required' => true)),
   ));

    $this->widgetSchema->setNameFormat('vendor[%s]');

    if ($this->vendor)
    {
        $this->setDefaults(array(
        'name' => $this->vendor->getName(),
        'contact_name' => $this->vendor->getContactName(),
        'contact_email' => $this->vendor->getContactEmail(),
        'contact_phone' => $this->vendor->getContactPhone(),
        'address1' => $this->vendor->getAddress1(),
        ));
    }

    parent::setup();

}

Saving the edited form correctly takes place in the controller. The correct executeVendorEdit action is nearly identical to my executeVendorCreate action with two differences: 1.) retrieving the current object via a Propel Query $this->vendor = VendorPeer::retrieveByPK($request->GetParameter('id')) and 2.) NOT declaring a new model object, but instead saving the values to the current object $this->vendor. Code Below.

Controller

public function executeVendorEdit(sfWebRequest $request)
{
    $this->vendor = VendorPeer::retrieveByPK($request->GetParameter('id'));

    $this->form = new VendorCreateForm($this->vendor);

    if ($request->isMethod('post')) {

        $this->form->bind($request->getParameter('vendor'));
        if ($this->form->isValid())
        {
            $values = $this->form->getValues();

            $this->vendor->setName($values['name']);
            $this->vendor->setContactName($values['contact_name']);
            $this->vendor->setContactEmail($values['contact_email']);
            $this->vendor->setContactPhone($values['contact_phone']);
            $this->vendor->setAddress1($values['address1']);
            $this->vendor->setCreatedTs('now');
            $this->vendor->save();

            $this->redirect('catalog/vendors');
        }
    }
}