Knockout foreach binding unordered list - html

First off, Merry Christmas!
Hopefully no one else is working on xmas day unless they're knockout experts and really feel the urge to help me out ;-)
I'm using the fabulous jQuery Column Navigation Plugin to show data to my users in a multi column fashion. It worked fine in my static testing, but now implementing it into production code I've hit something that hopefully isn't too difficult to sort out.
It requires a div inside a ul element to allow for scrolling when the list gets to big. The problem here is that the foreach I'm using to create the columns wraps each child element in a div and not the entire child collection.
For example:
I should be producing HTML that looks like this
<div id="myTree">
<ul>
<div> <!-- required to allow scrolling within each column -->
<li>
<a>Homepage</a>
<ul>
<div>
<li><a>Contact</a></li>
<li><a>Terms & Conditions</a></li>
<li><a>Privacy information</a></li>
</div>
</ul>
</li>
<li>
<a>Contents</a>
<ul>
<div>
<li><a>Page 1</a></li>
<li>
<a>Page 2</a>
<ul>
<div>
<li>Page 2.1</li>
<li>Page 2.2</li>
</div>
</ul>
</li>
<li><a>Page 3</a></li>
</div>
</ul>
</li>
</div>
</ul>
but using this knockout code
<div id="whatever" style="width: 100%">
<ul data-bind="foreach: { data: Column1 }">
<div>
<li><a data-bind="text: Name"></a>
<ul data-bind="foreach: { data: Column2 }">
<div>
<li><a data-bind="text: Name"></a>
<ul data-bind="foreach: { data: Column3 }">
<div>
<li><a data-bind="text: Name, attr: { 'href': Url }"></a></li>
</div>
</ul>
</li>
</div>
</ul>
</li>
</div>
</ul>
I end up with HTML that looks like
<div id="myTree">
<ul>
<div> <!-- required to allow scrolling within each column -->
<li>
<a>Homepage</a>
<ul>
<div>
<li><a>Contact</a></li>
</div>
<div>
<li><a>Terms & Conditions</a></li>
</div>
<div>
<li><a>Privacy information</a></li>
</div>
</ul>
</li>
<li>
<a>Contents</a>
<ul>
<div>
<div>
<li><a>Page 1</a></li>
</div>
<li>
<a>Page 2</a>
<ul>
<div>
<li>Page 2.1</li>
</div>
<div>
<li>Page 2.2</li>
</div>
</ul>
</li>
<li><a>Page 3</a></li>
</div>
</ul>
</li>
</div>
</ul>
How can I get the internal DIVs to wrapper ALl the children and not individual child records inside the parent??
Many thanks for any help, and MERRY CHRISTMAS once again.

The first comment is correct... you would just do this to produce your desired HTML output:
<ul>
<div data-bind="foreach: { data: Column3 }">
<li><a data-bind="text: Name, attr: { 'href': Url }"></a></li>
</div>
</ul>
Although having a div directly in a ul isn't exactly valid HTML, so I don't know why you would want to do that anyways.
An alternative is using virtual elements:
<ul>
<div>
<!-- ko foreach: { data: Column3 } -->
<li><a data-bind="text: Name, attr: { 'href': Url }"></a></li>
<!-- /ko -->
</div>
</ul>
There is no (nice) way of getting your desired output without modifying the "script" as you mention in your comment.

Related

How can I add a submenu to the sidenav in Materialize?

How can I add submenu to the following sidenav?
<ul class="sidenav sidenav-fixed" id="nav-mobile" style="width:250px">
<li> Text here</li>
<li>
<div class="divider"></div>
</li>
<li>
<a onclick="load('home')"><i class="material-icons">home</i>Home</a>
</li>
<li><a onclick="load('intro')"><i class="material-icons">apps</i>Content Table</a></li>
</ul>
MaterializeCSS documentation site uses a collapsible inside the sidenav:
https://materializecss.com/collapsible.html
Collapsible is a separate component that also needs initialising:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.collapsible');
var instances = M.Collapsible.init(elems);
});
Working codepen:
https://codepen.io/doughballs/pen/RwPWVqy
The actual markup taken from the Materialize doc site is:
<!-- Start nested content -->
<li>
<ul class="collapsible collapsible-accordion">
<li>
<a class="collapsible-header waves-effect waves-teal" tabindex="0"><i class="material-icons">menu</i>Nested</a>
<div class="collapsible-body">
<ul>
<li>Color</li>
<li>Grid</li>
<li>Helpers</li>
<li>Media</li>
<li>Pulse</li>
<li>Sass</li>
<li>Shadow</li>
<li>Table</li>
<li>Transitions</li>
<li>Typography</li>
</ul>
</div>
</li>
</ul>
</li>
You can do something like below with MaterializeCSS
<div id="slide-out" class="sidenav" style="transform: translateX(0%);">
<ul class="collapsible">
<li class="active">
<div class="collapsible-header">
Group1
</div> <div class="collapsible-body" style="display: block;">
<li>Course 1</li>
<li>Course 2</li>
</div>
</li>
<li class="">
<div class="collapsible-header">
केंद्रीय लोकसेवा आयोग
</div>
<div class="collapsible-body" style="">
</div>
</li>
</ul>
</div>

