Extending LeftAndMain and Add Tabs - tabs

I'm taking a long shot at trying to get tabs functional in my LeftAndMain Extension.
I couldn't find any documentation on how one would achieve this so I was just looking at the "Settings" tab setup in the Admin panel.
As I said, long shot :P
This makes them appear beautifully as tabs, however the toggle-between functionality isn't working due to a JS error:
jquery.js:551 Uncaught Error: jQuery UI Tabs: Mismatching fragment identifier.
/mymodule/templates/MyAdmin_Content.ss
<div class="cms-content center $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content">
<div class="cms-content-header north">
<div class="cms-content-header-info">
<% include CMSBreadcrumbs %>
</div>
<div class="cms-content-header-tabs cms-tabset-nav-primary ss-ui-tabs-nav ss-tabset">
<ul class="cms-tabset-nav-primary ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"
role="tablist">
<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0"
aria-controls="Root_Servers" aria-labelledby="ui-id-1" aria-selected="true"><a
href="#Root_Servers" class="ui-tabs-anchor" role="presentation"
tabindex="-1">Main</a></li>
<li class="ui-state-default ui-corner-top" role="tab" tabindex="-1" aria-controls="Root_Settings"
aria-labelledby="ui-id-2" aria-selected="false"><a
href="#Root_Settings" class="ui-tabs-anchor"
role="presentation" tabindex="-1" id="ui-id-2">Access</a></li>
</ul>
</div>
</div>
<div class="cms-content-fields cms-panel-padded center">
<fieldset>
<div id="Root" class="field CompositeField tabset">
<div id="Root_Servers" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom"
aria-labelledby="ui-id-1" role="tabpanel" aria-expanded="true" aria-hidden="false"
style="display: none;">
TAB 1
</div>
<div id="Root_Settings" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom"
aria-labelledby="ui-id-2" role="tabpanel" aria-expanded="false" aria-hidden="true"
style="display: block;">
TAB 2
</div>
</div>
</fieldset>
</div>
<div class="cms-content-actions cms-content-controls south text-center">
Footer
</div>
</div>
I'm aware that majority of the tabs classes are added by jQuery UI however I'm yet to discover how these tabs are instantiated for me to trim off what isn't initially required.
I was hoping to simply access updateCMSFields() but method does not exist on LeftAndMain
Hoping for a pointer, thanks

Old question but I got stuck on this as well.
The tabs and the tabbed content need to be in the same "tabs" container. In the case of Silverstripe that container is .cms-tabset so moving that class up to the .cms-content div at the top accomplishes that. Here's the modified code from the question (trimmed some of the fat to make it more legible):
<!-- Add .cms-tabset class here -->
<div class="cms-content center cms-tabset $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content" data-ignore-tab-state="true">
<!-- Start north -->
<div class="cms-content-header north">
<div class="cms-content-header-info">
<% include CMSBreadcrumbs %>
</div>
<div class="cms-content-header-tabs cms-tabset-nav-primary ss-ui-tabs-nav">
<ul class="cms-tabset-nav-primary">
<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active">
<a href="#Root_Servers" class="ui-tabs-anchor" role="presentation" tabindex="-1">
Testing
</a>
</li>
<li class="ui-state-default ui-corner-top">
<a href="#Root_Settings" class="ui-tabs-anchor" role="presentation" tabindex="-1">
Settings
</a>
</li>
</ul>
</div>
<!-- End north -->
</div>
<!-- Start center -->
<div class="cms-content-fields cms-panel-padded center">
<div id="Root" class="field CompositeField tabset">
<div id="Root_Servers" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom">
TAB 1 Content
</div>
<div id="Root_Settings" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom">
TAB 2 Content
</div>
</div>
<!-- End center -->
</div>

Related

Div should take screen height minus (height of header+footer and other div)

My html page contains one header, two divs (say div1 and div2) and one footer. I have given height to header, one div and footer. Now, I want the other div to take vertical height of any screen(phones, tablets, desktop. larger desktop etc.) minus the combined height of header, div1 and footer i.e, height of div2 = height of screen-(height of header+height of div1+height of footer) with scrollbar. Inside div 2 I am showing cards with some information just like chat application(whatsapp) which is appending dynamically using JavaScript. In third div, I am appending dynamically created chats to the Div with id "chat-body".
I am trying calc(100vh - (combined height of header+div1+footer)). It is coming fine for desktop but for smaller screens scroll bar for third div is going inside footer.
<header class="topBar">
<ul class="nav nav-tabs row" id="myTab" role="tablist">
<li class="nav-item col">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true" style="padding-top: 20px; font-size: 14px; cursor: pointer;" onclick="chat()">Chat</a>
</li>
<li class="nav-item col">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false" style="padding-top: 20px; font-size: 14px; cursor: pointer;" onclick="ticketStatus()">Incident</a>
</li>
<li class="nav-item col">
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false" style="padding-top: 20px; font-size: 14px; cursor: pointer;" onclick="ticketStatus()">Service Request</a>
</li>
</ul>
</header>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
<div class="container">
<div class="row h-100">
<div id="topButtons" class="card-body" style="padding-bottom: 0;"></div>
<div id="chatBody" class="card-body anyClass" onscroll="myFunction()">
<p class="WC_message_fl"><img class="con_im" src="images\chatrobo.png"></p>
<p class="WC_message_fl sahlaIntro"> Type your Questions & Start chatting with Sahla bot.</p>
</br>
</br>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
</br>
</br>
<p class="WC_message_fl" id='msg_table'></p>
<div class="container" style="overflow-x:hidden;overflow-y:auto;height:84vh;">
<div class="row" id="table"></div>
</div>
</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
</br>
</br>
<p class="WC_message_fl" id='msg_sr_table'></p>
<div class="container" style="overflow-x:hidden;overflow-y:auto;height:84vh;">
<div class="row" id="sr_table"></div>
</div>
</div>
</div>
<footer class="footr" id="footerChtbt">
<div id="myBtn" onclick="topFunction()"><img title="Go to top" src="images/GOTOTOP.png" style="width:65px;height:65px;"></div>
<div class="input-group" style="width: 90% !important;">
<input id="query" type="text" class="dir-auto form-control" placeholder="Ask Sahla bot..." onkeyup="pressedkey(event)" style="outline:0;box-shadow:none;border-width:0px;font-size:14px;" required>
<div class="input-group-append" style="margin-left: 1%;">
<img src="images/send_icon.svg" name="submitbtn" id="submitbtn" onClick="sendbtn()" style="cursor: pointer;">
</div>
</div>
</footer>
Try once using 100% instead 100vh
eg: height: calc(100% - number)

bootstrap dropdown inside ng repeat element hidden by overflow auto

I've tried turning overflow x off, changing the z-index, etc. but nothing seems to work for this antichrist code
nothing can go outside the box
The smaller boxes are generated by ngrepeat so I think something is not loading in order. Please help
Here's the jsfiddle for it but it's just the html code
https://jsfiddle.net/5dbtb4h5/
<div class="row containerrow">
<!-- left column for upcoming -->
<div class="col-sm-6 col-md-3 upcoming" style="background-color:yellow;">
<p id="upcomingtitle">Upcoming</p>
<div class="form-group updropdown">
<select class="form-control" id="xyz">
<option>All</option>
<option>Checked In</option>
<option>Not Checked In</option>
</select>
</div>
<div class="upcominglist">
<div class="upcomingtiles" ngdragclone="" ng-drag="true" ng-drag-success="$ctrl.testdrop()" ng-drag-data="appointment" ng-repeat="appointment in $ctrl.appointments" ng-if="appointment.StatusID == 0 || appointment.StatusID == 1">
{{$ctrl.formatPatientInfo(appointment.DOB, appointment.DateTime, appointment.Gender, appointment.AppointmentTypeID)}}
<div class="statusflag" ng-class="{'bluestatus' : appointment.StatusID > 0, 'emptystatus' : appointment.StatusID == 0}"></div>
<div class="uptext"> <span class="boldtitle">{{appointment.FirstName}} {{appointment.LastName}}, {{$ctrl.year - $ctrl.patientYear}}, {{$ctrl.gender}}</span><br/> {{$ctrl.signInTime}} {{$ctrl.patientAppointmentType}} <br/> {{appointment.Complaint}}
</div>
<div class="dropdown dropdown1">
<img class="dropdownarrow dropdown-toggle" id="menu1" data-toggle="dropdown" src="/images/transarrow.png">
<ul class="dropdown-menu dropdown-menu1 dropdown-menu-right">
<li role="presentation"><a ng-click="$ctrl.updateAppointmentStatus(appointment, 0)">Not Checked In</a></li>
<li class="divider"></li>
<li role="presentation"><a ng-click="$ctrl.updateAppointmentStatus(appointment, 1)">Checked In</a></li>
<li class="divider"></li>
<li role="presentation"><a ng-click="$ctrl.onClickStoreAppointment(appointment); $ctrl.on()">Move to Room</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- end right column -->
</div>
<!-- end container row -->

Initial Page Load Shows contents of both tabs

On initial load, the content from both tabs show on the webpage, once the tab is clicked for the first time they begin to work as expected.
Any ideas on why this is happening?
Here is my html
<div id="userFunctions" style="display: none;" >
<h2 id="welcome"></h2>
<button id="btnChangeUser" class="btn btn-primary" style="display: none;">Change User</button>
<br>
<hr>
<ul class="nav nav-tabs">
<li class="active"><a id="showSubs" data-toggle="tab" href="#subscriptionManagement">Subscription Portal</a></li>
<li><a id="showLocation" data-toggle="tab" href="#locationManagement">Location Management</a></li>
</ul>
<div class = tab-content>
<div id="subscriptionManagement" class="tab-pane fade in active">
<hr>
<section id="sendSubRequest">
<h4>Request Subscription</h4>
<div class="input-group">
<input type="text" id="subUserName" class="form-control "></input>
<span class="input-group-btn">
<button id="btnSubUser" class="btn btn-primary">Subscribe</button>
</span>
</div>
</section>
<br>
<section id="ReviewSubRequests">
<h4>Incoming Request(s)</h4>
<ul id='subscriptionsList'>
</ul>
</section>
</div>
<div id="locationManagement" class="tab-pane fade in active">
<hr>
<section id="cityDetails">
<section id="map">
</section>
<br>
<section>
<button id="btncheckInLocation" class="btn btn-primary">Check-In User location</button>
</section>
</section>
<section id="friendsList">
<h4>Subscribed Friends</h4>
<ul id='subscribedUsers'>
</ul>
</section>
</div>
</div>
</div>
Both your tabs (#subscriptionManagement and #locationManagement) have the active class, meaning they are both active by default. This class should be getting added on navigation, indicating that the content should be shown. You simply need to remove this class from the tab which you don't want to show on initial load:
Change:
<div id="locationManagement" class="tab-pane fade in active">
To:
<div id="locationManagement" class="tab-pane fade in">
Hope this helps! :)

Need help in aligning items together in Bootstrap grid layout

