Multiple HTML Elements on jQuery UI Tab - jquery-ui

I'm using jQueryUI Tabs and have a requirement to add UI elements to each tab that allow a user to Edit information about the tab, or remove the tab.
The markup I use on the <li> for a given tab looks like this:
<li>
<div style="background-color:Red;"> <-- Red to see what's happening -->
<span>Tab One</span>
<div style="text-align:right; margin-right:3px;">
<div><span id="editTab-1">edit</span></div>
<div><span id="delTab-1">X</span></div>
</div>
</div>
</li>
This renders just as I would hope in IE
______________________________
| Edit|
| Tab One |
|___________________________X__|
but it does not render properly in Chrome or FireFox (the tab is only wide enough for the "Tab One" text, and "Edit" / "X" are mostly "under" the tab (lower Z-Index apparently).
What is a compatible way to achieve my goal?

I'm not sure if this is what you were intending or not, as I haven't tested in IE, but this works in Chrome and FF:
<div id="tabs">
<ul style="cursor:pointer">
<li>
<a href="#tabs-1">
<div style="float: left; margin-right: 20px;">Tab One</div>
<div style="float: right; text-align:right;">
<div id="editTab-1">edit</div>
<div id="delTab-1">X</div>
</div>
</a>
</li>
<li>
<a href="#tabs-2">
<div style="float: left; margin-right: 20px;">Tab Two</div>
<div style="float: right; text-align:right;">
<div id="editTab-2">edit</div>
<div id="delTab-2">X</div>
</div>
</a>
</li>
</ul>
<div id="tabs-1" class="tabPane">Tab One Content</div>
<div id="tabs-2" class="tabPane">Tab Two Content</div>
</div>
See the working jsFiddle
If you want to handle the clicks dynamically, you could use:
var $tabs = $("#tabs").tabs();
$tabs.find("a div[id]").on("click", function() {
var id = $(this).attr("id"),
idTab = parseInt(id.substring(id.length - 1)),
isEdit = id.indexOf("edit") > -1,
isDelete = id.indexOf("del") > -1,
index = $tabs.tabs('option', 'selected');
if (index + 1 === idTab) {
if (isEdit) {
console.log("Edit Tab " + (index+1));
//however you want to edit here
}
if (isDelete) {
console.log("Delete Tab " + (index+1));
$tabs.tabs("remove", index);
}
}
}).css("cursor", "pointer");​
See the working jsFiddle

The problem, I think, stems from the fact that the tab <li> and then the <a> inside are floating elements, as designed in the jQueryUI CSS.
The technical part can best be summed up with this quote (from http://css.maxdesign.com.au/floatutorial/introduction.htm)
If no width is set, the results can be unpredictable. Theoretically, a floated element with an undefined width should shrink to the widest element within it. This could be a word, a sentence or even a single character - and results can vary from browser to browser.
So the red <div> is shrinking to the widest element - the <a>. IE and Firefox/Chrome are simply behaving differently, just their interpretation of the specifications. To be honest, that fact that Firefox and Chrome are similar and IE has had a long history of float bugs I'd side with Mozilla/Google here although can appreciate that IE seems to be behaving nicer in this instance.
You can solve the problem by simply setting a width on the red <div>. However the markup could also be a bit cleaner, for example:
<li style="background-color:red;width:150px">
Tab One
<div id="editTab-1" style="text-align:right;margin-right:3px">edit
<p id="delTab-1">X</p>
</div>
</li>
gives the same result.

Related

Material Components Web - Persistent and Perminent Drawer are Not Displayed as Expected

I am following the Material Components Web docs. As a template of the page I am using the very basic template as detailed in the quick start - My undertsnading is that this template is a "including all" template:
it uses:
node_modules/material-components-web/dist/material-components-web.css
and,
https://unpkg.com/material-components-web#latest/dist/material-components-web.min.js
(complete code below)
Seem like Persistent Drawer and Permanent Drawer are not displayed as expected. Not slidable, not aside to the left, not stretching its height.
Note that the Temporary drawer does work as expected.
What am I missing?
<!DOCTYPE html>
Material Components for the web
<aside class="mdc-persistent-drawer mdc-typography">
<nav class="mdc-persistent-drawer__drawer">
<header class="mdc-persistent-drawer__header">
<div class="mdc-persistent-drawer__header-content">
Header here
</div>
</header>
<nav id="icon-with-text-demo" class="mdc-persistent-drawer__content mdc-list">
<a class="mdc-list-item mdc-persistent-drawer--selected" href="#">
<i class="material-icons mdc-list-item__start-detail" aria-hidden="true">inbox</i>Inbox
</a>
<a class="mdc-list-item" href="#">
<i class="material-icons mdc-list-item__start-detail" aria-hidden="true">star</i>Star
</a>
</nav>
</nav>
</aside>
<h2 class="mdc-typography--display2">Hello, Material Components!</h2>
<div class="mdc-textfield" data-mdc-auto-init="MDCTextfield">
<input type="text" class="mdc-textfield__input" id="demo-input">
<label for="demo-input" class="mdc-textfield__label">Tell us how you feel!</label>
</div>
<script src="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.js"></script>
<script>window.mdc.autoInit();</script>
<script>
let drawer = new mdc.drawer.MDCPersistentDrawer(document.querySelector('.mdc-persistent-drawer'));
drawer.open = true;
</script>
In order to be displayed as expected, meaning: aside to the left, stretching vertically with 100% height, some css style need to be added. Style values can be taken from the demos package: here. Also note the classes added to the body element as detailed in the permanent drawer demo.

Jquery Mobile not displaying data-icons (correctly)

So, I'm adding a popup menu off the header and it works... works quite well actually except for one small thing. For the life of me I can't get it to display the icons the way I want them!
In the first <li> I brute force the data-icon into the <li> and it shows but its not positioned to the left. In the others, I left the data-icon where I'm accustomed to leaving them (where they work correctly everywhere else) and they don't display at all.
Any suggestions?
<div id="header" data-role="header" data-theme="b">
<h1>MyApp</h1>
Menu
<div data-role="popup" id="popupMenu" data-theme="b">
<ul data-role="listview" data-inset="true">
<li data-icon="gear" data-iconpos="left">Settings</li>
<li>GPS</li>
<li>About</li>
</ul>
</div>
</div>
<!-- /header -->
JSFiddle
The data-iconpos attribute not defined for regular list items, works only when the < li> item is inside a navbar widget: http://www.w3schools.com/jquerymobile/jquerymobile_ref_data.asp
Please, take a look to the fiddle I made: https://jsfiddle.net/xbo8npng/1/
I have placed the icons to the left using css:
<div id="header" data-role="header" data-theme="b">
<h1>MyApp</h1>
Menu
<div data-role="popup" id="popupMenu" data-theme="b">
<ul data-role="listview" data-inset="true">
<li class="left" data-icon="gear">Settings</li>
<li class="left">GPS</li>
<li class="left">About</li>
</ul>
</div>
</div>
and the styles:
.left a{
padding-left: 2.5em !important;
padding-right: 1em !important;
}
.left a:after{
left: 2px;
right: auto;
}
I hope this helps you!

How do I drag to an empty connected list using angular-ui?

As a follow-up to How do I move from one ui-sortable to another in Angular?
If I have 2 connected lists, and one of the lists is empty, how do I actually drop onto it? Again looking at http://minitrello.meteor.com he has a placeholder created even in an empty list. How do I replicate that so that when
list1 = [];
list2 = ['A','B','C']
I can actually drop onto list1? Fiddle at http://jsfiddle.net/hKYWr/894/
EDIT: Cleaner fiddle at http://jsfiddle.net/hKYWr/897/
If your List is empty then also you need to create an empty Li
I have added one List in each List
<li ng-show="list1.length==0"> </li>
<li ng-show="list2.length==0"> </li>
Below is the working Demo
Demo
Template code:
<div ng:controller="controller">
<div style="float:left; margin:5px;">
<h3>list1</h3>
<ul ui:sortable="sortableOptions" class="connectedList" ng:model="list1">
<li ng:repeat="item in list1" class="item">{{item}}</li>
<li ng-show="list1.length==0"> </li>
</ul>
</div>
<div style="float:left;margin:5px;">
<h3>list2<h3>
<ul ui:sortable="sortableOptions" class="connectedList" ng:model="list2">
<li ng:repeat="item in list2" class="item">{{item}}</li>
<li ng-show="list2.length==0"> </li>
</ul>
</div>
<div style="clear:both;"></div>
<hr />
<div>list1: {{list1 | json}}</div>
<div>list2: {{list2 | json}}</div>
</div>
It's a similarly 'hacky' solution to the accepted answer but you can also add some padding(top/bottom) on to your lists to handle this problem.
e.g.
<ul style="padding-top:20px; padding-bottom: 20px;">
See fiddle here for evidence!
This suggests the problem is that an empty list provides no 'target' to drop on.
Setting a min-height works just as well too.
A solution i used was just to set min-height to the connected list
.connectedList {
min-height: 10px
}
http://jsfiddle.net/hKYWr/2367/

jQuery Mobile back button not showing up when linked to drop down UL

So I have one page that works perfectly fine, I am actually creating the links programatically and any link to get to the page with the working back button from is fine - I can see the back button no problem, but then I have a drop down that is just UL full of links and the two pages I link to from there don't show the back button.
Here is the top of the working page.
<div data-role="page" id="detailsPage" data-add-back-btn="true">
<div data-role="header">
<h1 id="title"></h1>
</div>
There here is the one that doesn't work.
<div data-role="page" id="calendarPage" data-add-back-btn="true">
<div data-role="header">
<h1 id="title">Calendar</h1>
</div>
Here is the UL that has the link to the calendar page that won't show a back button.
<div class="ui-block-b">
<ul data-role="menu" id="optionsDropDown">
<li>
<span data-role="button" data-icon="arrow-d" data-iconpos="right" data-iconpos="left">Calendar</span>
<ul data-role="listview" data-inset="true">
<li data-icon="false">
Thursday
</li>
<li data-icon="false">
Friday
</li>
<li data-icon="false">
List All Sessions
</li>
<li data-icon="calendar">
<a href="#calendarPage" >Calendar</a>
</li>
<li data-icon="gear">
<a href="#settingsPage" >Settings</a>
</li>
</ul>
</li>
</ul>
</div>
The back button on detailsPage always works, the back button on calendarPage never shows up. I have trolled the site but people seems to have issues when they mess with changeHash which I haven't touched.
Could I be screwing something up in the JS? I can't see anything obvious, I could post my whole JS file but I don't even touch these pages from there or mess with the links or anything. I thought maybe because the display is set to none on that list I just showed you above that it wouldn't work but then I tried changing that - it make no difference if you can see it initially or not. I don't get any errors in the console. I am so stumped at the moment. I hope someone can help.
Thanks
Not sure if it is a possible cause but according to the docs, data-role="button" is only valid on <a>, <button> and <input> type elements. I don't see <span> listed there and wonder if that is affecting your navigation?
There is also no valid data-role="menu" attribute listed.
What version of jQuery Mobile are you using? Are you relying on any third party widgets?

Checking is visible returns false every time

I am having issues determining if a particular dom object is visible or not. I have the following code outputting to the console and it always returns false even though I can see the element on the screen.
console.log(itemElement.innerText +" is visible: " + $(itemElement.id).is(':visible'));
The context that I am testing is to see whether a list item in a jQuery Accordion object is visible or not. I am iterating through all the list elements (including sub list elements) and performing this check. Always the check returns false. I have googled everywhere for an answer but couldn't find one.
Here is the html to show what the layout looks like. I have edited it a bit to keep it reasonable but you should get a good idea of how it is set up.
<div id="collection_form">
<div id="element_container">
<ul class="element_list element_group ui-sortable">
<li id="de_1" class="element_group_parent eg-collapsed element_group_leaf">
stuff in here is same as below
</li>
<li id="de_29" class="element_group_parent eg-collapsed element_group_leaf">
<div>
<span>Room Booking</span>
<span class="element_type"> - Group</span>
<span class="remove_element">remove</span>
<div style="clear:both"></div>
</div>
<ul class="element_group">
<li id="de_30" class="element_config_form element_group_leaf">
<div>
<span>Room Number</span>
<span class="element_type"> - Text</span>
<span class="remove_element">remove</span>
<div style="clear:both"></div>
</div>
</li>
</ul>
</li>
<li id="de_31" class="element_group_parent eg-collapsed element_group_leaf">
<div></div>
<ul class="element_group">
<li id="de_32" class="element_config_form element_group_leaf">
<div> more stuff </div>
</li>
</ul>
</li>
</ul>
</div>
</div>
What is it that I am doing wrong?
Try this :
$(itemElement).is(':visible'); // this works if itemElement is a DOM element, or even if itemElement is a jQuery wrapped DOM elemenent
i suspect your itemElement.id is undefined
But if itemElement.id is correctly defined (as the id of your itemElement, in this case means that itemElement is a DOM element) you can do both these :
$("#"+itemElement.id).is(':visible');
or even better :
$(itemElement).is(':visible');

Resources