ActiveForm action not working for Ajax

Hi, I’m working on a project where I have to modify some files. I have a problem understanding how Yii works with form’s action with ajax.
Basically my code looks like this :

 <?php $form = \yii\widgets\ActiveForm::begin([
            'id' => 'comment-post-id-' . $post->id,
            'action' => ['application/controllers/comment/post-comment'],
            'method' => 'post',
            'options' => ['enctype' => 'multipart/form-data']
        ]); ?>

        <div class="form-group">
            <label class="form-label"></label>
            <textarea id="comment_content_textarea_<?= $post->id ?>" name="comment-content" style="display: none"></textarea>
            <input type="hidden" name="post-id" value="<?= $post->id ?>">
            <input type="hidden" name="user-id" value="<?= $currentUser->id ?>">
            <input type="hidden" name="_csrf" value="<?= Yii::$app->request->getCsrfToken() ?>" />
        </div>

        <?= Html::submitButton(Yii::t('app', 'Send'), ['class' => 'btn float-right btn-primary']); ?>
        <?php $form->end(); ?>

Here if I use the usual way to set my action I would have got : ‘action’ => [‘comment/post-comment’]
but it doesn’t work, it return me an uncorrect url. Having the forms not generated with the model is useful for me because I need a contenteditable div tag.
Then I have my js for Ajax which looks like this :

$postId = $post->id;
$commentScript = <<<JS
            jQuery(document).ready(function () {
                $('form#comment-post-id-$postId').submit(function(e){
                    e.preventDefault();
                    var data = $('form#comment_content_textarea_$postId').serialize();
                    $.ajax({
                        url: $('form#comment-post-id-$postId').attr('action'),
                        type: 'POST',
                        data: data,
                        success: function (data) {
                            alert('Comment sent')
                        },
                        error: function(jqXHR, errMsg) {
                            alert(errMsg);
                        }
                    });
                });
            });
 JS;
 $this->registerJs($commentScript);

Then my action looks like this :

public function actionPostComment()
{
    $comment = new Comment();
    $comment->post_id = Yii->$app->request->post('post-id');
    $comment->forum_id = Yii->$app->request->post('forum-id');
    $comment->user_id = Yii->$app->request->post('user-id');
    $comment->content = Yii->$app->request->post('comment-content');
    
    $comment->save()

}

I’m removed the validation step because I need to solve this problem first.
That’s how I’m proceeding and it doesn’t work when it comes to the ActiveForm action in the view part.
I get a POST 404 not found error even though the action is technically good. It seems like it doesn’t recognizes either the controller or the action itself.

So one question is : Is the action supposed to understand the link to the action like this ? :
‘action’ => [‘comment/post-comment’]
=
CommentController::actionPostComment()
and it passes the post parameter

I think there is something I didn’t get about how Yii works with action. Most troobleshooting topics I saw on the web never mentionned this problem. Maybe I miss-read something on the documentation.

If you get what I’m trying to solve please help me.
Thank you for reading this.

A suggestion, as I cannot tell if you are using basic or advanced template or whether ‘application’ should be interpreted as module, absolute path or relative path
If not already done so, look at how the ‘action’ is interpreted by ActiveForm api, which will use baseUrl helper

If ‘application’ a module, if so, and the module is correctly bootstrapped, then the action [‘comment/post-comment’] should work as it is considered to be a route relative to the current module and will prepend the module’s uniqueId.

In Yii2 basic to access the module, you need to add this to your application configuration:

    'modules' => [
        'application' => [
            'class' => 'app\modules\application\Module',
        ],
    ],
1 Like

Thank you for your answer.
I managed to get the solution thanks to you.
The file I was working on is outside the application folder and the urlManager affecting my route to controller action was not the right one or had no effect on it at least.
There was some project confirguration difficult to understand, so I simplified it.
Now everything works.

Thanks again :smiley:.