Skip to content
Advertisement

Yii2 redirect to specific tab from controller using url hash(#) or Fragment

This the relevant code in my form:

<?php $form = ActiveForm::begin ( [ 'id' => 'dynamic-form' , 'layout' => 'horizontal' , 'enableClientValidation' => true , 'enableAjaxValidation' => true ] ); ?>
<div class="panel panel-default">
    <div class="panel-body nav-tabs-animate nav-tabs-horizontal">
        <ul class="nav nav-tabs nav-tabs-line" data-plugin="nav-tabs" role="tablist">
            <li class="active" role="presentation"><a data-toggle="tab" href="#information" aria-controls="information" role="tab">
                    <?= Yii::t ( 'app' , 'Information' ); ?></a></li>    
            <li role="presentation"><a data-toggle="tab" href="#rest_days" aria-controls="rest_days" role="tab">
                    <?= Yii::t ( 'app' , 'Rest Days' ); ?></a></li>
            <li role="presentation"><a data-toggle="tab" href="#instructor_schedule" aria-controls="instructor_schedule" role="tab">
                    <?= Yii::t ( 'app' , 'Instructor Schedule' ); ?></a></li>
        </ul>
    </div>
</div>

and the code in controller:

public function actionUpdate( $id ) {
    $model = $this->findModel ( $id );

    if ( $model->load ( Yii::$app->request->post () ) && $model->save () ) {
        Yii::$app->getSession ()->setFlash ( 'successClass' );
        // return $this->redirect(['view', 'id' => $model->id]);
        return $this->redirect ( [ 'user/update-instructor' , 'id' => $model->instructor_id , '#' => 'instructor_schedule' ] );
    }
    return $this->render ( 'update' , [
                'model' => $model ,
    ] );
}

I want to redirect to the tab –instructor_schedule, it is redirecting correctly to user/update-instructor, but not going to the specific tab, but the first tab.

How I can achieve this?

Update View file – update_instructor.php

use yiiwidgetsPjax;
/* @var $this yiiwebView */
/* @var $model appmodelsUser */
$tab='';
if (isset($_GET["tab"])){
$tab= $_GET['tab'];
}
if(!empty($tab)){
$this->registerJs ( "$('#dynamic-form .nav-tabs a[href="#".$tab.""]').tab('show');" , yiiwebView::POS_READY );
}

$this->title = $title . ' ' . $model->first_name . ' ' . $model->last_name;
$this->params['breadcrumbs'][] = ['label' => 'Instructors', 'url' => ['instructor']];
//$this->params['breadcrumbs'][] = ['label' => $model->first_name.' '.$model->last_name, 'url' => ['view', 'id' => $model->id]];
$this->params['breadcrumbs'][] = $this->title;
$manager = User::find()->where(['user_role' => 'manager'])->andwhere(['status' => 10])->all();
$manager_array = ArrayHelper::map($manager, 'id',
    function ($model) {
        return $model->first_name . ' ' . $model->last_name . '(' . $model->manager->location['location_title'] . ')';
    });
?>



<?php $form = ActiveForm::begin(['id' => 'dynamic-form', 'layout' => 'horizontal', 'enableClientValidation' => true, 'enableAjaxValidation' => true]);?>
  <div class="panel panel-default">
      <div class="panel-body nav-tabs-animate nav-tabs-horizontal">
      <ul class="nav nav-tabs nav-tabs-line" data-plugin="nav-tabs" role="tablist">
        <li class="active" role="presentation"><a data-toggle="tab" href="#information" aria-controls="information" role="tab">
          <?=Yii::t('app', 'Information');?>
        </a></li>

        <li role="presentation"><a data-toggle="tab" href="#rest_days" aria-controls="rest_days" role="tab">
          <?=Yii::t('app', 'Rest Days');?>
        </a></li>
        <li role="presentation"><a data-toggle="tab" href="#instructor_schedule" aria-controls="instructor_schedule" role="tab">
          <?=Yii::t('app', 'Instructor Schedule');?>
        </a></li>
        <li role="presentation"><a data-toggle="tab" href="#custom_break_time" aria-controls="custom_break_time" role="tab">
          <?=Yii::t('app', 'Break Time');?>
        </a></li>


......

<div class="tab-content"> <br clear="all">
        <!-- start information tab -->
        <div class="tab-pane active animation-slide-left" id="information" role="tabpanel">
.....

<?php
if (!$model->isNewRecord) {
    ?>
        <div class="tab-pane animation-slide-left" id="rest_days" role="tabpanel">
          <?php DynamicFormWidget::begin([
....

<?php
if (!$model->isNewRecord) {
    ?>
          <div class="tab-pane animation-slide-left" id="instructor_schedule" role="tabpanel">
              <?php $this->title = Yii::t('app', 'Class Durations');
              $this->params['breadcrumbs'][] = $this->title;
            ?>

......

<?php
if (!$model->isNewRecord) { ?>
<div class="tab-pane animation-slide-left" id="custom_break_time" role="tabpanel">
 <?php   $this->title = Yii::t('app', 'Custom Break Times');
$this->params['breadcrumbs'][] = $this->title;
?>

.....

controller – ClassDurationController.php

public function actionUpdate($id,$tab='information') {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            Yii::$app->getSession()->setFlash('successClass');

            // return $this->redirect(['view', 'id' => $model->id]);
                        return $this->redirect(['user/update-instructor', 'id' => $model->instructor_id, 'tab' => 'instructor_schedule']);
        }

        return $this->render('update', [
            'model' => $model,                        
        ]);
    }

Advertisement

Answer

The main thing is that your hash # or fragment is resolved in the browser and never sent to the server, its reachable through javascript though.

If you are ok with changing your fragment to a parameter do the following.

I assume you are using bootstrap tabs.

  1. Change your actionUpdate($id) to actionUpdate($id,$tab='information').

  2. Change the code for redirect to

    return $this->redirect(
        [
            'user/update-instructor', 
            'id' => $model->instructor_id, 
            'tab' => 'instructor_schedule'
        ]
    );
    
  3. Then add the following inside your view file

    $js=<<<JS 
         $('#dynamic-form .nav-tabs a[href="#".$tab.""]').tab('show');        
    JS;
    
    $this->registerJs ( $js , yiiwebView::POS_READY );
    

Now if your url is http://www.yoursite.com/update?id=1 it will always show your the first tab and if http://www.yoursite.com/update?id=1&tab=instructor_schedule it will show the instructor_schedule tab or any other if valid name provided.

Hope this solves your problem.

EDIT

You should remove the active class from the li and the tabs to disable the showing of the default tab and then switching to the selected issue, that is what causing it

see the 2 culprits below

<li class="active" role="presentation">
    <a data-toggle="tab" href="#information" aria-controls="information" role="tab">
        <?=Yii::t('app', 'Information');?>
    </a>
</li>

and the tab

<div class="tab-pane active animation-slide-left" id="information" role="tabpanel">
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement