Prevent merge of elements when they are unique - javascript

I'm using TinyMCE 6 and I've created a custom block insert using a <ul>, and for the most part this is working great. However, if I have several and position the cursor in front of one of the blocks and hit backspace, it then merges all the contained <li> into a single <ul>. I've tried using attributes like data-id, id, name etc but Tiny simply discards this data from one of the elements and does the merge anyway. If I use a random number as a class name, they do not merge so this is a workaround.
For reference, the blocks are set as noneditable (I have a double-click handler configured for a custom function), so I don't see why it would try and merge them anyway.
Any ideas?
Here's a snippet of HTML as it should be:
<ul id="123" class="leaders mceNonEditable">
<li class="item-en text_gold"><span>Mmm Cookies</span><span>$MONEY$$$$$$</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
</ul>
<ul id="234" class="leaders mceNonEditable">
<li class="item-en"><span>Mmm Cookies</span><span>$495</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
</ul>
And some that ended up:
<ul id="123" class="leaders mceNonEditable">
<li class="item-en text_gold"><span>Mmm Cookies</span><span>$MONEY$$$$$$</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
<li class="item-en"><span>Mmm Cookies</span><span>$495</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
</ul>

Related

Deal with multiple ID's in document

I have a problem dealing with duplicate ID's. I'm also aware it's very bad practise to have elements with the same ID but in this case, I'll end up having to change a massive part of the application to change the ID's so they can be unique.
I am having a problem toggling classes on an element in jQuery. My structure is below:
<ul>
<li id="wl-7050"> <!-- This acts as a main data group holder for the below li elements -->
<span></span>
<div id="wlHeader-7050"></div>
<div id="wlBody-7050">
<ul>
<li id="wl-7050"> <!-- This is the single element version of the data group header as above -->
<div id="wlHeader-7050"></div>
</li>
<li id="wl-7051"></li>
<li id="wl-7052"></li>
<li id="wl-7053"></li>
</ul>
</div>
</li>
</ul>
What I'm needing is a function where if I click the first instance of ID wl-7050, the child elements receive a new class. Whereas, if I select the second (single) element with ID of wl-7050 then only that one element has the new classes added to it.
I've tried using jQuery along with it's :first & :eq(0) attributes but still no luck unfortunately.
I do have classes assigned to each li element and it's child elements but whenever I run $('#wl-7050:eq(0)'), it returns both and the parent wl-7050 element get's used also.
I am flexible with JavaScript and jQuery answers.
The id attribute specifies a unique id for an HTML element (the value must be unique within the HTML document).
You can't have two wl-7050. Use classes. Then to work on "add new class on click" it's just hard code. If you need a help I can edit my answer. But is just coding. Html IDs is a concept
I've been there before: I've had to deal with applications that do weird things, where changing them to be "correct" causes more grief than just dealing with it and moving on. You know duplicate IDs are bad, I know duplicate IDs are bad; let's sort the problem. (Yes, they're bad. Yes, they shouldn't be there. Unfortunately, there they are.)
You can treat IDs just like any other attribute on an element: they're attributes, albeit special ones. Code like this will work to select all elements with the same ID: $('[id=wl-7050]').
Now, we need to bind a click event to them. We'll do the same thing as we always do:
var lis = $('[id=wl-7050]').click(function(e){
console.log(this);
});
Here's the trick, and it would happen even if these elements all had different IDs: when you're clicking in a child LI, that click event will bubble up to the parent. We'll need to shut off event propagation so we don't trigger our click event twice:
var lis = $('[id=wl-7050]').click(function(e){
e.stopPropagation();
console.log(this);
});
Now we're in business and can work to figure out which type of LI we're working with: top-level or child.
var lis = $('[id=wl-7050]').click(function(e){
e.stopPropagation();
if ($(this).children('li').length > 0) {
// Top-level LI
}
else {
// Child-level LI
}
});
That should get you where you need to be. Let's all agree to never speak of those duplicate IDs again.
If you can't change the IDs, you could try adding a different class name to both elements:
<ul>
<li id="wl-7050" class="wl-7050-main">
<span></span>
<div id="wlHeader-7050"></div>
<div id="wlBody-7050">
<ul>
<li id="wl-7050" class="wl-7050-single">
<div id="wlHeader-7050"></div>
</li>
<li id="wl-7051"></li>
<li id="wl-7052"></li>
<li id="wl-7053"></li>
</ul>
</div>
</li>
</ul>
Then you query with:
$("#wl-7050.wl-7050-main");
$("#wl-7050.wl-7050-single");
You don't need to add an id to each li that would make it overly complicated. Just use classes inside your items and call them this way:
$("#group li").on("click", function(){
alert($(this).data("id"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="wl-7050"> <!-- This acts as a main data group holder for the below li elements -->
<span></span>
<div id="header"></div>
<div id="body">
<ul id="group">
<li data-id="1"> <!-- This is the single element version of the data group header as above -->
<div class="wlHeader"></div>
</li>
<li data-id="2"> <!-- This is the single element version of the data group header as above -->
<div class="wlHeader"></div>
</li>
<li data-id="3"> <!-- This is the single element version of the data group header as above -->
<div class="wlHeader"></div>
</li>
</ul>
</div>
</li>
</ul>

targeting a li with javascript without a ID

I have a mobile nav, that looks like this
<ul id="mobile-menu" class="menu>
<li class="normal-link">link-1</li>
<li class="dropdown-link">link-2
<ul class="submenu">
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
</ul>
</li>
<li class="dropdown-link">link-3
<ul class="submenu">
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
</ul>
</li>
<li class="normal-link">link-1</li>
</ul>
I cant change the html/wordpress generated code, but I can add css and javascript. So is there a way for me to get next to the dropdown-link's a image that will let the submenu free. if the image is pushed the image will change. if pushed again it will go back to the normal image and the dropdown dissappears again?
I am mostly looking for answer for the problem with of javascript on the dropdown link's but just so you know what i want to do with it.
This question is so very, very vague. But I guess you're looking for the nth-child() selector.
See the docs here for more information. Target your 'mobile-menu' ul, and use nth-child to select the li elements within.
My big question would be, why can't you change the HTML? If it's Wordpress, you can modify the template to change the HTML.
You question is not really clear but if you want to retrieve an element without using id, first you may use their classes
var myClass = document.getElementsByClassName("classname"); //returns a nodeList like array
myClass[0] //first element with "classname"
You may also use tag names
var divs = document.getElementsByTagName("div");
divs[2] //third "divs"
You may also use querySelectorAll, this works pretty much like CSS selector and also returns a nodeList
var qs = document.querySelectorAll(".class");
I hope this helps
You could add a class and use the Jquery class selector: $(".class-name") to target a specific <li>

how do I wrap my menu in to sub menu using jquery?

this is my site.
this is how I finally make it look like
I want to divide the the menu list items into two sub menu say menu left and right. And then wrap them in a div. This is make it easy for me to style them and this way they would stay responsive as well.
Now, I have been trying to achieve this by
jQuery( ".menu-item-580", ".menu-item-583",".menu-item-584",".menu-item-563").wrapAll("<div class='new' />").after(".menubar-brand");
I have trying this in browser console.
I also tried same above code by using appendTo() instead of after()
But, still no luck.
In your code you're basically doing this:
<ul>
<li>
<div class="new">
<li>
<li>
</div>
<li>
</ul>
which is not a valid markup.
The easiest way to goup <li>s would be to assign different additional css classes to different parts of the list:
<ul>
<li class="group1">
<li class="group1">
<li class="group2">
<li class="group2">
</ul>
Also, have a look at this: Is there a way to group `<li>` elements?

jQuery Mobile: unordered list

I have a an unordered list like this:
<ul id="mylist">
<li id="1">Heading</li>
<li id="2">Second</li>
</ul>
What I want to do is, when I add another list item:
<li id="3">First</li>
It needs to be prepended to the list item which is just below the first list item in "mylist". ie, just below 'Heading' in this case. So the final list looks like this:
<ul id="mylist">
<li id="1">Heading</li>
<li id="3">First</li>
<li id="2">Second</li>
</ul>
Thanks in advance.
NB: What I learned from trying to implement this is, when we append or prepend some content to an element selected with jQuery, it'll get prepended or appended to the content inside the selected element.
You can use after method and :first selector:
$('#mylist li:first').after('<li id="3">First</li>')
http://api.jquery.com/after/
You can use .after, or .insertAfter, for being more precise about placement in the DOM tree.

How to expand an unordered list down to a certain link

I have a dynamically built unordered list like below, and I want to find a way to expand all the nodes above the link with a certain id once the list is loaded using jquery,
For example I might want to expand all the nodes required for the link with the id=1905 to be visiblem and leave all other nodes collapsed.
Hope this makes sense.
<div id="menu">
<ul>
<li><a class="inactive" href="#"><img src="images/folder.png">Baking</a>
<ul>
<li><a class="inactive" href="#">Bars</a>
<ul>
<li><a id="1905" class="rlink" href="url">Rasberry Crumb Breakfast Bars</a></li>
</ul>
</li>
</ul>
</li>
<li><a id="1803" class="rlink" href="url">text</a></li>
</ul>
</div>
So the list would initially load like this
And I would want to expand it like this
You could try going up the parent nodes of the element you want and activate them:
var parentList= $('#link1905').closest('ul');
while (parentList.length > 0) {
parentList.prev('a').removeClass('inactive'); /* and/or .addClass('active'); */
parentList = parentList.closest('ul');
}
Also you must start your element id's with a letter: What are valid values for the id attribute in HTML?

Categories

Resources