Picture and bullet points next to eachother within columns as divs

I have been browsing and searching around for sometime now to find a working example of a picture in one column and text with bullet points in the other.
This is my result so far.
As you can see the text doesn't start at the top as I want it to.
<div style="overflow:hidden;position:relative;display:table">
<div style="display:table-cell;background:red">
<img src="http://www.lyricsmode.com/i/bpictures/4795.jpg" />
</div>
<div style="display:table-cell;width:100%;background:grey;">
<p>
Here is some text about how awesome Spongebob squarepants is!
</p>
<ul>
<li>Home
<ul>
<li>Dashboard</li>
</ul>
</li>
<li>Views
<ul>
<li>Tickets</li>
</ul>
</li>
<li>Customers
<ul>
<li>List of Customers</li>
</ul>
</li>
<li>Conditional
<ul>
<li>Admin extension</li>
</ul>
</li>
</ul>
</div>
Link to example in Fiddle
Try this
Fiddle Demo
<div style="overflow:hidden;position:relative;display:inline-flex">
just change the display css to inline-flex
try this.. I think this is what you're looking for.
<div style="float:left; background:red">
<img src="http://www.lyricsmode.com/i/bpictures/4795.jpg" />
</div>
<div style="background:grey; float:left;">
<p>
Here is some text about how awesome Spongebob squarepants is!
</p>
<ul>
<li>Home
<ul>
<li>Dashboard</li>
</ul>
</li>
<li>Views
<ul>
<li>Tickets</li>
</ul>
</li>
<li>Customers
<ul>
<li>List of Customers</li>
</ul>
</li>
<li>Conditional
<ul>
<li>Admin extension</li>
</ul>
</li>
</ul>
</div>
How about you actually use a table if you want the get that effect.
Try this html in the snippet:
<table >
<tr>
<td style="display:table-cell;background:red">
<img src="http://www.lyricsmode.com/i/bpictures/4795.jpg" />
</td>
<td style="display:table-cell;width:100%;background:grey;">
<p>
Here is some text about how awesome Spongebob squarepants is!
</p>
<ul>
<li>Home
<ul>
<li>Dashboard</li>
</ul>
</li>
<li>Views
<ul>
<li>Tickets</li>
</ul>
</li>
<li>Customers
<ul>
<li>List of Customers</li>
</ul>
</li>
<li>Conditional
<ul>
<li>Admin extension</li>
</ul>
</li>
</ul>
</td>
</tr>
</table>
You gonna have to change your divs into table and td respectively and add your td items (img and text containers) into tr.
If you have some constraints about this solution let me know.
ADVICE:
don't use inline styles, your markup gets really messy and it's difficult to make any changes later on.

Proper semantic markup for utility bar, logo and main navigation in header

