in AngleSharp, how can I loop through all list items (included the nested ones) and turn each one into a single list with the parent attributes - anglesharp

in AngleSharp, how can I loop through all list items (included the nested ones) and turn each one into a single list with the parent attributes. I tried code below
var parser = new AngleSharp.Parser.Html.HtmlParser();
var document = parser.Parse(theString);
var listItemsLinq = document.QuerySelectorAll("li");
foreach (var item in listItemsLinq)
{
var p = item.ParentElement.Clone(false);
var newiTem = item.Clone(false);
p.AppendChild(newiTem);
item.ParentElement.ParentElement.AppendChild(p);
item.ParentElement.RemoveChild(item);
Response.Write(document.DocumentElement.OuterHtml);
}
This gives me empty list, the list is created but the item context has not been copied over.
Example list
<ul>
<li>one.</li>
<li>two.</li>
<li>three.</li>
<li>Four:
<ul>
<li>Four-One</li>
<li>Four-Two</li>
<li>Four-Three</li>
</ul>
</li>
<li>Five</li>
<li>Six</li>
</ul>

I am not sure what you mean by "the item context has not been copied over". Why all that cloning if you could simply re-append?
Since you use .Clone(false) the children won't be copied. As such the text children also won't be copied.
Hence starting with your example
<ul>
<li>one.</li>
<li>two.</li>
<li>three.</li>
<li>Four:
<ul>
<li>Four-One</li>
<li>Four-Two</li>
<li>Four-Three</li>
</ul>
</li>
<li>Five</li>
<li>Six</li>
</ul>
We would end up with the following
<ul>
</ul>
<ul>
<li></li>
</ul>
<ul>
<li></li>
</ul>
<ul>
<li></li>
</ul>
<ul>
<li></li>
</ul>
<ul>
<li></li>
</ul>
<ul>
<li></li>
</ul>
The first list is empty, because it is the original list, where we have removed all items.
Solution 1
If you want to consider nested lists, but want them grouped, then our solution may look like (only inner part of the loop):
var parent = item.ParentElement;
var p = parent.Clone(false);
p.AppendChild(item);
parent.ParentElement.AppendChild(p);
The result is
<ul>
</ul>
<ul>
<li>one.</li>
</ul>
<ul>
<li>two.</li>
</ul>
<ul>
<li>three.</li>
</ul>
<ul>
<li>
Four:
<ul>
</ul>
<ul>
<li>Four-One</li>
</ul>
<ul>
<li>Four-Two</li>
</ul>
<ul>
<li>Four-Three</li>
</ul>
</li>
</ul>
<ul>
<li>Five</li>
</ul>
<ul>
<li>Six</li>
</ul>
Solution 2
If you also want to apply this to nested lists then you only need to also loop inside the loop:
var parent = item.ParentElement;
while (parent.ParentElement.LocalName === 'li') {
parent = parent.ParentElement.ParentElement;
}
var p = parent.Clone(false);
p.AppendChild(item);
parent.ParentElement.AppendChild(p);
This results in the flattened tree of lists consisting of a single item.
Hope this helps!

Related

CSS selector in list using class [duplicate]

This question already has answers here:
CSS selector for first element with class
(23 answers)
Closed 3 years ago.
I would like to apply styling to list items in ordered list (specifically to the ::after or ::before), based on the classes of the <li>. The code for these lists looks like the following:
<ol>
<li class="class1">Item 1</li>
<li class="class1">Item 2</li>
<li class="class1">Item 3</li>
<li class="class2">Item 4</li>
<li class="class2">Item 5</li>
</ol>
The lists are generated automatically, and the position of the first class2 item may vary inside the list (it can even be absent in some case, leaving only class1 items in the list).
I would like to add something in the ::before of the first item of each class (like a specific header for each type of item in my list). Ending up with something like this:
Example of expected result
Anyone could help me with the CSS selector to use for this? I tried several things with + or ~ but nothing works seems for now...
Thanks!
David
There is no :first-of-class selector available, but you can use the general sibling combinator to remove the pseudo element for all elements with the same class, that are following the first one:
.class1::before { content:"some header for class 1"; display:block; }
.class2::before { content:"some header for class 2"; display:block; }
.class1 ~ .class1::before, .class2 ~ .class2::before { content: none; }
<ol>
<li class="class1">Item 1</li>
<li class="class1">Item 2</li>
<li class="class1">Item 3</li>
<li class="class2">Item 4</li>
<li class="class2">Item 5</li>
</ol>
You can use a section tag to define a header for your list.
<section>
<h3>Reference Document</h3>
<ol>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ol>

jqueryui connected sortable list to activate hover when dragged

