We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Autopopulate field in form - Updating record

Hello guys!

I have a volt template with a form and forms element (I'm using Phalcon Forms like {{ text_field("nickname", "required" : "required", "class" : "form-control", "id" : "nickname", "placeholder" : "Choose your nickname") }})

So all elements are on Front-End :-(

The question is: How can I pass an Object to be used in the form and autopopulate? Also, it will work for Select elements?

I also have a "custom controls", like:

1 Input, 1 button - when the user press the button, the input content will be added to an array an the value will be showed in a <ul> behind the controls - That is a hackish control por user-custom multi-valued inputs (btw, is there a better approach for this?).

Thanks for reading!



85.5k
edited Jan '18

a complete form

<?php

namespace Whatever\Frames\Forms;

use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;
use Phalcon\Forms\Element\Hidden;
use Phalcon\Forms\Element\TextArea;
use Whatever\Models\{
    FrameTypes, FrameColors
};

class Add extends \Phalcon\Forms\Form
{

    public function initialize($entity = null, $options = [])
    {

        $name = new Text("name", [
            "class" => "form-control"
        ]);

        $this->add($name);

        $text = new TextArea("text", [
            "class" => "form-control"
        ]);

        $this->add($text);

        $hiddenField = new Hidden("id");

        $this->add($hiddenField);

        //this is your usual select
        $primalColor = new Select("primal_color", FrameColors::find([
            "conditions" => "shown != 0"
        ]), [
            "class" => "form-control",
            "using" => [
                "id",
                "name",
            ]
        ]);

        if ($entity &&  $entity->getPrimalColor() !== 0) {
            $primalColor->setDefault($entity->getPrimalColor());
        }

        $this->add($primalColor);

        //this is select2 field with multiple options
        $colors = new Select("alt_colors[]", [], [
            "class" => "form-control frame-colors-input",
            "multiple" => "multiple",
            "using" => [
                "id",
                "name",
            ]
        ]);

        if ($entity &&  false === empty($entity->getAltColors())) {

            $str = $entity->getAltColors();
            $pr = FrameColors::find([
                "conditions" => "id in ({arr:array})",
                "bind" => [
                    "arr" => explode(",", $str)
                ]
            ]);

            $colors->setOptions($pr);
            $colors->setDefault(explode(",", $str));
        }

        $this->add($colors);
    }
}

now when you want to create a new product ( or whatever ) in your controller;


//create
$this->view->setVar("form", new Form());
//edit | update
$this->view->setVar("form, new Form( Model::findFirstById(1));

also as far as I remember, forms automatically was checking for post ( or get i am not 100% sure ), to automatically fill the data

honestly i write the radio buttons and checkboxes in the forntend and i handle "checked" there with ifs. but u can use the same logic as above

in volt is

   this.view.getVar("form").render("-field-name-goes-here")


13.8k

Hi Izo, thanks for reply!

The main problem is that my form Elements are not in PHP file but in a volt file. This is because there are more "custom fields" that normal fields.

For custom fields, I mean custom-write multiple inputs, and things that need JS events and vectors.

is there any solution to send the object to at least the normal Phalcon Form Elments that are in a volt template?

a complete form

<?php

namespace Whatever\Frames\Forms;

use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;
use Phalcon\Forms\Element\Hidden;
use Phalcon\Forms\Element\TextArea;
use Whatever\Models\{
   FrameTypes, FrameColors
};

class Add extends \Phalcon\Forms\Form
{

   public function initialize($entity = null, $options = [])
   {

       $name = new Text("name", [
           "class" => "form-control"
       ]);

       $this->add($name);

       $text = new TextArea("text", [
           "class" => "form-control"
       ]);

       $this->add($text);

       $hiddenField = new Hidden("id");

       $this->add($hiddenField);

       //this is your usual select
       $primalColor = new Select("primal_color", FrameColors::find([
           "conditions" => "shown != 0"
       ]), [
           "class" => "form-control",
           "using" => [
               "id",
               "name",
           ]
       ]);

       if ($entity &&  $entity->getPrimalColor() !== 0) {
           $primalColor->setDefault($entity->getPrimalColor());
       }

       $this->add($primalColor);

       //this is select2 field with multiple options
       $colors = new Select("alt_colors[]", [], [
           "class" => "form-control frame-colors-input",
           "multiple" => "multiple",
           "using" => [
               "id",
               "name",
           ]
       ]);

       if ($entity &&  false === empty($entity->getAltColors())) {

           $str = $entity->getAltColors();
           $pr = FrameColors::find([
               "conditions" => "id in ({arr:array})",
               "bind" => [
                   "arr" => explode(",", $str)
               ]
           ]);

           $colors->setOptions($pr);
           $colors->setDefault(explode(",", $str));
       }

       $this->add($colors);
   }
}

now when you want to create a new product ( or whatever ) in your controller;


//create
$this->view->setVar("form", new Form());
//edit | update
$this->view->setVar("form, new Form( Model::findFirstById(1));

also as far as I remember, forms automatically was checking for post ( or get i am not 100% sure ), to automatically fill the data

honestly i write the radio buttons and checkboxes in the forntend and i handle "checked" there with ifs. but u can use the same logic as above



85.5k
Accepted
answer

i am not sure if i understood you


//controller
$this->view->setVar("record", model::findFirstById(1));

//volt

{% set myVeryCustomElement = text_field(.......) %}

{% if record.name is not empty %}
myVeryCustomElement.setDefault(record.name)
{%endif}

but i have no idea if this wourld work :D



13.8k

By mistake I marked this reply as solved :-/

Your code seems interesting, I will check it up later ;-D

I have customs controls like this:

Suppose 1 input and 1 button, you can write anything in that input, like your pet's name ;-D then you need to click the button to "add" that pet name in the "form memory" (that's an arbitrary name), this actions will add the value to an array that will converted in JSON and passed input an input hiden in the form submission. Also, in the UI, the value of the input will added in a <ul> HTML element with a small button to remove then form UI and from the vector.

That is the simplest custom form I have :-(

I have few normal Form elements, but would be cool to add automatically its values. I think I will pass the value directly from the Controller to the view and add pseudo-manually :/

i am not sure if i understood you


//controller
$this->view->setVar("record", model::findFirstById(1));

//volt

{% set myVeryCustomElement = text_field(.......) %}

{% if record.name is not empty %}
myVeryCustomElement.setDefault(record.name)
{%endif}

but i have no idea if this wourld work :D



85.5k

seems like you have some JS involded ? usually if i do stuff like this ( dynamic forms, where you click a button and new field pops up ) i use JS for everything, includidng ensure edit values ( when user wants to edit )

//volt
<div class="main-pet-container" data-values="[{name: "pet1"}, { name : "pet2"}] //this.view.getVar("jsonPetNames")

</div>

//js
$(".main-pet-container").data("values").forEach( ( pet ) => {} )); ....

at least this is what I understand that you are doign



13.8k

That's correct, well, I wished to save to do all that manual job that involves, but it's ok. Thanks for you replies.

By the way, if in my controller I do: $this->view->jsonPetName, which is the differenci between getting with {{ jsonPetNames }} and {{ this.view.getVar("jsonPetNames") }}?



85.5k

getVar can return null, while jsonPetName can return undefined index ( warrning ) , you should be using setters and getters everytime and everywhere, no matter the language / framework



13.8k

Wise advice! Thank you!

getVar can return null, while jsonPetName can return undefined index ( warrning ) , you should be using setters and getters everytime and everywhere, no matter the language / framework