I am trying to create an appropriate semantic markup for header section of design below.
Please header section of this bootstrap theme (Sorry i couldn't add image due to reputation restriction)
Please see code below
<header role="banner">
Skip to main content
<div class="utility-bar">
<ul>
<li><span>Mail</span>
</li>
<li><span>Number</span>
</li>
</ul>
<ul>
<li><span>Social Link 1</span>
</li>
<li><span>Social Link 2</span>
</li>
<li><span>Social Link 3</span>
</li>
<li><span>Social Link 4</span>
</li>
<li><span>Social Link 5</span>
</li>
</ul>
</div>
<a href="#">
<img src="img/logo.svg">
</a>
<nav role="navigation">
<ul>
<li>
Main 1
<ul>
<li>SubMenu 1
</li>
<li>SubMenu 2
</li>
<li>SubMenu 3
</li>
<li>SubMenu 4
</li>
<li>SubMenu 5
</li>
</ul>
</li>
<li>Main 2</li>
<li>Main 3</li>
<li>Main 4</li>
<li>Main 5</li>
<li>Main 6</li>
</ul>
<button title="Show / Hide menu">
<img src="burger.png" alt="Show / Hide menu">
</button>
</nav>
</header>
From reading articles about semantics in sites like HTML5Doctor and posts in stackoverflow. I have the following doubts.
Where should we place the "utility bar"/ "Top Bar", which contains
the social links and contact details? Should we place it in aside
outside the header tag, as it is tangential content to the site.
Is the trick of using H1 for logo with text-indent, not advised
anymore?
Where should we place the burger icon for responsive view. Some doesn't place it in the markup , but add it using javascript. It is the recommended way. if we place it in markup, where is the appropriate place.

Twitter Bootstrap - Make "scrollspy" trigger a bit sooner

I am using Twitter Bootstrap 3.2.0 and the nifty scrollspy feature in it. It works fine for me. I just have a long menu on the right side, and it is set to be affixed, and it corresponds to a huge amount of text. This functions without an issue with the following code;
Questions
Without data-offset-top="60", it doesn't 'stay put' right. I don't understand why this is.
I would like to make it 'trigger' sooner. Right now, a <div> with the corresponding id has to be almost all the way to the top of the page for the matching menu item to get 'highlighted'. Is it possible to make this a bit quicker, maybe where it will trigger when it is around 200px from the top?
HTML
<div class="row">
<div class="col-lg-9 col-md-9 col-sm-12 col-xs-12">
<!-- all of my page contents here, with appropriate "id" set on each to correspond -->
</div>
<div class="col-lg-3 col-md-3 hidden-sm hidden-xs" data-offset-top="60" data-spy="affix" data-theme-role="sidebar" id="sidebar-menu">
<ul class="nav sidenav">
<li class="active">
alpha
<ul class="nav">
<li>
alpha[1]
</li>
</ul>
</li>
<li>
beta
</li>
<li>
gamma
<ul class="nav">
<li>
gamma[1]
</li>
<li>
gamma[2]
</li>
<li>
gamma[3]
</li>
</ul>
</li>
<li>
delta
<ul class="nav">
<li>
delta[1]
</li>
<li>
delta[2]
</li>
</ul>
</li>
<li>
epsilon
<ul class="nav">
<li>
epsilon[1]
</li>
<li>
epsilon[2]
</li>
</ul>
</li>
<li>
zeta
<ul class="nav">
<li>
zeta[1]
</li>
<li>
zeta[2]
</li>
</ul>
</li>
<li>
eta
<ul class="nav">
<li>
eta[1]
</li>
<li>
eta[2]
</li>
</ul>
</li>
<li>
theta
<ul class="nav">
<li>
theta[1]
</li>
<li>
theta[2]
</li>
</ul>
</li>
</ul>
</div>
</div>
I had similar issues,
1- The data-offset-top kind of tells the affix plugin when to get started....so how far down the user scrolls until it needs to affix the div you have set up.
something that might work better than just a hard coded number, 60, is to set up the affix in javascript, rather than the attributes of the HTML element. and when you set the offset, you can get the exact starting position of the element, and then have the affix only kick in after that location has been scrolled past.
$('#sidebar-menu').affix({ //this sets up the affix plugin
offset: $('#sidebar-menu').position().top //this gets the exact
//location of the div and only starts to affix after that
});
when you use the javascript method, you should take out the
data-offset-top="60" data-spy="affix"
2- The data offset should work, again, maybe try the javascript version
$(document).ready(function() {
$('body').scrollspy({
target: '#sidesummary',
offset: 100
});
});

position my menu dropdown to the right

on my website MInGamez.com i have a line of text named Products i will later change that to Menu , but im having problems with it because i need that and the dropdown menu it has to be to the right with its pre-defined 35px; , so how would i be able to align my dropdown to the right?
JsFiddle
and because i have to add code with a js fiddle i will post my html down below ,
HTML
<!--start menu -->
<div id='cssmenu'>
<ul>
<!-- site logo -->
<li class='active'><a href='index.html'><span><img style="height: 35px;width:75;" src="images/logo_image.png" alt="website logo"/></span></a>
</li>
<!-- end site logo -->
<!-- search form -->
<li class="active"><span>
<div>
<form id="searchform">
<div>
<input type="text" size="30" value="" id="inputString" onkeyup="lookup(this.value);" />
</div>
<div id="suggestions"></div>
</form>
</div>
</span>
</li>
<!-- end search -->
<!-- drop down -->
<li class='has-sub'><span>Products</span>
<ul>
<li class='has-sub'><a href='#'><span>Product 1</span></a>
<ul>
<li><a href='#'><span>Sub Item</span></a>
</li>
<li class='last'><a href='#'><span>Sub Item</span></a>
</li>
</ul>
</li>
<li class='has-sub'><a href='#'><span>Product 2</span></a>
<ul>
<li><a href='#'><span>Sub Item</span></a>
</li>
<li class='last'><a href='#'><span>Sub Item</span></a>
</li>
</ul>
</li>
</ul>
<!-- end drop down -->
</ul>
</div>
<!-- end menu -->
Something like this?
I've added:
#cssmenu ul ul > li:hover > ul {
left: 190px !important;
}
Why don't you quite simply give the outter most div a position: relative; and then give the menu position: absolute; right: 35px; or whatever. That would make sure the menu stays afloat, right aligned, inside the confined boundaries of the outter most div.