safecracker matrix-menu doesn't appear in overlay - expressionengine

I have a site, not visible to the public, where I use safecracker and matrix fields in several locations. On pages that load normally, everything is fine. But when the matrix fields appear in an overlay (using colorbox), the matrix-menu div isn't created.
Stepping through the code with FireBug, the issue seems to be that the line:
var $body = $(document.body);
doesn't set $body correctly (maybe this is a race condition for the overlay loading?). So when it gets to this chunk of code in matrix.js:
obj.menu.$ul = $('<ul id="matrix-menu" />').appendTo($body).css({
opacity: 0,
display: 'none'
});
$body doesn't resolve, so the menu can't attache anywhere. I think I've fixed it, but want to check and see if I should be worried that I'll break anything else. If I change the above code to:
obj.menu.$ul = $('<ul id="matrix-menu" />').appendTo($(document.body)).css({
opacity: 0,
display: 'none'
});
everything seems fine. Is there a better way to address this?

If the Matrix field doesn’t have a height when it is first initialized, it puts most of its initialization stuff on hold, assuming that it’s either hidden by default or lives on a secondary publish tab. This cuts down on the initial page load time and also fixes some issues with some celltypes (Text, Assets, maybe others.) that need to know the dimensions of DOM elements within their cells.
Matrix will automatically resume its initialization when it has been expanded or its tab has been clicked on, but if you’re using Matrix outside of the Publish page and hiding it, you’ll need to trigger that initialization-resuming yourself:
for (var i = 0; i < Matrix.instances; i++)
{
Matrix.instances[i].initRowsIfVisible();
}

Related

Inline inside flex

I am currently using the following css to display a list of items with a flexbox
section ol li div ul {
display:flex;
flex-direction:row;
flex-wrap: wrap;
gap:7px;
row-gap:0;
list-style-type: none;
}
This satisfies me on all but one problem:
when I have a big item that will not fit entirely on the rest of the line, it will be set at the beginning of a new line, thus possibly making a huge part of the line before unused. I do not wish that (note that for small items, this is exactly what I want).
Initial goal (probably not achievable): I have been thinking on what kind of rule I would like and it would be something like "if more than x% of the line is wasted, then display the item inline instead". This would enable to continue filling the line.
I have currently abandoned on doing that with only html and css and I might consider trying to write such a rule in js later, but not for now (unless somebody has a very nice solution).
Current goal: I have thus decided to manually specify some items (that are "big") that should be inlined (sometimes using media queries, but we can ignore them for now). The idea is to add the following class to those objects.
.inlineitem {
display:inline;
}
Problem: display:inline; within a flex container does not work and I do not wish to change the whole flex container for the other items... Is there a way to achieve what I want ?

Vertical scrollbar visibility in react-virtualized table

When using react-virtualized's Table class with a table with many columns, it is necessary to scroll horizontally to the very end of the columns in order to be able to see the vertical scrollbar.
(you can see an extremely similar question about React-Table here, it is not clear to me if react-virtualized's table code uses React-Table's code at all, but in any case I am having an identical problem)
in the linked issue someone commented that:
.ReactTable .rt-tbody{
overflow: initial !important;
}
fixed their issue. I checked this solution with react-table and got the desired behavior.
However, as far as I can tell react-virtualized table doesn't have tbody class available for css. (The docs do list a bunch of available class names, but a body class name doesn't seem to be on that list).
I've messed around with the css trying to set different overflow options in different ways to no avail. I have not been able to get the vertical scrollbar to display without needing to horizontally scroll all the way to the end. What can I do to make that happen?
(Edit: I've also tried to figure out some way to make this work with react-floating-scroll but it seems like the ref passed back by virtualized table isn't the kind of ref the scroll code needs...)
This will move the scroll bar to the left side instead of right side.
.ReactVirtualized__Table {
.ReactVirtualized__Table__Grid {
direction: rtl !important;
.ReactVirtualized__Grid__innerScrollContainer {
direction: ltr !important;
}
}
}

React Virtualized Table drop down filter in header cut off by overflow: none

