PHPWord Footer Position - position

Does anyone know if it is possible to re-position (or set the height of) a footer using PHPWord?
I have a footer exactly as required in terms of text.
$footer = $section->addFooter();
$textrun = $footer->addTextRun();
$textrun->addText('My Footer Text');
However, what I'd like to achieve is to:
Reduce the height of the footer or set the distance from bottom of the page.
There in an option in Word365 called "Footer from bottom", there are also similar options in older versions of Word.
I've tried adjusting the page margins but these appear to be separate from the footer (and header) positioning.

I managed to find a solution by reviewing the GitHub repo.
This commit provides a solution: Added support for page header & page footer height
You can pass the attributes "headerHeight" & "footerHeight" when you create the section that contains your header and footer.
// Adding an empty Section to the document...
$section = $this->_phpWord->addSection(array(
'headerHeight' => 300,
'footerHeight' => 50)
);
$footer = $section->addFooter();
$textrun = $footer->addTextRun();
$textrun->addText('My Footer Text');
There are also some public methods for setting these values after you've created your section, these are: setFooterHeight() and setHeaderHeight().
$section->setHeaderHeight(300);
$section->setFooterHeight(50);

Related

Vue 3 Masonry Layout

Does anyone know of a masonry layout which works with Vue 3 and Server Side rendering?
My requirements is that I can not specify the columns up front, I want the masonry layout to work that out.
In my Vue 2 application I am using "vue-masonry". I had to also use "vue-client-only" as my application as my application is a server rendered application.
<!-- Only rendered during client side rendering, vue-masonry is not support in SSR -->
<client-only>
<div
class="grid"
v-masonry="containerId"
transition-duration="0.3s"
item-selector=".grid-item">
<div
v-masonry-tile class="grid-item"
v-for="(item, i) in items"
v-bind:key="i">
<img
:src="getItemImage(item)"
:data-key=i
alt="Small preview">
</div>
</div>
</client-only>
When I have this in my Vue 3 project I get the error
slot is not a function
I tried to perhaps use "vue-masonry-css" but that fails with
Uncaught TypeError: Cannot read property 'use' of undefined
For the following code
import Vue from 'vue';
import VueMasonry from 'vue-masonry-css';
Vue.use(VueMasonry);
I was also looking for a masonry layout with SSR and Vue 3 support.
Since I couldn't find one for my use case I created https://github.com/DerYeger/vue-masonry-wall.
Check out the demo at https://vue-masonry-wall.yeger.eu/ to see if it fits your requirements.
I have been looking for an answer myself to implement dynamic Masonry layout and nothing worked for me properly so I had to develop my own algorithm for my blog page that support even IE11 and Edge browsers.
1. The grid layout should have the following structure:
<div class="grid-container">
<div class="grid-item">
<div class="grid-item-content"></div>
</div>
</div>
2. style the grid container:
.grid-container {
min-width: 70%;
max-width: 100%;
display: grid;
column-gap: 1rem;
grid-template-columns: repeat( auto-fit, minmax(22em , 1fr));
grid-auto-rows: 300px;
}
.grid-item {
height: fit-content;
/*add the rest of your desired styling properties*/
}
You can change the width of the container and assign it whatever value you want.
The other two important properties from the css snippet above are:
grid-template-columns to generate responsive grid items with minimum width of 22em and max width that equals the width of the grid container 1fr.
grid-auto-rows property that, as the name suggests, gives rows height implicitly. for our masonry layout algorithm to work, I gave the minimum height value that a grid item in my case can have.
3. the following js algorithm will adjust the grid items after they have been loaded to achieve a masonry layout: ##
resizeAllGridItems() {
//calculate the grid container with
let gridWidth = document.getElementsByClassName("grid-container")[0].offsetWidth;
/*calculate the grid item width (the width should be the same for all grid items
because we used `repeat( auto-fit, minmax(22em , 1fr))` to generate our responsive
columns)*/
let gridItemWidth = document.getElementsByClassName("grid-item")[0].offsetWidth;
/*devide the with of the grid container by the with of the grid item item to get
the number of generated columns*/
let columnsNumber = ~~(gridWidth / gridItemWidth);
/*the second part of the algorithm with loop through all the generated grid items.
Starting with the second row, the grid item in that row will be given a `margin
-top` value that equals the height of the grid item situated right above it, minus
the value of `grid-auto-rows`. This way whenever there's an extra space, the grid
item below will have it's `margin-top` value adjusted to take the extra space.*/
let x = columnsNumber;
let colIdx = 0;
let columnsHeights = [0, 0, 0];
let tempColumnsHeights = [];
let allItems = document.getElementsByClassName("grid-item");
for(x; x<allItems.length; x++) {
let topItemHeight = columnsHeights[colIdx] + allItems[x - columnsNumber].offsetHeight;
allItems[x].style.marginTop = (topItemHeight - 300) + 'px';
tempColumnsHeights.push(topItemHeight - 300);
colIdx++;
/*move to the next row of grid items to adjust them if all the items of the
previous row are adjusted*/
if (colIdx === columnsNumber) {
colIdx = 0;
columnsHeights = tempColumnsHeights;
tempColumnsHeights = [];
}
}
}
That's it. Now you have a masonry layout that is made by adjusting the margin top of grid items programatically taking into consideration several variables like the value of auto rows, the height of grid items, their width and the width of the grid container.
I came across several articles that also explain other approaches and algorithms to implement masonry layout but they didn't work for me. This article from css-Trick explains a lot of methods to implement a masonry layout. However I already tried these two other methods but didn't work for me:
the first adjusts the value of grid-row-end according the height of the grid item and it's content to span the grid item by one or more rows.
the second approach is using a third party library like Masonry.
Note if you're using grid items with image elements: I found this article that I tried that uses the imagesLoaded.js library. Using this library will make it possible to execute the algorithm after all the images are loaded. In my case I gave the images container a fixed height that way my articles' cards heights will be independent from the images it contains.
IE11 and Edge support
Use autoprefixer npm package which is a PostCSS plugin to parse CSS and add vendor prefixes to CSS rules using values from Can I Use. It is recommended by Google and used in Twitter and Alibaba. It add all necessary prefixes and parses your grid display properties for IE11 and edge. You can refer to this answer on how to enable grid support with autoprefixer since it's disabled by default: https://stackoverflow.com/a/61144097/8453311
In Vue 3, there's no export global Vue instance like in Vue 2.
As I checked the vue-masonry source code, they using Vue global instance, Vue 2 directive API (breaking change in Vue 3).
So I think have to read and port that library to Vue 3 to make it work.
I run into the same situation and still looking for a library that supports Vue 3.
If I couldn't find any maybe I will port that my self but in the next 2-3 weeks.
Did you try adding Vue Mansory in main.js
like:
import VueMasonry from 'vue-masonry-css'
createApp(App).use(VueMasonry).mount('#app')

