I have a dropdown for submit form, now issue is when I run test, it gives error:
1) Failed to ensure that clients create works in tests\codeception\frontend\acceptance\ClientCrudCest::testClientCreate (.\acceptance\ClientCrudCest.php)
Step I click "schedule_pending"
Fail Link or Button by name or CSS or XPath element with 'schedule_pending' was not found.
Scenario Steps:
13. $I->click("schedule_pending") at _pages\ClientCrudPage.php:26
12. // I am going to submit client form with no data
11. $I->see("Client Profile") at acceptance\ClientCrudCest.php:63
10. $I->see("Add Client","h3") at acceptance\ClientCrudCest.php:62
9. $I->amOnPage("/frontend/web/index-test.php/clients/create") at tion\BasePage.php:77
8. $I->dontSeeLink("Sign In") at acceptance\ClientCrudCest.php:56
FAILURES!
Tests: 1, Assertions: 4, Failures: 1.
Here is Dropdown buttons:
<ul class="dropdown-menu" role="menu">
<li>SAVE & PENDING</li>
<li>SAVE & ENROLLMENT</li>
<li>SAVE & APPOINTMENT</li>
<li>SAVE & EVALUATION</li>
</ul>
Class ClientCrudPage:
class ClientCrudPage extends BasePage
{
public $route = 'clients/create';
public function submit(array $signupData)
{
foreach ($signupData as $field => $value) {
$inputType = $field === 'body' ? 'textarea' : 'input';
$this->actor->fillField($inputType . '[name="Clients[' . $field . ']"]', $value);
}
$this->actor->click('schedule_pending');
}
}
How I can perform click on dropdown links?
Yii2 module does not support javascript, so clicking on <a href="#"> is rather pointless.
But if you insist, you can click it with $I->click("#schedule_pending") or
$I->click('SAVE & PENDING')
Related
I'm working with Bootsrtap 4 and I'm trying to add the class active to my nav-item elements whenever their nav-link href attribute is the same as the current url.
On the html side, I uesd a basic url generator as shown below:
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{{ url('/brands') }}" role="button">Brands</a>
</li>
<!-- ... -->
</ul>
And then I used a jQuery method to compare them with the current url:
$('.navbar-nav .nav-item .nav-link').each( () => {
// If the current path and the link url are the same...
if ($(this).attr('href').indexOf(location.pathname) !== 1) {
// ...then add the class 'active' to 'nav-item', its parent
$(this).parent().addClass('active')
}
})
However, I noticed that $(this).attr('href') was undefined, probably because it's a generated url, and therefore nav-item doesn't get the active class.
EDIT: as an example, for now it's a very basic url, without parameter, which looks like this:
http://domain.example/brands
Does anyone know how to solve this problem? Thanks in advance.
I'd recommend you to go another way. Instead of "activating" the link with jQuery, you could easily do it server-side with Laravel:
<ul class="navbar-nav">
<li class="nav-item">
<a class="{{ Request::is('brands*') ? 'nav-link active' : 'nav-link' }}"
href="{{ url('/brands') }}"
role="button">Brands</a>
</li>
<!-- ... -->
</ul>
Explanation:
Laravel uses the template-engine twig for rendering the HTML server-side. Instead of manipulation the DOM client-side, you can easily add an conditional to check for the current request parameters. Laravel gives you nativeliy the possibility to check the request path even with a wildcard.
Your problem is most likely caused by the difference between using () => {} or function () {}
When you use the arrow syntax the prop this is unbound. Meaning that also $(this) will return an empty jQuery object instead of returning the anchor. Any follow up jQuery chaining will return something empty/undefined.
So, changing .each( () => { to .each(function() { will at least fix your undefined problem.
Information about the arrow syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Okay this is what i do generally do in all my laravel projects when it comes to make sidebar or any link "active" on click :-
<li class="nav-item {{ in_array(Route::currentRouteName(),[
'admin.dashboard',
'admin.updates',
])? 'active show' : ''}}">
<i class="typcn typcn-clipboard"></i>Dashboard
<nav class="nav-sub">
Home
</nav>
</li>
Now notice this {{ BladeHelper::sideBar_link_isActive('admin.dashboard') }}
I created dynamic helper function to get the current url and return "active" class
Path : app\Helpers\BladePageHelper
<?php
namespace App\Helpers;
use Route;
class BladePageHelper
{
public static function sideBar_link_isActive($selectedLink){
$currentRouteName = Route::currentRouteName();
if($selectedLink === $currentRouteName){
return 'active';
}else{
return '';
}
}
}
I'm using route name here like
Route::("/","MyController#mymethod")->name("myname")
You can do this with url too.
I hope this helps.
Happy Coding
I have an Angular5 application with a bootstrap tab control. I set the href of a tab to # if the property modelChanged is true, otherwise I set it to #tab1 (or #tab2):
<ul class="nav nav-tabs">
<li class="active">
<a (click)="changeTab()" [attr.href]="modelChanged ? '#':'#tab1'" data-toggle="tab">Tab 1</a>
</li>
<li>
<a (click)="changeTab()" [attr.href]="modelChanged ? '#':'#tab2'" data-toggle="tab">Tab 2</a>
</li>
</ul>
So basically I am able to change the tab if modelChanged is set to false, othwerise not.
Now I wan't to use a function called changeTab() where I change the modelChanged property to false and would expect that the tab change from 1 to 2 but it doesn't until I click the tab again:
changeTab() {
modelChanged = false;
}
Anyone knows a solution for that?
Sorry that I don't have a working plunker but I think some of you will be able to answer my question anyway.
2 ways to do the same
1) in your click specify modelChanged = !modelChanged,
[click]="modelChanged = !modelChanged"
2) [click]="modelChanged = changeTab()"
and in your controller specify the changeTab function like this
function changeTab(){
//do something
return false;
}
I want the tab to be set to active once I click on that tab (action). However, the issue I am experiencing is that the "Dashboard" tab is always set to active
<div class="row top-buffer">
<ul class="nav nav-tabs">
<li class="active">#Html.ActionLink("Dashboard", "Index")</li>
<li>#Html.ActionLink("Users", "Users")</li>
<li>#Html.ActionLink("Investigator Groups", "Groups")</li>
<li>#Html.ActionLink("Assign Games", "AssignGames")</li>
<li>#Html.ActionLink("Reports", "Reports")</li>
</ul>
</div>
Edit:
I tried doing the following, which now allows the tabs to be set to active, but no longer redirects to the action.
<li class="active" data-toggle="tab">#Html.ActionLink("Dashboard", "Index")</li>
<li data-toggle="tab">#Html.ActionLink("Users", "Users")</li>
follow this tutorial Setting the active menu item in a MVC C# Bootstrap application
by adding an extension method
public static class HtmlHelpers
{
public static string IsActive(this HtmlHelper htmlHelper, string action, string controller)
{
var routeData = htmlHelper.ViewContext.RouteData;
var routeAction = routeData.Values["action"].ToString();
var routeController = routeData.Values["controller"].ToString();
var returnActive = (controller == routeController && action == routeAction);
return returnActive ? "active" : "";
}
}
and then use it
<li class="#Html.IsActive("Index", "Dashboard")">#Html.ActionLink("Dashboard", "Index")</li>
<li class="#Html.IsActive("Users", "Users")">#Html.ActionLink("Users", "Users")</li>
I found a Grails framework for generating Breadcrumbs here. It does generate breadcrumbs based on a static definition in a breadcrumbs.xml file where it defines the hierarchies of the crumbs:
<map>
<nav id="homeCrumb" matchController="samplePages" matchAction="homeBreadCrumbPage">
<!-- levels navigation -->
<nav id="itemsLevel1Crumb" matchController="samplePages" matchAction="level1BreadCrumbPage">
<nav id="itemsLevel2Crumb" matchController="samplePages" matchAction="level2BreadCrumbPage">
<nav id="itemsLevel3Crumb" matchController="samplePages" matchAction="level3BreadCrumbPage">
<nav id="showItemCrumb" matchController="samplePages" matchAction="itemDetailsBreadCrumbPage"/>
</nav>
</nav>
</nav>
<nav id="simple1Crumb" matchController="samplePages" matchAction="simpleBreadCrumb"/>
<nav id="simple2Crumb" matchController="samplePages" matchAction="simpleBreadCrumbWithAttr"/>
<!-- levels navigation -->
</nav>
</map>
This file is evaluated and printed by a taglib:
class BreadCrumbTagLib {
static def log = LogFactory.getLog("grails.app.breadCrumbTag")
def breadCrumb = { attrs , body ->
def manager = BreadCrumbManager.getInstance()
def uri = request.getRequestURI()
def context = request.getContextPath()
def controller = params.controller
def action = params.action
def attrTitle = attrs.title
def attrLink = attrs.link
// if controller and action are missing from params try to get them from request url
if (!controller && !action && uri && context && uri.indexOf(context) != -1) {
def uriParams = uri.substring(uri.indexOf(context) + (context.length() + 1), uri.length())
def uriArray = uriParams.split('/')
if (uriArray.size() >= 2 ) {
controller = uriArray[0]
action = uriArray[1]
}
}
def crumbs = manager.getBreadCrumbs(controller, action)
if (crumbs) {
out << '<div class="breadcrumb"><ul>'
def size = crumbs.size()
crumbs.eachWithIndex { crumb, index ->
out << '<li>'
// override title and link of breadcrumb on current page (i.e. last bread crumb in hierarchy)
// if name, link attributes are supplied
if (index == size - 1) {
if (attrTitle)
crumb.title = attrTitle
if (attrLink)
crumb.link = attrLink
}
// set title to undefined if not found, associated
// renderer if present can overwrite it
if (!crumb.title)
crumb.title = "undefined"
if (crumb.title && crumb.title.size() > 40)
crumb.title = crumb.title.substring(0, 40) + "..."
if (crumb.viewController && crumb.viewAction) {
def content = g.include(controller:crumb.viewController, action:crumb.viewAction, breadcrumb:crumb, params:params)
out << content
} else if (crumb.viewTemplate) {
def content = g.include(view:crumb.viewTemplate, breadcrumb:crumb, params: params)
out << content
} else if (crumb.linkToController && crumb.linkToAction && (size - 1 > index)){
out << "${crumb.title}"
// if crumb has a link and its not the last vread crumb then show link else
// just show the text
} else if (crumb.link && (size - 1 > index)){
out << "${crumb.title}"
} else {
out << "${crumb.title}"
}
out << "</li>"
// do not print for last bread crumb
if (size - 1 > index)
out << "<li>ยป</li>"
}
out << "</ul></div>"
}
}
}
Problem: When I have a structure where I need some params which are not fix.
Example: I am in the third level of navigation lets say
A1 / A2 / A3
In my case A2 should open a page like user/show/1234 where 1234 is the id of the user to show. The problem is that I cannot add 1234 hard coded in the breadcrumbs.xml file because this id changes depending on which user you want to show.
How can I handle this when an intermediate breadcrumbs link needs dynamic parameters?
After thinking about it some more, I realized it may be better not to use the HttpSession. If you use a session-scoped service instead it will be easier to unit test the breadcrumb code.
First, create a session-scoped service to maintain the user's navigation history.
class NavigationHistoryService {
static transactional = false
static scope = "session"
def history = [:]
public List push(String controller, String action, Map params) {
def crumb = [
action: action,
params: params]
history.controller = crumb
return history
}
In your controllers inject the service and use it to keep track of where the user has been. Then add the history as part of what's returned by the action's model:
class CompanyController {
def navigationHistoryService
def show() {
navigationHistoryService.push('company', 'show', params)
...
[crumbs: navigationHistoryService.history]
}
}
Finally, use the history in your GSP to render the crumbs.
<ol class="breadcrumb">
<li><g:link controller="company" action="${crumbs.company.action}" params="${crumbs.company.params}">SOMETHING</a></li>
</ol>
It looks like your breadcrumbs are in the format CONTROLLER/ACTION/ID. If that's so, the information you need is already available in your GSP via the webRequest property. Here's an example using Twitter Bootstrap breadcrumbs:
<ol class="breadcrumb">
<li>${webRequest.controllerName}</li>
<li>${webRequest.actionName}</li>
<li class="active">${webRequest.id}</li>
</ol>
You'd still have to set up the hrefs to something meaningful. A more robust approach would be something like this...
<g:set var="crumbs" value="${[webRequest.controllerName, webRequest.actionName, webRequest.id].findAll { it != null }}.collect { [label: it, active: false] }" />
<% crumbs.last().active = true %>
<ol class="breadcrumb">
<g:each in="${crumbs}">
<li class="${it.active ? 'active' : ''}">${it.label}</li>
</g:each>
</ol>
Embedding Groovy code into GSP via the <% %> tags is not recommended, but something like this could be done in a TagLib. This approach can handle breadcrumbs of 1-3 parts in length. It adjusts according to the current URI.
use simple by blade view
<ul class="breadcrumb" style="padding-right: 20px">
<li> <i class="fa fa-home"></i> <a class="active" href="{{url('/')}}">Home</a>
{{--<i class="fa fa-angle-right"></i>--}}
</li> <?php $link = url('/') ; ?>
#for($i = 1; $i <= count(Request::segments()); $i++)
<li>
#if($i < count(Request::segments()) & $i > 0)
<?php $link .= "/" . Request::segment($i); ?>
<a class="active" href="<?= $link ?>">{{Request::segment($i)}}</a>
{{--{!!'<i class="fa fa-angle-right"></i>'!!}--}}
#else {{Request::segment($i)}}
#endif
</li>
#endfor
</ul>
I have some tabs at the top of a web page: home, features, contact, etc.
I need the category I am currently on to be marked as .
How can I appropriately code my _Layout.cshtml page with razor syntax so that I don't have to manually mark each page's appropriate tab as class="current" ?
<li class="current">#Html.ActionLink("Home", "Index", "Home")
<li>#Html.ActionLink("Blog", "Blog", "Home")
<li>#Html.ActionLink("Portfolio", "Portfolio", "Home")
Example way you could do it.
#helper BuildLink(string name, string action, string controller)
{
var url = Url.Action(action, controller);
bool isActive = Request.Url.AbsolutePath.Equals(url, StringComparison.InvariantCultureIgnoreCase);
<li class="#(isActive ? "current" : String.Empty)">#name</li>
}
#BuildLink("Home", "Index", "Home")
#BuildLink("Blog", "Blog", "Home")
#BuildLink("Portfolio", "Portfolio", "Home")
you can set on each controller ViewData["Home"] = "activeTab" class, and use that information in the view.
This will make the tab active if the value of that viewData dictionary is taken.
Is simple and very clean.
Inside controller set viewdata like this
ViewData["SomeTab"] = "activeTab";
return View("Index");
View side:
<li class="<# ((string)ViewData["SomeTab"] ?? "") >"><#Html.ActionLink("SomeTab", "Index", "Home")></li>
<li class="<# ((string)ViewData["MyPage"] ?? "") %>"><#Html.ActionLink("MyPage", "MyPage", "")></li>