Not able to submit form inside footer in Yii2

311 Views Asked by At

I've a subscribe newsletter form inside footer that display on all page. To do this I've created a subscriber widget like this:

SubscriberWidget.php

<?php
namespace frontend\components;

use Yii;
use yii\base\Widget;
use yii\helpers\Html;
use frontend\models\SubscribeNewsletterForm;

class SubscriberWidget extends Widget
{

    public function run()
    {
        $subscriber_model  = new SubscribeNewsletterForm();

        return $this->render('_subscribe-newsletter-form.php', [
            'subscriber_model' => $subscriber_model
        ]);
    }
}
?>

Here's the SubscribeNewsletterForm model code:

SubscribeNewsletterForm.php

<?php

namespace frontend\models;

use Yii;
use yii\base\Model;

class SubscribeNewsletterForm extends Model
{
    public $email;

    public function rules()
    {
        return [
            [['email'], 'required'],
            ['email', 'email']
        ];
    }
}
?>

Here is the code of my _subscribe-newsletter-form.php

<?php

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\helpers\Url;

?>

<h3>Subscribe to Newsletter</h3>
<?php $form = ActiveForm::begin(['id' => $subscriber_model->formName(), 'action' => ['project/subscriber'], 'validateOnBlur' => false, 'validateOnType' => false]); ?>
    <div class="input-group">
        <?= $form->field($subscriber_model, 'email')->textInput()->label(false); ?>                             
        <span class="input-group-btn">
            <?php echo Html::submitButton('Sign Up', ['class' => 'btn btn-primary subscribe-btn']); ?>
        </span>                             
    </div>
<?php ActiveForm::end(); ?>

<?php
$script = <<< JS
    $('#{$subscriber_model->formName()}').on('beforeSubmit', function(e){
        var form = $(this);
        $.post(
            form.attr("action"),
            form.serialize()
        ).done(function(data){      
            form.trigger("reset");
        })
        return false;
    });
JS;
$this->registerJs($script);
?>

Inside ProjectController.php I've created the action as follow:

public function actionSubscriber()
    {
        $subscriber_model  = new SubscribeNewsletterForm();

        $request = Yii::$app->request;
        if($request->isAjax && $subscriber_model->load($request->post())){
            $subscriber =  new Subscriber([
                'email' => $subscriber_model->email
            ]);
            $subscriber->save();
        }
    }

Here's the Subscriber model code.

Subscriber.php

<?php

namespace frontend\models;

use yii\db\ActiveRecord;

class Subscriber extends ActiveRecord
{
    public static function tableName()
    {
        return 'subscriber';
    }
} 
?>

frontend/config/main.php

<?php
$params = array_merge(
    require(__DIR__ . '/../../common/config/params.php'),
    require(__DIR__ . '/../../common/config/params-local.php'),
    require(__DIR__ . '/params.php'),
    require(__DIR__ . '/params-local.php')
);

return [
    'id' => 'app-frontend',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'controllerNamespace' => 'frontend\controllers',
    'components' => [
        'request' => [
            'csrfParam' => '_csrf-frontend',
        ],
        'user' => [
            'identityClass' => 'common\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
        'session' => [
            // this is the name of the session cookie used for login on the frontend
            'name' => 'advanced-frontend',
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        /*
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
        */
    ],
    'params' => $params,
];
?>

With above code validation is working but i'm not able to save the email in database. Please tell what i'm doming wrong.

1

There are 1 best solutions below

9
Wade On

You need rules on your Model. Also, I always replace the generated tables names with the table prefix supported method. Also, I always like to use the Timestamp behavior to log when things are created or updated. Especially when your grabbing contact info for the use of leads, I would record the timestamps as well as their IP Address.

Subscriber.php

use yii\behaviors\TimestampBehavior;

// ...

/**
 * @inheritdoc
 */
public static function tableName()
{
    return '{{%subscriber}}';
}

/**
 * @inheritdoc
 */
public function behaviors()
{
    return [
        TimestampBehavior::className(),
    ];
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        ['email', 'filter', 'filter' => 'trim'],
        ['email', 'required'],
        ['email', 'email'],
        ['email', 'string', 'max' => 255],
        ['email', 'unique', 'targetClass' => '\common\models\Subscriber', 'message' => 'This email address has already been taken.'],

        [['created_at', 'updated_at'], 'integer'],
    ];
}