Is there a way to change height of tkinter Treeview heading?

I got a problem with changing the height of the Treeview.heading. I have found some answers about the dimensions of Treeview.column, but when I access Treeview.heading in the documentation, there is not a single word about changing the height of the heading dynamically when the text doesn't fit (and wrapping it) or even just hard-coding height of the heading in pixels.
I don't have to split the text to two rows, but when I just keep it that long the whole table (as it has many entries) takes up the whole screen. I want to keep it smaller, therefore I need to split longer entries.
Here is how it looks like:
I can't find any documentation to verify this but it looks like the height of the heading is determined by the heading in the first column.
Reproducing the problem
col_list = ('Name', 'Three\nLine\nHeader', 'Two\nline')
tree = Treeview(parent, columns=col_list[1:])
ix = -1
for col in col_list:
ix += 1
tree.heading(f'#{ix}', text=col)
The fix
col_list = ('Name\n\n', 'Three\nLine\nHeader', 'Two\nline')
or, if you want to make it look prettier
col_list = ('\nName\n', 'Three\nLine\nHeader', 'Two\nline')
The only problem is I haven't figured out how to centre the heading on a two line header
Edit
The newlines work if it is the top level window but not if it is a dialog. Another way of doing this is to set the style. I've got no idea why this works.
style = ttk.Style()
style.configure('Treeview.Heading', foreground='black')
you can use font size to increase the header height for sometimes;
style = ttk.Style()
style.configure('Treeview.Heading', foreground='black', background='white', font=('Arial',25),)