I am trying to align 7 items in a grid layout so that each element is fixed in it's place currently I am able to achieve like below screenshot. Here is the plunker for the same code (but some how it does not look good on plunker).
The problem in my current state is minutes is wrapped to 2nd line. Also how can I utilise extra space from Agent: label area and Reset button area so that the space gets utilised?
Code
<div class="row">
<div class="col-md-1" style="padding-right:0px; padding-left:0px; margin-top:5px">
<div ng-show="!loadinga">
<b>Agent: </b>
</div>
</div>
<div class="col-md-2" style="padding-left:0px;">
<div class="dropdown " ng-show="!loadinga">
<button class="btn btn-default btn-block dropdown-toggle whiteDropdown" ng-disabled="loading" style="background-color: #fff; border-color: #C3C3C3" type="button" id="dropdownMenu1" aria-expanded="true">
{{dropDownTitle}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scroll-menu nav" role="menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="agent in agentListData">
<a role="menuitem" href="#" ng-click="">{{agent}}</a>
</li>
</ul>
</div>
</div>
<div class="col-md-2" style="padding-left:0px;">
<div class="dropdown " ng-show="!loadinga">
<button class="btn btn-default btn-block dropdown-toggle whiteDropdown" ng-disabled="loading" type="button" id="dropdownMenu2" aria-expanded="true">
{{dropDownAllTaskStatusTitle}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scroll-menu nav" role="menu" aria-labelledby="dropdownMenu2">
<li ng-repeat="task in taskStatusListData">
<a role="menuitem" href="#" ng-click="">{{task.title}}</a>
</li>
</ul>
</div>
</div>
<div class="col-md-2" style="padding-right: 0px; padding-left:0px;">
<div ng-show="!loadinga">
<input id="autoComplete" ng-model="selected" typeahead="task.name for task in taskList | filter:$viewValue | limitTo:20" class="form-control" typeahead-on-select="" placeholder="Search Tasks" typeahead-focus-first="true" ng-disabled="loading" type="text" ng-blur="" />
</div>
</div>
<div class="col-md-2 divGridText" ng-show="!loadinga" style="padding-right: 0px; padding-left:0px; margin-right:0px" align="right">
<input ng-model="isChecked" ng-click="checkboxClicked(isChecked)" ng-disabled="loading" type="checkbox" />
<label for="excludeMinutesStep" style="font-weight:normal">Exclude tasks running < </label>
<input id="excludeMinutesStep" min="0" max="10" ng-disabled="!isChecked || loading" ng-model="excludeValue" ng-change="" size="2" style="width:40px" type="number" /> minutes
</div>
<div class="col-md-2 divGridText" ng-show="!loadinga" style="padding-right: 0px; padding-left:0px;" align="centr">
<input id="datalabels" ng-model="isLabelShowChecked" ng-click="" ng-disabled="loading" type="checkbox" />
<label for="datalabels" style="font-weight:normal;">Show Task Labels</label>
</div>
<div class="col-md-1 divGridImage" ng-show="!loadinga" align="center" style="padding-right: 0px; padding-left:0px;">
<button style="margin-left:3px" class="btn btn-custom" ng-click="">Reset</button>
</div>
</div>
Update
Or is there a way to keep Agent: label and drop down in same line without giving separate div with col-md-1 class to label?
Need something like below screenshot
Right so my attempts at solving this are below, I'm not going to give you the same body of text because you can review that in the previous post.
Here is the completed grid with all the parts you have requested, it's also laid out better. (Its not really device friendly as requested).
I updated the example to work correctly
Code:
<head>
<script data-require="jquery#*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script data-require="angular.js#1.x" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script data-require="ui-bootstrap#*" data-semver="0.13.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.min.js"></script>
<link data-require="bootstrap-css#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="MainController">
<div class="container-fluid">
<div class="row">
<div class="hidden-xs col-sm-2 sidebar">
<div class="sidebar-nav" style="height:100% !important;min-height: 100% !important">
<div class="navbar navbar-custom" role="navigation">
<ul class="nav recommendation-nav">
<li class="active">
<img style="padding-right: 5px" /> Side bar
</li>
<li >
<img style="padding-right: 5px" />Side bar
</li>
<li >
<img style="padding-right: 5px" />Side bar
</li>
<li >
<img style="padding-right: 5px" />Side bar 1
</li>
<li >
<img style="padding-right: 5px" />Side bar 2
</li>
<li >
<img style="padding-right: 5px"/>Side bar 3
</li>
</ul>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-sm-offset-1 report-area">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-sm-2">
<div class="dropdown" ng-show="!loadinga">
<button class="btn btn-default btn-block dropdown-toggle whiteDropdown" ng-disabled="loading" style="background-color: #fff; border-color: #C3C3C3" type="button" id="dropdownMenu1" aria-expanded="true">
{{dropDownTitle}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scroll-menu nav" role="menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="agent in agentListData">
<a role="menuitem" href="#" ng-click="">{{agent}}</a>
</li>
</ul>
</div>
</div>
<div class="col-xs-12 col-sm-2">
<div class="dropdown " ng-show="!loadinga">
<button class="btn btn-default btn-block dropdown-toggle whiteDropdown" ng-disabled="loading" type="button" id="dropdownMenu2" aria-expanded="true">
{{dropDownAllTaskStatusTitle}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scroll-menu nav" role="menu" aria-labelledby="dropdownMenu2">
<li ng-repeat="task in taskStatusListData">
<a role="menuitem" href="#" ng-click="">{{task.title}}</a>
</li>
</ul>
</div>
</div>
<div class="col-xs-12 col-sm-2">
<div ng-show="!loadinga">
<input id="autoComplete" ng-model="selected" typeahead="task.name for task in taskList | filter:$viewValue | limitTo:20" class="form-control" typeahead-on-select="" placeholder="Search Tasks" typeahead-focus-first="true" ng-disabled="loading" type="text"
ng-blur="" />
</div>
</div>
<div class="col-xs-12 col-sm-4 divGridText" ng-show="!loadinga">
<input ng-model="isChecked" ng-click="checkboxClicked(isChecked)" ng-disabled="loading" type="checkbox" />
<label for="excludeMinutesStep" style="font-weight:normal">Exclude tasks running < </label>
<input id="excludeMinutesStep" min="0" max="10" ng-disabled="!isChecked || loading" ng-model="excludeValue" ng-change="" size="2" style="width:40px" type="number" /> minutes
</div>
<div class="col-xs-12 col-sm-1 divGridText" style="width:9.33%" ng-show="!loadinga" >
<input id="datalabels" ng-model="isLabelShowChecked" ng-click="" ng-disabled="loading" type="checkbox" />
<label for="datalabels" style="font-weight:normal;">Task Labels</label>
</div>
<div class="col-xs-1 col-sm-1 divGridImage" ng-show="!loadinga">
<button style="margin-left:3px" class="btn btn-custom" ng-click="">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Preview:
Your parent divs (the columns) should be set to 0 padding and 0 margin, and the childs should have whatever padding/margin you want. This prevents an overflow.
For example, if you have 4 columns (which equal to 25% width each) and even one of them has a left or right padding of like 10px, then the 4th column will be pushed to the next line because they are now exceeding the 100% width.
Bad example:
HTML:
<div class="col-1">
//content
</div>
<div class="col-2">
//content
</div>
CSS:
.col-1, .col-2 { width: 50%; display: inline-block; padding-left: 15px }
The above code will have the second column flow to the next line because of that padding-left of 15px, which you also use in your own code.
Good example:
HTML:
<div class="col-1">
<div class="inner-col-1">
//content
</div>
</div>
<div class="col-2">
<div class="inner-col-2">
//content
</div>
</div>
CSS:
.col-1, .col-2 { width: 50%; display: inline-block }
.inner-col-1, .inner-col-2 { padding: 0 15px }
The above code will ensure that your columns are on the same line, and the inner content can now use whatever padding/margins you want because they won't affect the width of the parents.
If you don't need to use the application on another screen size, you could try to align Agent: to the right of his container and the reset button to the left of the container. You could the set negative margins to the row, that would give you more place for your content.
Otherwise, bootstrap gives you the possibility to subdivise each column into 12 new columns, you could try something like this :
<div class="row">
<div class="col-md-6">
<!-- you can put here the 4 first elements as you like, on a 12 columns layout -->
</div>
<div class="col-md-6">
<!-- you have again a 12 columns layout for the 3 lasts elements -->
</div>
</div>
look at http://getbootstrap.com/examples/grid/ in the section "Two columns with two nested columns" for a visual example
Easy but no very attractive solution
<span>minutes</span>
PS: I am not sure I have fully understood your question

Accessible accordion roles (tab and tablist)

I'm working on an accessible accordion and I'm not quite sure why the following code does not work properly with VoiceOver:
<ul class="accordion" role="tablist">
<li class="accordion__item">
<h3 class="accordion__head" id="tab1" tabindex="0" role="tab" aria-controls="panel1">Headline</h3>
<div class="accordion__content" id="panel1" role="tabpanel" aria-labelledby="tab1" aria-hidden="true">
Content
</div>
</li>
<li class="accordion__item">
<h3 class="accordion__head" id="tab2" tabindex="0" role="tab" aria-controls="panel2">Headline</h3>
<div class="accordion__content" id="panel2" role="tabpanel" aria-labelledby="tab2" aria-hidden="true">
Content
</div>
</li>
VoiceOver always says something like "tab 1 of 1 Heading 1...", although there clearly are two different role="tab" inside my .accordion. So i tried removing each .accordion__item and ended up with something like that:
<div class="accordion" role="tablist">
<h3 class="accordion__head" id="tab1" tabindex="0" role="tab" aria-controls="panel1">Headline 1</h3>
<div class="accordion__content" id="panel1" role="tabpanel" aria-labelledby="tab1" aria-hidden="true">
Content 1
</div>
<h3 class="accordion__head" id="tab2" tabindex="0" role="tab" aria-controls="panel2">Headline 2</h3>
<div class="accordion__content" id="panel2" role="tabpanel" aria-labelledby="tab2" aria-hidden="true">
Content 2
</div>
</div>
While this works (VoiceOver says "tab 1 of 2 ...") I really need the .accordion__item around my actual content for styling. Although there is only very little difference between the two I'm not sure why only the second code really works with Screen Readers. So I'm asking you if there is any way to have both my surrounding .accordion__item and a correct VoiceOver text?
Thanks in advance.
Also I know that there is more than just that to make an accordion accessible, but that is currently the only issue I really don't know why it doesn't work.
What you need to do is set role="presentation" on all the structures that are not one of the tablist specific roles.