I wrote a plugin for CKEditor 4 that uses widget and dialog. My widget, simplifying a little bit, consists of a div with a nested ul and a number of li's. For some reason, when I switch from WYSIWYG mode to SOURCE mode, the ul is turned into a double nested ul.
I have defined which elements in the widget should be editables and I have defined which elements should be allowedContent for those editables.
My original structure in WYSIWYG mode (after the dialog closes and the widget is created) is like this:
<div class="mycustombox">
<div class="conditions-box">
<div class="conditions-services">
<span class="rwd-line-title">TITLE FOR THE UNORDERED LIST</span>
<ul class="services-list">
<li>an example list item</li>
<li>another example list item</li>
</ul>
</div>
</div>
</div>
I have double checked that this is the actual html by inspecting the source of the page in the Chrome Developer Console. But when I switch to SOURCE mode, the structure then becomes:
<div class="mycustombox">
<div class="conditions-box">
<div class="conditions-services">
<span class="rwd-line-title">TITLE FOR THE UNORDERED LIST</span>
<ul class="services-list">
<ul>
<li>an example list item</li>
<li>another example list item</li>
</ul>
</ul>
</div>
</div>
</div>
The original ul with the class I gave it is there, but there is an extra nested ul wrapping the li elements.
I have defined my allowed widget content in the plugin.js:
allowedContent: 'div(!mycustombox); div(!conditions-box); div(!conditions-services); span(!rwd-line); span(!rwd-line-title); ul(!services-list); li; p; div',
requiredContent: 'div(mycustombox)',
upcast: function( element ) {
return element.name == 'div' && element.hasClass( 'mycustombox' );
},
And I have defined the ul element as an editable like so:
editables: {
priceincludes: {
selector: 'div.conditions-box div.conditions-services ul',
allowedContent: 'li em strong'
},
}
I have also allowed ul's to be editable by the general CKEditor instance as so:
CKEDITOR.dtd.$editable[ 'ul' ] = 1;
Is there some setting in the CKEditor configuration which could be causing this behaviour?
Well I don't know if this is the best solution, but it works.
Tell CKEDitor to stop trying to automatically wrap li elements with a ul tag. For some reason it's treating them as though they weren't already wrapped in a ul tag.
Using this at the beginning of my plugin.js fixes the problem:
delete CKEDITOR.dtd.$listItem['li'];
delete CKEDITOR.dtd.$intermediate['li'];
I got the idea from here:
http://margotskapacs.com/2014/11/ckeditor-stop-altering-elements/
Seems kind of hackish to me, but until I find a better solution I'll just use this.
Related
Hello I am relatively new to QA automated web testing and I try to use SO as a last resort.
That being said I am having issues selecting a choice from a drop down menu in our web app.
Here is the following code:
<div id="edit-main-user-role-wrapper" class="form-item">
<select id="edit-main-user-role" class="form-select my-dropdown ahah-processed" name="main[user_role]" style="display: none;"></select>
<div class="newListSelected" style="position: static;">
<span class="selectedTxt">
Student
</span>
<ul class="newList" style="top: -136px; height: 136px; left: 0px; display: none;">
<li>
<a class="" href="JavaScript:void(0);"></a>
</li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
When I inspect the drop down icon with Firefox inspect element it directs me to this line in the code: span class="selectedTxt"
I have tried accessing the list by id, class, xpath, and css all to no avail.
Here are some of my past attempts:
#browser.div(:class => 'form-item').select_list(:text => 'Student').fire_event ("on click")
#browser.select_list(:xpath, menu).option(:text, option).click
An element with a select tag should only be meaningful if there are elements with option tags nested inside it. Often these pages have a lot of extra javascript in them to give context.
For dropdowns that don't follow the select/option pattern, you want to click on the element that drops down the list, and then click on the element you want that becomes visible as a result.
This is what eventually worked for me:
#browser.span(:class, "selectedTxt").click # to make the list visible
#browser.element(:xpath, "#{xpath}").click # click on the specified xpath
I know this may not be the most elegant answer, but it works!
not sure if you're still looking for answers, but either of these worked for me:
#browser.select_list(:id => "you_leaving_us").option(:text => "Other").select
#browser.select_list(:id => "you_leaving_us").option(:value => "8").select
Instead of li's, I had options. Hope it works
I wish to customize a new style in ckeditor (under liferay 6.2).
So far, I'm able to create styles like this, in the ckconfig.jsp :
{name: 'Floating style', element: 'div', attributes: {'class': 'floating-list'}}
This is a style I would like to apply to a wrapping div parent to a the desired ul list. It would look like that :
<div class="floating-list">
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>
But the problem is that when I apply the style to my list, it of course applies to my ul li contents like this :
<ul>
<li><div class="floating-list">item</div></li>
<li><div class="floating-list">item</div></li>
<li><div class="floating-list">item</div></li>
<li><div class="floating-list">item</div></li>
</ul>
To avoid this behaviour, I wrote a little piece of jquery code :
$('.floating-list').closest('ul').each(function(){
var list = $(this);
var item = list.find('li');
item.each(function(){
$(this).html( $(this).find('.floating-list').html() );
});
list.replaceWith('<div class="floating-list"><ul>'+list.html()+'</ul></div>');
});
This works actually, but this is really dirty.
I'm wondering if there was a way to make it out. Thanks.
can try this:
CKEDITOR.instances.idofyourCKEditor.on('change', function() {
//for apply to all li's of ckeditor
jQuery(".cke_reset").contents().find("li").each(function(){
if(jQuery(this).parent().is("ul")){
jQuery(this).wrap("<div></div>"); //or .wrapInner( "<div class='new'></div>"); if you want do inside
}
});
});
with the event change can update the list when you are creating or editing
with the method contents() of jquery can update the elements inside of iframe .cke_reset, or the id if you can find him.
with the method parent() or children().eq(0) of jquery can get the element for check if is or not wrap
with the method wrap("<div class='chimichanga'></div>") and wrapInner( "<div class='new'></div>") can update the code html fast and easy.
all,
I'm having an issue when using the panelbar and animation. whe it expands, it 'jumps' a little at the bottom. My content inside the panel does have padding/margin at the bottom, which i need there to create separation. Anyone know how to make it quit jumping while still have padding/margin at the bottom of the content inside it?
We also had this trouble with panelBar, and we solved it by adding css rule to a content in panelBar like this:
html:
<ul data-role="panelbar" >
<li>
<span><h3>Some text</h3></span>
<ul class="category-content>
<li> Some item </li>
</ul>
</li>
</ul>
css:
.category-content {
width: 100%;
}
We have setup the twitter bootstrap dropdown to work on hover (as opposed to click [yes we are aware of the no hover on touch devices]). But we want to be able to have the main link work when we click it.
By default twitter bootstrap blocks it, so how can we re-enable it?
Just add disabled as a class on your anchor:
<a class="dropdown-toggle disabled" href="http://google.com">
Dropdown <b class="caret"></b></a>
So all together something like:
<ul class="nav">
<li class="dropdown">
<a class="dropdown-toggle disabled" href="http://google.com">
Dropdown <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>Link 1</li>
<li>Link 2</li>
</ul>
</li>
</ul>
Since there is not really an answer that works (selected answer disables dropdown), or overrides using javascript, here goes.
This is all html and css fix (uses two <a> tags):
<ul class="nav">
<li class="dropdown dropdown-li">
<a class="dropdown-link" href="http://google.com">Dropdown</a>
<a class="dropdown-caret dropdown-toggle"><b class="caret"></b></a>
<ul class="dropdown-menu">
<li>Link 1</li>
<li>Link 2</li>
</ul>
</li>
</ul>
Now here's the CSS you need.
.dropdown-li {
display:inline-block !important;
}
.dropdown-link {
display:inline-block !important;
padding-right:4px !important;
}
.dropdown-caret {
display:inline-block !important;
padding-left:4px !important;
}
Assuming you will want the both <a> tags to highlight on hover of either one, you will also need to override bootstrap, you might play around with the following:
.nav > li:hover {
background-color: #f67a47; /*hover background color*/
}
.nav > li:hover > a {
color: white; /*hover text color*/
}
.nav > li:hover > ul > a {
color: black; /*dropdown item text color*/
}
For those of you complaining about "the submenus don't drop down", I solved it this way, which looks clean to me:
1) Besides your
<a class="dropdown-toggle disabled" href="http://google.com">
Dropdown <b class="caret"></b>
</a>
put a new
<a class="dropdown-toggle"><b class="caret"></b></a>
and remove the <b class="caret"></b> tag, so it will look like
<a class="dropdown-toggle disabled" href="http://google.com">
Dropdown</a><a class="dropdown-toggle"><b class="caret"></b></a>
2) Style them with the following css rules:
.caret1 {
position: absolute !important; top: 0; right: 0;
}
.dropdown-toggle.disabled {
padding-right: 40px;
}
The style in .caret1 class is for positioning it absolutely inside your li, at the right corner.
The second style is for adding some padding to the right of the dropdown to place the caret, preventing overlapping the text of the menu item.
Now you have a nice responsive menu item which looks nice both in desktop and mobile versions and that is both clickable and dropdownable depending on whether you click on the text or on the caret.
I'm not sure about the issue for making the top level anchor element a clickable anchor but here's the simplest solution for making desktop views have the hover effect, and mobile views maintaining their click-ability.
// Medium screens and up only
#media only screen and (min-width: $screen-md-min) {
// Enable menu hover for bootstrap
// dropdown menus
.dropdown:hover .dropdown-menu {
display: block;
}
}
This way the mobile menu still behaves as it should, while the desktop menu will expand on hover instead of on a click.
An alternative solution is just to remove the 'dropdown-toggle' class from the anchor. After this clicking will no longer trigger the dropwon.js, so you may want to have the submenu to show on hover.
You could use a javascript snippit
$(function()
{
// Enable drop menu clicks
$(".nav li > a").off();
});
That will unbind the click event preventing url changing.
Here's a little hack that switched from data-hover to data-toggle depending the screen width:
/**
* Bootstrap nav menu hack
*/
$(window).on('load', function () {
// On page load
if ($(window).width() < 768) {
$('.navbar-nav > li > .dropdown-toggle').removeAttr('data-hover').attr('data-toggle', 'dropdown');
}
// On window resize
$(window).resize(function () {
if ($(window).width() < 768) {
$('.navbar-nav > li > .dropdown-toggle').removeAttr('data-hover').attr('data-toggle', 'dropdown');
} else {
$('.navbar-nav > li > .dropdown-toggle').removeAttr('data-toggle').attr('data-hover', 'dropdown');
}
});
});
This can be done simpler by adding two links, one with text and href and one with the dropdown and caret:
Posts
<ul class="dropdown-menu navbar-inverse bg-inverse">
<li>Create</li>
</ul>
Now you click the caret for dropdown and the link as a link. No css or js needed.
I use Bootstrap 4 4.0.0-alpha.6, defining the caret is not necessary, it appears without the html.
<div id="menu">
<ul>
<li>Menu link</li>
</ul>
</div>
<div id="content">Dummy content</div>
I want to get the UL tag using parent id.
The condition is if the UL tag is missing, i need to apply new class for the Content Div.
script
document.observe("dom:loaded", function() {
if( --------)
{
$('content').removeClassName('fwidth');
}
else{
$('content').addClassName('fwidth');
}
Thanks
I don't really understand your question, but if you want to find out if <div id="content"> has ul elements, try
if ($('content').down("ul"))