Setting iFrame height programmatically in Dynamics CRM 2011

In Dynamics CRM, how do you set the height of an iframe programmatically? The following function doesn't do anything, the iframe always comes up the same size. Even when you go to iframe properties and change the row numbers there, it still doesn't cause any changes in size.
function doOnLoad(sender, args) {
setIframeHeight();
}
function setIframeHeight() {
//lowest control in iframe
var element = $('btnInsert');
//the following line gets called, and what's displayed is 25
alert(window.parent.parent.frames[0].document.getElementById('IFRAME_TransactionProduct_RA_d').parentNode.height);
//the following line doesn't do anything
window.parent.parent.frames[0].document.getElementById('IFRAME_TransactionProduct_RA_d').parentNode.height = 5000000;
}
you may try this in iframe code:
//set div(show iframe) height = iframe body height * 1.2 window.parent.parent.frames[0].document.getElementById('IFRAME_ApprovalProcess_d').style["height"] = ($(body * 1.2)) + "px";
//but it may get some issue if the contenter in the form not load,so that window.parent.parent.frames[0].document.getElementById('IFRAME_ApprovalProcess_d') this can be undifined.
To get the height of a element you can do like you have but to set you have use style, like that:
parentNode.style.height = "100px";

Issue with CSS width and views columns and headers

I have some CSS I am applying to a view header and view column.
Here is a sample
.viewHeaderName {
width:235px;
background-color:rgb(192,192,192);
color:rgb(0,0,0);
font-family:Trebuchet MS,sans-serif;
font-size:10t;
font-weight:bold;
text-align:left;
}
.viewColumnName {
font-family:Trebuchet MS,sans-serif;
font-size:9pt;
}
Basically I am trying to set the width of the column to what I want. I don't want the text in the header or in the column to wrap. This works perfectly for categorized views for all the columns.
But for simple sorted views, the header is being offset to the right from the text in the column several characters.
If I remove the width parameter in the CSS then everything lines up fine but I don't get the width I want.
you can use td/th nowrap attribute described here
http://www.w3schools.com/tags/att_td_nowrap.asp
or
use white-space element in css described here
http://www.w3schools.com/cssref/pr_text_white-space.asp
white-space:nowrap;

DOJO ContentPane inner DIV height changing on ContentPane resize

I'm using DOJO's ContentPane module. I have a div element in one of the panes and I need to give it a certain height - 100 pixels less than the height of the ContentPane so that the div changes its height dynamically when you change the ContentPane size by dragging the splitters. I'm new to Dojo and would be happy if somebody could help me with this.
Thanks.
I think the best solution is via nested BorderContainers with properly set splitters, because that way dijit/layout will take care of resizing and you won't need to write any JavaScript code and your layout will be based solely on CSS.
It's kinda cumbersome to explain, so I created a working example for you at jsFiddle: http://jsfiddle.net/phusick/Ayg8F/ + a diagram:
NB: Do not forget to set height: 100% for html, body and the top BorderContainer.
The drawback of this solution is you will have to replace plain divs with ContentPanes. If you do not want to or can't you can use dojo/aspect and connect to BorderContainer or ContentPane resize method and resize your divs manually whenever the size changes:
require([
"dojo/ready",
"dojo/aspect",
"dijit/registry",
"dijit/layout/ContentPane",
"dijit/layout/BorderContainer"
], function(
ready,
aspect,
registry
) {
ready(function() {
var bc = registry.byId("borderContainer1");
aspect.after(bc, "resize", function() {
// calculate and set <div> size here
console.log("resize divs");
});
});
});​

Resources