Hi. I have one issue with the Navbar widget of the yii2-bootstrap4 extension (https://github.com/yiisoft/yii2-bootstrap4). Sorry if this is quite large, but, i want to describe my process so any could point me out what i am doing wrong.
I started installing yii2 through composer (basic template). After that, still using composer, i installed the extension for bootstrap4. After that I downloaded the bootstrap sources from the official web site and put them in a folder under the assets folder (@app/assets/source/bootstrap) and i made the necessary changes to the assetmanager component in @app/config/web.php to use these files for bootstrap:
'assetManager' => [
'bundles' => [
'yii\bootstrap4\BootstrapAsset' => [
'sourcePath' => '@app/assets/source/bootstrap/dist',
'css' => [
YII_ENV_DEV ? 'css/bootstrap.css' : 'css/bootstrap.min.css',
],
],
'yii\bootstrap4\BootstrapPluginAsset' => [
'sourcePath' => '@app/assets/source/bootstrap/dist',
'js' => [
YII_ENV_DEV ? 'js/bootstrap.js' : 'js/bootstrap.min.js',
],
],
],
]
Also i changed the $depends variable in @app/assets/AppAsset.php to use the extension for bootstrap4 instead of the default bootstrap3:
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap4\BootstrapAsset',
];
After all this, i tested the default project generated by the basic template in the browser and the top navbar was not rendering correctly. I noted that the css classes in @app/views/layout/main.php that are set in the Navbar::begin section were slightly different in bootstrap 4, so i changed them (i took the example from the Bootstrap web site):
<?php
NavBar::begin([
'brandLabel' => Yii::$app->name,
'brandUrl' => Yii::$app->homeUrl,
'options' => [
//'class' => 'navbar-inverse navbar-fixed-top',
'class' => 'navbar navbar-expand-lg navbar-light bg-light',
],
]);
echo Nav::widget([
//'options' => ['class' => 'navbar-nav navbar-right'],
'options' => ['class' => 'navbar-nav mr-auto'],
'items' => [
['label' => 'Home', 'url' => ['/site/index'], 'options' => ['class' => 'nav-item']],
['label' => 'About', 'url' => ['/site/about'], 'options' => ['class' => 'nav-item']],
['label' => 'Contact', 'url' => ['/site/contact'], 'options' => ['class' => 'nav-item']],
Yii::$app->user->isGuest ? (
['label' => 'Login', 'url' => ['/site/login'], 'options' => ['class' => 'nav-item']]
) : (
'<li>'
. Html::beginForm(['/site/logout'], 'post')
. Html::submitButton(
'Logout (' . Yii::$app->user->identity->username . ')',
['class' => 'btn btn-link logout']
)
. Html::endForm()
. '</li>'
)
],
]);
NavBar::end();
?>
And now the navbar is rendering as expected. But here comes my issue: If i resize the browser for testing the responsive feature, the toggle button didn’t show when the navbar items are hidden. Inspecting the code generated by the widget i found this snippet were the toggle button is supposed to be rendered:
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#w0-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
Verifying from the Bootstrap official documentation of the NavBar i found that the html should be:
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#w0-collapse" aria-controls="w0-collapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span></button>
There is just one span element inside the button element and has the css class: “navbar-toggler-icon”. I modified the page code using chrome developer tools to verify if that is the reason of my issue and deleted all three span elements generated and put the one from Bootstrap official documentation and voila! it worked as expected.
Checking the Navbar widget code inside @app/vendor/yiisoft/yii2-bootstrap4/src/NavBar.php i found this variable:
public $togglerContent = '<span class="navbar-toggler-icon"></span>';
which is used in this function:
protected function renderToggleButton()
{
$options = $this->togglerOptions;
Html::addCssClass($options, ['widget' => 'navbar-toggler']);
return Html::button(
$this->togglerContent,
ArrayHelper::merge($options, [
'type' => 'button',
'data' => [
'toggle' => 'collapse',
'target' => '#' . $this->collapseOptions['id'],
],
'aria-controls' => $this->collapseOptions['id'],
'aria-expanded' => 'false',
'aria-label' => $this->screenReaderToggleText,
])
);
}
which in turn is called here:
public function init()
{
parent::init();
/*... all the code for render the component */
echo $this->renderToggleButton() . "\n";
echo Html::beginTag($collapseTag, $collapseOptions) . "\n";
}
So in theory the span element should be in the html rendered, but instead, four span elements, which i couldn’t find where are generated, are rendered in the final html. And for that, the toggle button is not showed when i resize browser.
Has somebody faced this issue? It is something i am doing wrong?
Thank you very much for your replies, and again, very sorry for the post’s length.