0

I want to submit a form whose field is an array of an unknown number of elements.

class DynamicForm extends Model
{
    /** var string[] */
    public elements[];
}

Inside the view that there is the form submission, I want to add a button which has an 'onclick' Javascript function, which adds a new field in the form innerHtml. Unfortunately, I can't find a way to embed some PHP code inside my javascript expression. Here is where I am right now:

<?php
$form = ActiveForm::begin([
    'id' => 'test-form',
    'layout' => 'horizontal',
    'fieldConfig' => [
        'errorOptions' => [
            'role' => 'alert',
        ],
        'horizontalCssClasses' => [
            'label' => 'col-sm-3',
            'offset' => 'col-sm-offset-3',
            'wrapper' => 'col-sm-9',
            'error' => '',
            'hint' => '',
        ],
    ],
]); 
$formField = $form->field($model, 'elements[]', []);

$JsFunction = new \yii\web\JsExpression(
    "function addField() {
        document.getElementById(\"test-form\").innerHTML += \"<?php echo $formField; ?>\";
    }; 
    addField();"
);

echo Html::button(
    'Add element',
    [
        'class' => 'btn btn-primary',
        'onclick' => $JsFunction,
    ]
);
?>

Strange thing is that, if I put inside the innerHTML a string like "<p>hello!</p>", it works perfectly. Another strange thing is that, if I put the HTML code that the 'php echo' command generates,

'<input type=\"text\" id=\"dynamicform-elements\" class=\"form-control\" name=\"DynamicForm[elements][]\">'

it still works!

Although I think that entering manual HTML code for Yii::ActiveForm is not a really good practice, that's why I want the PHP to do the job for it.

Thank you in advance!

cj_panpet
  • 1
  • 1
  • 1
  • Possible duplicate of [What is the difference between client-side and server-side programming?](http://stackoverflow.com/questions/13840429/what-is-the-difference-between-client-side-and-server-side-programming) – Jared Smith Mar 07 '17 at 13:52

2 Answers2

0

In view;

$this->registerJs("addField(". $formField  .")", 3);
$this->registerJsFile('/js/file.js', ['position' => 3]);

in file.js

"function addField(variable) {
    document.getElementById("test-form").innerHTML += variable;
}; 

In JavaScript file you can create class with params of constuctor for better customize class. e.g

var class = function (config) {
        this.var1= config;

function addField() {
        document.getElementById("test-form").innerHTML += this.var1;
    }
};

and in View PHP;

$this->registerJs("var addField = new Class(".\yii\helpers\Json::encode($same_array).")", 3); 
Rafal
  • 573
  • 5
  • 11
  • Unfortunately this does not work. I get an "Unexpected token <" error in `$this->registerJs("addField(". $formField .")", 3);`. This was the error I get everytime Javascript "meets" the code that PHP generated. – cj_panpet Mar 07 '17 at 14:22
0

I finally managed to solve this, it was a problem with some characters of PHP's html generated code. If I do:

$formField = $form->field($model, 'elements[]', []);
$formField = str_replace(["\r\n", "\n", "\r"], ' ', $formField);
$formField = str_replace(["\""], '\'', $formField);
$this->registerJs('var addField = function(field) {
    form = document.getElementById(\'my-form\');
    form.innerHTML += field;
};', View::POS_HEAD);

echo Html::button(
    'Add keyword',
    [
        'id' => 'myButton',
        'class' => 'btn btn-primary',
        'onclick' => 'addField("' . $formField . '")',
    ]
);

...works perfectly.

cj_panpet
  • 1
  • 1
  • 1