We have a React Virtualized Table with a header row.
One (or more) of the header cells will contain a drop down Componentallowing you to select values to filter the column by.
We have created the Component, and the ValuePanel has position: absolute; to make it float above the other elements on the page.
We included it in the header and it mostly works, except that the HeaderRow has overflow:none; on it.
<div
class="ReactVirtualized__Table__headerRow table-toplevel-row table-toplevel-header"
role="row"
style="height: 100px;overflow: hidden;padding-right: 17px;width: 1920px;"
>
This "chops off" the bottom of the panel showing the values.
Reading up on overflow: none; and position: absolute; it seems that the ValuePanel must have a (positional) parent outside of the HeaderRow.
This can be achieved by either:
Moving the ValuePanel element so it's no longer an ancestor of the HeaderRow.
Having the nearest ancestor of the ValuePanel element with a position of absolute or relative (i.e. it's positional parent) outside of the HeaderRow.
The problem with 1, is that the Component is supposed to be a self-contained and reusable anywhere, so it shouldn't require part of it's HTML to exist outside of itself ... that violates the "self-contained" bit.
The problems with 2 are that we won't always be able to guarantee where the positional parent is in the hierarchy above the ValuePanel unless the positional parent is inside the Component. And the ValuePanel gets it's width from it's positional parent, so if the positional parent is outside of the Component then the width could well be wrong.
We very much want to avoid having to specify a fixed width for the component and/or the ValuePanel. And we want to keep the Component self-contained.
The thought occurred to remove overflow: none; from the HeaderRow, but it's obviously there for a reason. I haven't tested, but I assume getting rid of that would cause issues with header content that, well, overflows. We could replace it with overflow-y: none;overflow-x: hidden;, but again this seems like it's likely to cause issues under certain circumstances.
I had a search around, but I couldn't find any results for it.
Has anyone achieved this before and can provide some insight? Or otherwise has some ideas/advice?
Slightly longer answer now that I'm back at my computer: Check out react-portal.
It lifts content out of the z-index stack (and so avoids clipping problems) while maintaining the visual position of it (top/left), allowing it to render outside of the clipping rect/box of its parent. It's perfect for things like drop-down menus within List or Table.

CSS - z-index:-1 breaking in google chrome

Basically creating a webpage with a dropdown menu I wrote following a tutorial. My page layout consists of 3 separate tables which include 1 for the title/banner, one for the drop down menu and one for the body/content.
The problem I am having first off is that when I scroll over my drop-down menu it drops behind my body/content table. I found a fix for this which was to include z-index:-1. This worked perfectly in IE but after testing it in chrome it prevented links and iframes to be interacted with on the content/body table.
#bodytable {width:1100px;
height:100%;
margin:auto;
position:relative;
top:10px;
z-index:-1;
}
The entire .css code can be found here:
http://pastebin.com/T97JAjQ8
Try giving them each a positive z-index value. Obviously the higher numbes will be "on top" of the other with lesser value. Instaed of giving a table "-1", give it something positive, like 10 and make the dropdown menus "20". You can even set the z-index of the body, to 0 as a baseline.
I haven't confirmed this, but it could be that chrome doesn't like negative z-index values.
Giving Negative z-index makes your element to go under body or wrapper div and hence, prevent them to be interacted because the body element is on the top of that table when you click the event occurs on the body tag not table tag. You have to give positive z-index value. Default stack order of elements is determined the position where the element is defined. For example, your table will be have a larger z-index value if it is defined after menu div. You can fix your problem by changing only the current stack order. By just changing that negative value to positive.
element {
z-index:1;
}
The above code will set the target element to be on top of others beside the current stack order.

determining how many items in a div

I have a div in which I'm putting some items (as spans). If there are too many items, I would like a "more" link to appear, otherwise- no link.
Problem is the div's width is dynamic (it's about 20% of the page - which means I can't tell how wide exactly it is).
Question is - how to determine (preferably on client side, but might be on server side as well) if there are too many items - and instead of displaying the extra items - displaying a "more" link.
For example here there are 2 extra items, which should not be displayed at first, but only after the user will click the "more" link (which still doesn't exist).
I'm not mentioning my server side language because if the problem can be solved only on server side, just a general description will be enough.
Thanks.
First of all, embedded styles in HTML? Eww!! Use CSS files and class attributes.
Secondly, you should use <UL> for lists, as it seems you are trying to build a list.
To answer your question, you can easily do this with jQuery (if set an ID on your DIV):
var maxCount = 3;
if ($('#myDiv').find('SPAN').length > maxCount)
{
//over max, so hide something.
}
But really it should be more like (where myList is an ID of an unordered list):
var maxCount = 3;
if ($('#myList').children().length > maxCount)
{
//over max, so hide something.
}
This is a pretty common feature. Here's a jQuery plug-in called lessMore to do it. You would call it like so:
$('#content').lessMore({
limit: 5,
numbers: false
});
Using an existing plug-in is better for code-reuse and you avoid re-inventing the wheel.

Resources