getBoundingClientRect() is returning zero in XUL - dom

I have a problem with my firefox extension
I have a XUL popup panel with a hbox for the tag cloud, and a JS code to add divs to this hbox:
<hbox id="tag_base" ondblclick="alert('done')"/>
JS:
var root = document.getElementById('tag_base');
var tag = document.createElement('div');
tag.textContent = 'test';
root.appendChild(tag);
var rect = tag.getBoundingClientRect()
alert(rect.top)
I need to get the dimensions of each added div, however, getBoundingClientRect simply refuses to work.
If I remove alerts, it's always zero.
With alerts the story is different:
The first time the alert is called it returns zero, although the div appears on the screen.
Any subsequent alerts return the correct coordinates.
If I set a breakpoint in Chromebug, everything is reported correctly.
If I do not interupt the execution in any way, and run a loop, only zeroes got returned.
This has got me quite confused.
Calling "boxObject" produces the same results, while "getClientRects[0]" is undefined on the first call.
Any hints on what might be causing this will be greatly appreciated.

Note :
Caution, if you use getBoundingClientRect with an element which has display:none then it will return 0, anywhere in the dom.

Although I can't find any documentation on this seemingly fundamental issue, the problem you noticed is most likely because the layout (aka "reflow") process has not yet run by the moment you ask for the coordinates.
The layout/reflow process takes the page's DOM with any styles the page has and determines the positions and dimensions of the elements and other portions of the page (you could try to read Notes on HTML reflow, although it's not targeted at web developers and probably is a bit outdated).
This reflow process doesn't run synchronously after any change to the DOM, otherwise code like
elt.style.top = "5px";
elt.style.left = "15px";
would update the layout twice, which is inefficient.
On the other hand, asking for elements position/dimension (at least via .offsetTop) is supposed to force layout to return the correct information. This doesn't happen in your case for some reason and I'm not sure why.
Please create a simple testcase demonstrating the problem and file a bug in bugzilla.mozilla.org (CC me - ***********#gmail.com).
My guess is that this is related to XUL layout, which is less robust than HTML; you could try creating the cloud in an HTML doc in an iframe or at least in a <description> using createElementNS to create real HTML elements instead of xul:div you're creating with your current code.

Be sure the DOM is ready. In my case, even when using the getBoundingClientRect function on click events. The binding of the events needed to happen when the DOM is ready.

Related

How to insert form block in developer mode in Squarespace

I'm working on a Squarespace website in developer mode where I can create the website with code.
In the file site.region, I noticed that I can insert a footer block using this code:
<squarespace:block-field id="footerBlocksMiddle" class="Footer-blocks Footer-blocks--middle sqs-alternate-block-style-container" columns="12" label="{localizedStrings.footerMiddleBlocks}" />
However, I haven't been able to figure out how to insert a form block preferably so that I can set it as email storage.
I tried <squarespace:block-form but that does not work.
The error looks like this on the squarespace configuration page:
"Something went wrong."
How do I write out this code?
What's actually going on in the footer code you mentioned, is that a block field is being inserted. Within that block field, you can add whatever blocks in whatever arrangement you like.
So to accomplish your goal, you'll insert a block field and then add only a form block to it. Then, in other places where you want that form block to appear, you add the block field (containing the form block) into the code.
As long as you use the same id, the same block field will be reused, allowing you to edit the form in whatever area you happen to be in, and changes will affect everywhere else the block field was placed.
<squarespace:block-field id="myFormOnlyBlockField" columns="1"/>
Place that where you want the form block to appear. Of course, initially, you have to add the form block to it and configure it. From then on, adding the code above throughout your site template will show the form, and changing any instance of the block will affect all instances.
Note that I've set 'columns' to '1' in the example above, figuring that you're just adding a single block so no need to have more columns. you could set it to something else and it'd work just as well. Also note that the areas where you add the block field might have a bit too much spacing/padding/margin around it, so you may need to CSS to adjust for that.
Alternatively, it is possible to execute JavaScript within a code block to make an AJAX/Fetch request to the page with the form block on it, and have that form block replace the code block within which the JavaScript is executed. Such an approach would work even without developer mode.

Correctly generate an HTML table with a forEach loop in EJS while using a MongoDB cursor object?

I'm new to the MEAN stack and I'm having trouble printing out an HTML table using EJS.
Basically, I have an EJS tag that stays white inside of VS Code and I have no idea why (line 14).
I have two forEach loops, the first one on line 6 outputs my mongoDB cursor results correctly. However, the second forEach loop with the HTML does not work because I cannot close my EJS tag for some reason and it breaks everything from that place down.
How do you correctly generate an HTML table with a forEach loop in EJS while using a MongoDB cursor object?
Just in case you want to see how I am getting my data (the console.logs can be seen in the first image):
I changed the app.get block of code to:
I think the main difference is that I put the response.render code inside of the .find() method ? I believe the comment Jeff made has the truth behind it. I don't fully understand it yet, but I know now that you want to pass the query object inside of the .find() method now. I also still don't know why I could console.log, but not embed HTML before the fix. That is strange, however, by putting the response in the .find(), I can do both now. Go figure.
One note, the syntax highlighting is still messed up in the ejs on the right panel, but it comes out clean in the browser now. Here is the rest of the code and some screen shots:

cakephp element not displaying

I have a number of form inputs inside an element as they are repeated in other forms, however it does not output the content of the element when i include it in a view. I can place "Die();" within the element and it will show everything up until that point including the inputs within the element. When checking the source code (without the "Die();") it seems to have disregarded everything within the element including formatting such as DIV's.
The only thing i can think is that cakephp does not like you setting a form in a view then including inputs to the form using elements, does any one know if this is the case, or know the actual reason why this is happening?
The answer is i'm an idiot and forgot to echo the element.... yeah.

Use Template on Invisible Table for inserting into existing bound sap.m.Table

Excuse the confusing language but hopefully this makes sense: (see code for more clear explanation)
I have a requirement to display a list of "spare parts" in an sap.m.Table but there is the ability if one of these "spare parts" has a related "spare part" (e.g. A heavy duty version, a light version, etc) , that you can click a button on the row and display these related "spare parts" by inserting them immediately below the "spare part" in question.
While I can get the sap.m.Table doing what I want to do, I would like to take advantage of templates and binding to create a temporary sap.m.Table; bind it to the relationship that returns these alternate spare parts; and reuse the template for a row to give me an array of ColumnListItems which I can insert into the Table at the right place.
Unfortunately, doing this, a sap.m.Table has a feature that if it is not displayed, it doesn't actually make the Odata call and leverage the template function.
To explain possibly much clearer, refer to this jsbin:
http://jsbin.com/sihofu/4/edit?html,js,output
Any better ideas on how to generate template output for a binding without using a sap.m.Table; or alternative, getting the sap.m.Table to make the call without placing it on the screen visible (temporarily)?
The specific code to look at is as follows:
var oTable2 = new sap.m.Table();
oTable2.attachUpdateFinished(function() {
console.log("But this one doesn't");
// What I'm trying to do here is insert these entries below Key 1
});
oTable2.bindAggregation("items", {
path: "/ExampleSecondaryValues",
template: oTemplate,
});
Thanks,
Matt
Back from Holidays now and solved this problem with a bit of brute force by simply enhancing/extending the sap.m.table control slightly.
The problem was if the control was invisible, nothing was rendered, and some optimisation within UI5 core means that in the case nothing is rendered, the AfterRender event is not called on the control and this event is what fires the UpdateFinished event.
I won't debate whether that optimisation is appropriate or not, but to fix this I simply extended the table control with a new control which looks like as follows:
sap.m.Table.extend("my.InvisibleTable", {
renderer: function(oRm, oControl) {
oRm.write("<span");
oRm.writeControlData(oControl);
oRm.write("></span>");
}
});
e.g. Simply always rendering something in the render function, causes the AfterRender event to be called; which in turns allows the sap.m.Table to fire the UpdateFinished event which allows me to then safely get the rendered template items to insert in my visible table.
Would love to know a much better way of doing this (possibly using the template control or similar), but this works okay to solve the problem.
Cheers,
Matt

Save the annotation marks in flexpaper annotation document viewer

How to save the annotation marks in flexpaper annotation document viewer?
Thanks.
FlexPaper provides a JavaScript function called getMarkList:
marksArray = JSON.stringify($FlexPaper('documentViewer').getMarkList());
You can apply the annotations again using addMarks:
var initialMarks = JSON.parse(marksArray);
$FlexPaper('documentViewer').addMarks(initialMarks);
This works for the HTML5 version but I suspect it would also apply to the Flash and HTML versions.
Ok, so I think I've found a bug in Flexpaper that prevents this from being useful (bug is in the Flash version, have not tested HTML version). If anyone has actually got this to work on Flash, please let me know!
Basically, addMark() is performing an unnecessary coordinate transformation which makes it impossible to put back in a mark that you have extracted in the same spot (this only seems to be the case for notes, drawings don't seem to have this issue).
Here's how to reproduce:
Go to http://devaldi.com/annotations/UK_Investment_Fund.php?ro=flash,html and open Chrome JS console. Enter these commands:
>> note = $FlexPaper('documentViewer').getMarkList()[2]
Object {width: 200, pageIndex: 1, height: 180, note: "The annotations plug-in allows both highlighting a…created↵↵Notes can be resized, moved and deleted.", id: "3AFE17A3-4977-3ECA-C468-70F2C40B81E8"…}
>> // Now try to add back in the same annotation
>> $FlexPaper('documentViewer').addMark(note)
>> // Notice that on the screen the note is in the wrong spot
>> // (not the same spot as the original one). Lets check the positioning
>> added_note = $FlexPaper('documentViewer').getMarkList()[6]
>> added_note.positionX
356.718192627824
>> note.positionX
-5.945303210463702
The normalize/denormalization of positions should work fine as long as you set 'displayFormat' to 'html' as part of your object creation. The normalisation process basically adjusts X/Y/Width/Height so that the document is considered to be 1000 in height. The viewer then adjusts the positions when the annotations are being displayed if the document is different in height for flash or html. It also of course considers the proportions of the width/height of the document as part of this process.
All the best
Erik on the FlexPaper Team