Tabulator sticky headers without using the height argument - sticky

I want to have sticky headers in Tabulator, and I don't want to use the height variable when creating the table. Any ideas would be greatly appreciated.
var table = new Tabulator("#example-table", {
height:"100px", // Sticky header works
// height:false,// Use instead of height:"100px", sticky header fails
// leaving the height argument out, sticky header fails
columns:[
{title:"Name", field:"name"},
{title:"Progress", field:"progress", align:"right", sorter:"number"},
{title:"Gender", field:"gender"},
{title:"Rating", field:"rating", align:"center"},
{title:"Date Of Birth", field:"dob", align:"center", sorter:"date"}
],
data: [
{id:1, name:"Oli Bob", progress:12, gender:"male", rating:1, dob:"14/04/1984", car:1},
{id:2, name:"Mary May", progress:1, gender:"female", rating:2, dob:"14/05/1982", car:true},
{id:3, name:"Christine Lobowski", progress:42, gender:"female", rating:0, dob:"22/05/1982", car:"true"},
{id:4, name:"Brendon Philips", progress:100, gender:"male", rating:1, dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", progress:16, gender:"female", rating:5, dob:"31/01/1999"},
{id:6, name:"Frank Harbours", progress:38, gender:"male", rating:4, dob:"12/05/1966", car:1},
{id:7, name:"Jamie Newhart", progress:23, gender:"male", rating:3, dob:"14/05/1985", car:true}
]
});
Please see/run this jsfiddle.

If you upgrade to version 4.6 and add a max-height of 100% to your table then the table will scroll once it has exceeded the height of the containing element.
The table must have a scrollbar in order for the headers to stay fixed, otherwise it just treats the table as a static element on a page and dosnt overflow

Solved via #Oli Folkerd (of course). Using/updating to Tabular 4.6, and setting the maxHeight arguement to 100%. Then the table will scroll with sticky headers within the container element. Perfect and thank you #Oli Folkerd
See the solution and try it here jsfiddle
HTML
<link href="https://unpkg.com/tabulator-tables#4.6.2/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.6.2/dist/js/tabulator.min.js"></script>
<div class="example-table" id="example-table"/>
CSS
div.example-table {
height: 150px;
border: 1px solid black;
}
JavaScript
var table = new Tabulator("#example-table", {
// height:"100px", // Sticky header works
// height:false, // Use instead of height:"311px", sticky header fails
// leaving the height argument out, sticky header fails
maxHeight:"100%", // use this and version 4.6 of Tabulator
columns:[
{title:"Name", field:"name"},
{title:"Progress", field:"progress", align:"right", sorter:"number"},
{title:"Gender", field:"gender"},
{title:"Rating", field:"rating", align:"center"},
{title:"Date Of Birth", field:"dob", align:"center", sorter:"date"}
],
data: [
{id:1, name:"Oli Bob", progress:12, gender:"male", rating:1, dob:"14/04/1984", car:1},
{id:2, name:"Mary May", progress:1, gender:"female", rating:2, dob:"14/05/1982", car:true},
{id:3, name:"Christine Lobowski", progress:42, gender:"female", rating:0, dob:"22/05/1982", car:"true"},
{id:4, name:"Brendon Philips", progress:100, gender:"male", rating:1, dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", progress:16, gender:"female", rating:5, dob:"31/01/1999"},
{id:6, name:"Frank Harbours", progress:38, gender:"male", rating:4, dob:"12/05/1966", car:1},
{id:7, name:"Jamie Newhart", progress:23, gender:"male", rating:3, dob:"14/05/1985", car:true}
]
});

Related

Change size of the icon in ObjectListItem

i'm setting up a list by getting items from the OData service and when i want to display them using the ObjectListItem i found no way to increase the size of image and i've tried to use css like that but i didn't work
.sapMImg {
font-size: 400px ; /*!important;*/
}
<ObjectListItem
type="Navigation"
press=".onSelectionChange"
icon="/H31{MimeType}"
title="{MatlDesc}"
number="{PriceUnit}"
numberUnit="{BaseUom}"
numberState="{= 11 > 10 ? 'Success' : 'Error' }"
class="sapMImg"
/>
Add this to a css file you are already using:
.sapUiIcon {
font-size: 1.5rem !important;
}
To use an external css file, you can load them using this config on the manifest:
"resources": {
"css": [
{
"uri": "content/css/style.css"
},

sap.ui.layout.SplitPane Doesn't Apply SplitterLayoutData

I am trying to set the size on sap.ui.layout.SplitPane on the left side as following:
<Page title="Where used">
<l:ResponsiveSplitter defaultPane="default">
<l:PaneContainer>
<l:SplitPane requiredParentWidth="400">
<l:layoutData>
<l:SplitterLayoutData size="20%"/>
</l:layoutData>
<Panel height="100%">
<Label text="Hello"/>
</Panel>
</l:SplitPane>
<l:SplitPane requiredParentWidth="400">
<Panel height="100%">
<Label text="Hello"/>
</Panel>
</l:SplitPane>
</l:PaneContainer>
</l:ResponsiveSplitter>
</Page>
As you can see on the code, I tried to achieve with
<l:SplitterLayoutData size="20%"/>
But the size does not apply at all. What am I doing wrong?
I looked at this example: https://github.com/SAP/openui5/blob/master/src/sap.ui.layout/test/sap/ui/layout/ResponsiveSplitter.html#L106, [Result]
Update: The fix should be available as of UI5 version 1.60. Otherwise, please keep reading..
Just figured out that it only works if the aggregation <l:layoutData> comes after the default aggregation.
<l:SplitPane requiredParentWidth="400">
<Panel height="100%">
<Label text="Panel 1"/>
</Panel>
<l:layoutData>
<l:SplitterLayoutData size="20%"/>
</l:layoutData>
</l:SplitPane>
.. which shouldn't actually matter. I'll analyse the source code why it matters and update the answer later.[1] But this is how you can "fix" it so that it works for now.
Source: https://embed.plnkr.co/0yo35xOiSmF5eG6R?show=V.view.xml,preview
[1]: It turns out that SplitPane has an overwritten mutator for the layoutData aggregation:
SplitPane.prototype.setLayoutData = function(oLayoutdata) {
var oContent = this.getContent();
if (oContent) {
return oContent.setLayoutData(oLayoutdata);
} else {
return this;
}
};
source
As you can see, it applies the layout data not to itself but to its content. If the content doesn't exist at that moment, the <layoutData> is just ignored. And since XML nodes are evaluated sequentially one by one, the Panel (content) had to come first before the SplitterLayoutData.
IMO this is clearly a bug in the framework since the framework has to assure that the outcome is always the same no matter in which order aggregations were defined (content <--> layoutData).
Please check this: JS Fiddle
oResponsiveSplitter = new sap.ui.layout.ResponsiveSplitter({
defaultPane: "defaultPane",
rootPaneContainer: [
new sap.ui.layout.PaneContainer({
orientation: "Horizontal",
panes: [
new sap.ui.layout.PaneContainer({
// orientation: "Horizontal",
panes: [
new sap.ui.layout.SplitPane({
demandPane: true,
content: new sap.m.Panel({
headerText: "1",
content: new sap.m.Text({text: lorem + lorem})
}),
requiredParentWidth: 400
}),
new sap.ui.layout.SplitPane({
demandPane: false,
content: new sap.m.Panel({
headerText: "2",
content: new sap.m.Text({text: lorem + lorem})
}),
requiredParentWidth: 400,
layoutData: new sap.ui.layout.SplitterLayoutData({
size: "20%"
})
}),
new sap.ui.layout.SplitPane({
demandPane: true,
content: new sap.m.Panel({
headerText: "3",
content: new sap.m.Text({text: lorem + lorem})
}),
requiredParentWidth: 400,
}),
]
})
]
})
]
});
I think it answers your problem.
Also, I understand that here SplitterLayoutData size works as expected when the layout is horizontal.

Flexible content modules in Silverstripe

We are looking at using Silverstripe CMS and want to be able to have modules which can be reordered.
We have come from a Wordpress setup and mostly use the flexible content ACF field. Modules (e.g. text, masthead or video) need to be able to be re-ordered.
We use our CMS's as an API so these modules are output as a section to the page or post:
[
{
"id": 10,
"title": "Post title",
"slug": "post_slug",
"path": "/post_slug",
"template": "campaign",
"published": "2017-05-25 06:09:36",
"image": null,
"seo": {
"title": "",
"description": "",
"image": {
},
},
"sections": [
{
"type": "masthead",
"Title": "",
"video": false,
"image": [
],
"showCta": false,
"cta": [
]
},
{
"type": "video_text",
"video_text": [
{
"type": "video",
"video_url": "https://www.youtube.com/watch?v=asdfa",
"video_length": "07:38",
"video_preview": false
},
{
"type": "text",
"title": "Video Title",
"content": "Video text content",
"call_to_action": false,
"cta": [
]
}
]
},
{
"type": "text",
"title": "Text Title",
"content": "",
"alignment": "centre",
"call_to_action": false,
"cta": {
"text": "CTA button",
"link_type": "internal_link",
"internal_link": "about",
"external_link": "",
"section_id": [
]
}
},
]
}
]
Does Silverstripe have it's own way of handling modules / do I need to ditch this flexible content modules method? How do others handle flexible content modules in Silverstripe?
Both silverstripe-blocks and silverstripe-elemental works very well in their own regard but I don't think they will achieve what you want. These modules don't really give you the power to use pre-defined templates. You can hook the templates in but the code will be massive. I not sure if there is an open source module for that yet.
From your JSON code, in order to have those Sections to render something like this below;
<section id="Sections">
<div id="video_text" class="section">
<iframe width="560" height="315" src="https://www.youtube.com/watch?v=asdfa" frameborder="0" allowfullscreen></iframe>
</section>
<div id="text" class="section">
<h2>Text Title</h2>
<a class='text-center btn btn-default' href="/about/">CTA button</a>
</section>
</sections>
You might want to do this.
Use DataObjects (DO) for you Sections, easy for re-ordering.
Create an abstract DO, BlockSection, with fields like Title(Varchar), Content(HTMLText), Sort(Int) and most importantly has_one to Page.
For the video use can name the DO VideoBlockSection and it extends BlockSection,
TextBlockSection for the other one. Don't forget the $singular_name for each DO (useful for nice class naming in the Grid)
On Page getCMSFields add the Grid to manage the Sections. You need to add GridFieldSortableRows and GridFieldAddNewMultiClass and now you can add you Section on each Page.
Add has_many from Page to BlockSection and a method that will render the Blocks and outputs the html.
Page.php
private static $has_many = array(
"Sections" => "BlockSection",
);
function SectionContent()
$aContent = ArrayList::create();
$oSections = $this->Sections();
if (count($oSections )) {
foreach ( $oSections as $oSection ) {
$aContent->push(ArrayData::create([
"Section" => $oSection,
"Content" => $oSection->renderWith([$oSection->ClassName, get_parent_class($oSection)]),
]));
}
}
return $aContent;
For the VideoBlockSection the template array list will be VideoBlockSection and BlockSection
VideoBlockSection.ss
<div id="video_text_{$ID}" class="section">
<iframe width="560" height="315" src="{$URL}" frameborder="0" allowfullscreen></iframe>
</section>
In you specific case, because you are using an API you need to use a wrapper to render the Template.
It needs to match [section][type] to a Template (renderWith) video_text to VideoBlockSection
Lastly in Page.ss
<% loop $SectionContent %>
{$Content}
<% end_loop %>
This was a proof of concept but its working for me so refactoring, speed and memory usage was not considered (but its working).
This way I had to ditch the unnecessary so called "page types" which I find not to be reusable in most cases.
This works 100% for me and I use it together with Bootstrap 3. I use it to create CTAs, parallax scroll, Google Map Section (multiple maps on one page), Thumbnails. Specify image resize method (Cropped, ByWidth, ByHeight).
DO NOT ditch that flexible content modules method.
I am working on an open source module which works with SS4 and Bootstrap 4 (with possibilities of using any other html framework)

ag-grid column headers stacked to the left

Only the first column header is being drawn correctly, all subsequent items in the columnDef array are drawn below it. If I populate the table with data, all column data is stacked to the left as well.
Here's what it looks like; the gray band in the row, below Country is actually moving down, as part of the framework.setTimeout() function in ag-grid.js.
The JS looks like:
gridOptions.columnDefs = [
{ headerName: 'Country', field: 'country' },
{ headerName: 'City', field: 'city' },
{ headerName: 'Jan', field: 'jan_act' },
{ headerName: 'Feb', field: 'feb_act' },
{ headerName: 'Mar', field: 'mar_act' },
{ headerName: 'Apr', field: 'apr_act' },
{ headerName: 'May', field: 'may_act' }];
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
I'm using ag-grid.noStyle.js v7.0.2 and think I have all dependencies loaded correctly for ag-grid. Am not using React or Angular.
Ah, found it! It's the <!DOCTYPE html> tag.
Problem was immediately resolved by changing the height of my div to pixel based, not %, e.g.
<div id="myGrid" style="height: 400px;" class="ag-fresh"></div>
Found it by going back to absolute basics after the JavaScript Datagrid example also failed to work.
Working with the CSS height property and percentage values.

Tiny MCE adding custom HTML tags

I am using Tiny 4.3.3 for MODx
I need to add a
<p class="classname">
<em class="openImg"></em>
Some randome Input text by the user
<em class="closeImg"></em>
</p>
I don't mind if is an extra menu Item or is in the Paragraph dropdown menu. I just want the less time consuming work around possible.
I have tried this http://alexzag.blogspot.co.uk/2009/12/custom-tags-in-tinymce.html but somehow this doesn't work.
Could anyone point me to a good tutorial or tell me how could i add a icon or name to the drop down menu that creates the p and em tags with the right classes automatically please?
Thanks
It has been a while since the question was asked, but as i am currently making exactly the same, i thought i share my discoveries and solutions regarding this matter. :)
I am extending TinyMCE for a test-project at work and our solution needs custom tags - in some of them the user should be able to enter only one line, in others (as your em) a lot of text.
Steps to be done, in order to achieve the desired solution:
tell the TinyMCE editor, that your elements are good using the two configuration keywords extended_valid_elements and custom_elements:
tinymce.init({
selector: "textarea#editor",
// ...
extended_valid_elements : "emstart,emend",
custom_elements: "emstart,emend",
content_css: "editor.css"
});
create the two images for the opening and the closing tag. I named mine for the example emstart.png and emend.png.
create a custom CSS style for your custom elements and put them in the custom CSS file (the one that is specified in the TinyMCE configuration, in my case editor.css):
emstart {
background: url(emstart.png) no-repeat;
background-position: left -3px top -3px;
padding: 10px 10px 5px 10px;
background-color:#aabbcc;
border:1px dotted #CCCCCC;
height:50px;
width:100px;
}
emend {
background: url(emend.png) no-repeat;
background-position: left -3px bottom -3px;
padding: 5px 10px 10px 10px;
background-color:#aabbcc;
border:1px dotted #CCCCCC;
height:50px;
width:100px;
}
write a custom plugin that inputs the new tags and put it in the plugins directory. I called mine customem:
plugin code:
tinymce.PluginManager.add('customem', function(editor, url) {
// Add a button that opens a window
editor.addButton('customEmElementButton', {
text: 'Custom EM',
icon: false,
onclick: function() {
// Open window
editor.windowManager.open({
title: 'Please input text',
body: [
{type: 'textbox', name: 'description', label: 'Text'}
],
onsubmit: function(e) {
// Insert content when the window form is submitted
editor.insertContent('<emstart>EM Start</emstart><p>' + e.data.description + '</p><emend>EM End</emend>');
}
});
}
});
// Adds a menu item to the tools menu
editor.addMenuItem('customEmElementMenuItem', {
text: 'Custom EM Element',
context: 'tools',
onclick: function() {
editor.insertContent('<emstart>EM Start</emstart><p>Example text!</p><emend>EM End</emend>');
}
});
});
The last step is to load your custom plugin to the editor (using the plugin and toolbar configuration option) and enjoy the result:
tinymce.init({
selector: "textarea#editor",
height: "500px",
plugins: [
"code, preview, contextmenu, image, link, searchreplace, customem"
],
toolbar: "bold italic | example | code | preview | link | searchreplace | customEmElementButton",
contextmenu: "bold italic",
extended_valid_elements : "emstart,emend",
custom_elements: "emstart,emend",
content_css: "editor.css",
});
The editor now looks like this:
and the source like in your example:
First of all you will need to modify the tinymce setting valid_elements and valid_children to your needs (add em to the valid_elements and em as child to the tags desired (probably p) to valid_children).
Second you will need an own plugin with an own drop down or button to insert this code.
You can add one or more tag structures simply using the template plugin.
See documentation
https://www.tiny.cloud/docs/plugins/opensource/template/
See interactive example:
https://codepen.io/gpsblues/pen/WNdLgvb
tinymce.init({
selector: 'textarea#template',
height: 300,
plugins: 'template code',
menubar: 'insert',
toolbar: 'template code',
extended_valid_elements: "emstart[*],emend[*]",
templates : [
{
title: 'emstart/emend',
description: 'Add a personal tag structure with personal tags <emstart></emstart> <emend></emend>.',
content: '<p class="classname"><emstart class="openImg"></emstart>Input text<emend class="closeImg"></emend></p>'
}
],
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px}'
});