In Short
I need to be able to activate a menu on hover while I'm dragging a sortable object. Is this possible?
The context:
I have a nav menu that's being powered by cssmenu, which basically takes list items and arranges them into a nice clean menu structure. I'd like to connect the lists in the nav menu and be able to rearrange the elements with jqueryui sortable connected lists. I can get the connected lists to work separately (outside of the cssmenu) and within one menu of a particular list. The problem is when I try to drag from one menu item to another, the drop-down isn't activated.
You can see in this fiddle that I can sort objects within a list but I can't activate the drop-down menu to drag it into another list (i.e. drag from the yellow list to the blue list or vice versa):
http://jsfiddle.net/9j5wyoLn/
html
<div id='cssmenu'>
<ul id='subNavElements'>
<li class='active has-sub'><a href='#'><span>About Us</span></a>
<ul id="sortable1" class="connectedSortable">
<li class="">Item 1</li>
<li class="">Item 2</li>
<li class="">Item 3</li>
<li class="">Item 4</li>
</ul>
</li>
<li class='active has-sub'><a href='#'><span>Articles</span></a>
<ul id="sortable2" class="connectedSortable">
<li class="">Article 1</li>
<li class="">Article 2</li>
<li class="">Article 3</li>
<li class="">Article 4</li>
</ul>
</li>
</ul>
</div>
js
//make sortable
$(document).ready(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
css: handled in fiddle (too much to show below)
Figured it out...
I added a class in the css called "openSaysMe" which styles the elements to appear.
#cssmenu .openSaysMe {
left: auto;
top: 34px;
opacity: 1;
}
Then I added the class when the items are being sorted, took the class away once the sorting was complete.
$( "#sortable1, #sortable2, #sortable3" ).sortable({
connectWith: ".connectedSortable",
sort: function( event, ui ) {
$('#cssmenu ul ul').addClass('openSaysMe');
},
beforeStop: function( event, ui ) {
$('#cssmenu ul ul').removeClass('openSaysMe');
}
}).disableSelection();
Here's a fiddle: http://jsfiddle.net/9j5wyoLn/2/

CSS Selector for incremented ID

I have a bunch of incremented elements
<ul>
<li id="idTab1">
<li id="idTab2">
<li id="multiTab1">
<li id="multiTab2">
<li id="multiTab3">
<li id="idTab3">
</ul>
Is there some CSS selector method for me to select all 'multiTab' elements? something like 'li #multiTab*' ? :P
You can use ^=, example:
li[id^="mulitiTab"]

Custom WordPress menu output (wrapping parent links in span)

I'm trying to implement a responsive jQuery navigation but I need to extend the default output of the WP menu. I need to wrap any pages that have children with a span and remove the link. For example:
<nav id="menu-right">
<ul>
<li>
<span>Friends</span>
<ul>
<li>Alexa</li>
<li>Alexander</li>
<li>Fred</li>
<li>James</li>
<li>Jefferson</li>
<li>Jordan</li>
<li>Kim</li>
<li>Meagan</li>
<li>Melissa</li>
<li>Nicole</li>
<li>Samantha</li>
<li>Scott</li>
</ul>
</li>
<li>
<span>Family</span>
<ul>
<li>Adam</li>
<li>Ben</li>
<li>Bruce</li>
<li>Eddie</li>
<li>Jack</li>
<li>John</li>
<li>Martina</li>
<li>Matthew</li>
<li>Olivia</li>
<li>Owen</li>
</ul>
</li>
<li>
<span>Work colleagues</span>
<ul>
<li>David</li>
<li>Dennis</li>
<li>Eliza</li>
<li>Larry</li>
<li>Lisa</li>
<li>Michael</li>
<li>Rachelle</li>
<li>Rick</li>
</ul>
</li>
</ul>
</nav>
Any ideas?

inject html without using jscript

I have the following code:
<ul id="myList">
<li class="li1">Example 1</li>
<li class="li2">Example 2</li>
<li class="li3">Example 3</li>
<li class="li4">Example 4</li>
</ul>
Is there any way i can transform the list to:
<ul class="myList">
<li class="li1"><div class="container">Example 1</div></li>
<li class="li2"><div class="container">Example 2</div></li>
<li class="li3"><div class="container">Example 3</div></li>
<li class="li4"><div class="container">xample 4</div></li>
</ul>
using css only.
without using javascript
CSS cannot add elements, that really isn't its purpose.
That being said, you can achieve a similar effect by making the items display: block, like this:
#myList > li { display: block; }
No. CSS is designed to instruct the browser on how elements look and are positioned. It isn't capable of editing the live HTML.

Resources