div automatic height is too small for content - html

I have a situation where I have a report that is normally displayed in a jsp, and now I have a print where those multiple instances of said page needs to be included multiple times, so this is a combined report kind of thing. To circumvent issues that would arise from adding values to the model with the same key we came up with this way to include the jsp.
<c:forEach var="prodTest" items="${listProductionTest}">
<div style="display:block" id="chargeReport${prodTest.report.recId}">
</div>
<script type="text/javascript">
$.get("ChargeReportContent?recId=${prodTest.report.recId}", function( data ) {
$("#chargeReport${prodTest.report.recId}").html(data);
});
</script>
ChargeReportContent is an endpoint that returns the jsp with the values. It retrieves data correctly however the divs height is all wrong causing the both reports to overlap. It seems auto height gives itself enough height to only include the first part of the report.
display block doesnt seem to work. These reports should each have size of around 1500px but putting the height as a fixed value is not really an option as the size can change depending on the report or updates.
Plz help!

what's the position of the elements inside the div?
Make sure they are not fixed, absolute or have float set.
Divs are set to display block by default, you might try to set it to flex

A colleague suggested that this is because the html was filled programmatically, the size was not accurate. We never figured out a clean way to fix this, but the best we came up with is to calculate the needed height ourselves and then set it. For example
the title is always 92px, recipe is always 256px, Reportlines size= 42+(21(materials+1)), notes part is 23px if there are no notes, 42 if there is a note, etc.
if in the JSP we could not easily retrieve a number of Alarms we made an invisible input to store the value and is added by the model like
<input id="alarmCounter${report.recId}" style="display: none" value="${alarmCount}"></input>
and then we retrieve the val to use it in the calculation.
After we find the total we just set it in the get that gets the included page
$.get("ChargeReport?recId=${prodTest.report.recId}", function( data ) {
$("#chargeReport${prodTest.report.recId}").html(data);
let alarmCount = 0;
alarmCount =parseInt($('#alarmCounter${prodTest.report.recId}').val());
var chartsize = 400*($('#chartExists${prodTest.report.recId}').val() == 'true' ? 1 : 0)
var pixelsNeeded= 92 + 256 + 205
+ 42+ 21*(${fn:length(prodTest.report.reportLines)}+1)
+ 21*(alarmCount+2)
+19+24*${!empty prodTest.report.comment}
+ chartsize + 51
+50;
$('#chargeReport${prodTest.report.recId}').css("height",pixelsNeeded+"px");

Related

What is the problem with my JS function searching html classes and conditionally hiding or showing?

I am trying to modify a Dawn 2.0 theme to, on the product page, only render images with certain tags depending on an input selector. I have one product which consists of 8 items, each item has an image. This product can be ordered in three variations:
The first variation would be the product with 4 items.
The second variation would be the product with 6 items.
The third variation would be the product with 8 items.
There is a variant selector in the products page:
and the three variants have been created on the Shopify admin products page. The solution that I'm attempting to use is this one. I chose it as it's the only one I found reference to elsewhere (apart from buying an add on which I don't want to do), it seemed a logical approach to me, though I have no particular loyalty to this approach if anyone can think of a better way to achieve what I'm trying to.
This solution involves using values assigned to image's alt text attribute via the Shopify admin products page. The alt text values applied are:
set_all for the first 4 images, because these 4 items would be included in all three of variants (the one with only x4 itmes, the one with x6 items, and the one with x8 items).
set_6&8 for the 5th and 6th images, because these 2 items would be included in both the 2nd variant (the one with x6 items) and the 3rd variant (the one with x8 items).
set_8 for the 7th and 8th images, because these 2 items would only be included in the 3rd variant (the one with x8 items)
Then interpolating that alt text value into a data tag in the html:
data-thumbnail-set-number="{{media.alt}}"
which is applied to the <li> that each image is housed within and then writing a js function which:
hides all images
stores in local variable the alt text value of the featured image ('featured image' being the one, and only, image that you can apply to each variant in the Shopify admin products page. Therefore if the user selects a different variant a different featured image with different alt text is attached to that variant).
shows the images whose data-thumbnail-set-number value matches the value from the variant's featured_image.alt text. JS being:
'./assets/global.js' in VariantSelects class, line ~561
onVariantChange() {
...
this.filterThumbnails();
...
};
filterThumbnails() {
if (this.currentVariant.featured_media != null && this.currentVariant.featured_media.alt != null) {
document.querySelectorAll('[data-thumbnail-set-number]').forEach(function(el) {
el.style.display = 'none';
});
// show thumbnails for selected set
var selected_set = this.currentVariant.featured_media.alt;
document.querySelectorAll('[data-thumbnail-set-number="' + selected_set + '"]').forEach(function(el) {
el.style.display = 'block';
});
}
else {
//show all thumbnails
document.querySelectorAll('[data-thumbnail-set-number]').forEach(function(el) {
el.style.display = 'block';
});
}
// console.log("thumbnail update", this.currentVariant.featured_media.alt)
}
This all works apart from two problems:
I need to write further conditions in the JS to not just match the featured_image.alt text but to also include:
the set_all images as those items come with all 3 variations, and for the set_8 variant to include the set_6&8 images. I should be able to deal with this fine, will probably hard code the data-thumbnail-set-number that each three conditional is looking for.
Even though the JS function seems to be effective at searching and showing the images with a data-thumbnail-set-number value that matches the variant's featured image alt text value, the page also always seems to render one other image, which does not have the data-thumbnail-set-number class applied to the <li> at all, and it seems that that image is always the first of the images saved to the main product.
Despite a good deal of time looking I can't seem to understand why issue 2. is happening, and how to stop it. Can anybody help me solve this?
PEBCAK 🥴
To solve issue 2, I found that another <li> is inserted in the main-product.liquid above the <li> which iterates and shows all images in the image colleciton just to show just the featured image. I don't really understand why this featured image is separated out for rendering apart from the others in the collection, but it it. I just needed to add the data-thumbnail-set-number="{{media.alt}}" into this newly found featured image <li>.
As i took some time to write out this question I thought that I'd leave it here in case it's of help to anyone else.

Scroll to table row or list item in an Angular app

In the code snapshot below in app.component.html, I display clickable rows in a table in Lines 39 to 58. Once the user clicks a row, I display other relevant rows in a table named suraTable as shown in Lines 63 to 77. Namely, when the user clicks on a row, the function onSelectAya(aya, suraTable) in app.component.ts is called. That function loads the necessary rows and the table is displayed.
What I am stuck with is this. Suppose suraTable ends up with 100 rows. The current behaviour is that rows 1, 2, 3... are displayed of course. I need to be able to show the table at Row 50 say (information carried in the parameter aya on Line 91). How do I scroll to that position? I tried the scrollTop way but when checking the values before and after the setting of suraTable.scrollTop, the value is always 0 (0 pixels that is). Line 100 shows that when console.log(suraTable) is reached, expected output is generated in the browser, which means that I am getting hold of the element correctly to start with.
So, how do I scroll to a specific row in a table, or to an item in a list (I could convert the whole structure to a list if easier) from within the app.component.ts component? Thank you.
<mat-row id="{{task.taskId}}"
*matRowDef='let task; columns: columnsReadyTask;let i = index;'></mat-row>
if working with datasources, you will need some delay after getting element on the page with id...
setTimeout(() => {
const selectedRow = document.getElementById(taskId);
if(selectedRow) {
selectedRow.scrollIntoView({block: 'center'});
}
}, 500);
This may not work on old browsers.
If this is simply a scrolling thing, you could add specific id to your rows so you can know theyr number, and then do
var elmnt = document.getElementById("rowNumber"+rowNumber);
elmnt.scrollIntoView();
If when the scrolling is taking part your element is not rendered on DOM, try adding a callback for when that rendering is finished. If that is not possible, maybe a setTimeout can do.

(AS3) Getting an HTML-specific character index in a textfield after word wrap

I didn't know how to phrase the title, so sorry about that. If you have a better title suggestion, let me know and I'll change it.
I've got a chunk of text that is displayed as HTML in a TextField. An example of this text is this:
1
<font size="30" color="#FF0000">When your only tool is a hammer, all problems start looking like nails.</font>
</br>
2
<i>99 percent of lawyers give the rest a bad name.</i>
<b>Artificial intelligence is no match for natural stupidity.</b>
<u>The last thing I want to do is insult you. But it IS on the list.</u>
</br>
3<showimage=Images/image1.jpg>
I don't have a solution, but I do admire the problem.
The only substitute for good manners is fast reflexes.
Support bacteria - they're the only culture some people have.
</br>
4
Letting the cat out of the bag is a whole lot easier than putting it back in.
Well, here I am! What are your other two wishes?
Most of the tags are basic, meant to display what I can do formatting wise. However, since Adobe Air has a sandbox that prevents inline images (via the <img src='foo.png'> tag), I've had to come up with another way to display images.
Basically, I intend on having an image displayed somewhere on the screen, and as the user scrolls the image will change based on where in the text they have scrolled to. The image can be a background image, a slideshow on the right, anything really.
In the snippet above, look for my custom tag <showimage=Images/image1.jpg>. I want to get the local y position of that tag once the TextField is rendered as HTML and word wrapped. The trouble is, when I query the y position of the tag (using getCharBoundaries), I can only either search for the tag when I render the text as a .text instead of a .htmlText. If I search for the tag in the TextField after rendering it as .htmlText, it doesn't get found because the tags are hidden and replaced with formatting.
The trouble with the y value I get before rendering the HTML is that the y value will be different due to font sizes, tags being hidden and word wrap changing the line and y value that the tag is located at.
How do I get the correct y value of an HTML tag once the HTML has been rendered?
I've considered using a different style tag, maybe something like &&&&&showImage=Images/image1.jpg&&&&, but that seems like a cop-out and I'd still run into problems if multiple of those tags were in a block of text and the tags were removed, followed by word wrap that shifts lines in a pretty unpredictable way.
myTextField.textHeight tells you the height of the text in pixels. So you can split the string on whatever you're looking for, put the text before your target in the textField and get the textHeight, then put the rest of the text in.
Here's some example code - tMain is the name of the textField:
var iTextHeight: int = 0;
var sText: String = '<font size="30" color="#FF0000">When your only tool is a hammer, all problems start looking like nails.</font></br><i>99 percent of lawyers give the rest a bad name.</i><b>Artificial intelligence is no match for natural stupidity.</b><u>The last thing I want to do is insult you. But it IS on the list.</u></br><showimage=Images/image1.jpg> I don\'t have a solution, but I do admire the problem. The only substitute for good manners is fast reflexes. Support bacteria - they\'re the only culture some people have. </br>Letting the cat out of the bag is a whole lot easier than putting it back in. Well, here I am! What are your other two wishes?';
var aStringParts: Array = sText.split("<showimage=Images/image1.jpg>");
for (var i = 0; i < aStringParts.length; i++) {
if (i == 0) {
tMain.htmlText = aStringParts[i];
trace("height of text: " + tMain.textHeight);
} else {
tMain.appendText(aStringParts[i]);
}
}
sText gets split on the tag you're looking for (removes the text you're looking for and breaks remaining text into an array). The text leading up to the tag is put in the textField and the textHeight is traced. Then the rest of the text is put in the textField. This gives you the y pixel number you need to arrange things.
Let me know of any questions you have.
Instead of going through the trouble of parsing your image tag, have you tried playing with HTMLLoader and using the loadString method? This should load everything in its proper place including the image using the img tag.
private var htmlLoader:HTMLLoader;
private function loadHtml(content:String):void
{
htmlLoader = new HTMLLoader(); //Constructor
htmlLoader.addEventListener(Event.COMPLETE, handleHtmlLoadComplete); //Handle complete
htmlLoader.loadString(content); //Load html from string
}
private function handleHtmlLoadComplete(e:Event):void
{
htmlLoader.removeEventListener(Event.COMPLETE, handleHtmlLoadComplete); //Always remove event listeners!
htmlLoader.width = htmlLoader.contentWidth; //Set width and height container
htmlLoader.height = htmlLoader.contentHeight;
addChild(htmlLoader); //Add to stage
}
Another approach is to search your html string for <showImage ..> tags and replace these with shortcodes e.g [showImage ..] , before inserting the htmlString in a textField. Then this is NOT xml but text and you can retrieve the y value (that is if i understand correctly your issue).
Then the rest of your code can take it from there.
(ps using HtmlLoader seems nice alternative though)

DOMPDF How to make PDFs height automatic

I'm afraid that this question does not have an answer, but here it goes.
What I am trying to do is get people to fill in various information about them selves in my website, and echo all of it in a HTML template file (which gets converted into PDF later). Since all users have variable amounts of entries and entry lengths, it's impossible to predict the end result height of the document.
In other words: the more info a user gives about them selves, the higher in size the document gets. And there is no way to set DOMPDF to generate PDF heights according to the end result of the HTML template.
Am I missing a solution right under my nose here?
There is not a built-in way to do this, but that doesn't mean it is not possible. You happen to be the second person to ask this and that first time I did manage come up with a way it can be done.
The following comes from an original post on the dompdf support group.
First, you need to make a minor modification to the stylesheet of your document. You want to set the top and bottom page margins to zero so they don't add in to the height calculation. So in your first-pass HTML add the following additional style declaration:
#page { margin-top: 0px; margin-bottom: 0px; }
Next, you have to determine what the best first-pass document size will be. I was using a simple document, so I went with a simple 8cm x 8cm page size. You'll probably want to use a larger height to avoid any bugs related to paging. 8cm is roughly 226.77pt. So I set up the first pass to use a document defined with the appropriate dimensions:
$dompdf = new DOMPDF( );
$dompdf->set_paper( array( 0 , 0 , 226.77 , 226.77 ) );
$dompdf->load_html( $first_pass_html );
$dompdf->render( );
Then we get the number of pages that resulted from this pass and unset the $dompdf variable so we can do our second pass:
$page_count = $dompdf->get_canvas( )->get_page_number( );
unset( $dompdf );
Finally, render the document a second time using a page height calculated from the page height used in the first pass multiplied by the number of pages generated (plus a little extra padding to accommodate margins).
$dompdf = new DOMPDF( );
$dompdf->set_paper( array( 0 , 0 , 226.77 , 226.77 * $page_count + 20 ) );
$dompdf->load_html( $original_html );
$dompdf->render( );
$dompdf->stream( 'sample.pdf' , array( 'Attachment' => 0 ) );

more minimaler cubism.js horizon chart from json example

Following up on a previous question... I've got my minimal horizon chart example much more minimaler than before ( minimal cubism.js horizon chart example (TypeError: callback is not a function) )
<body>
<div class="mag"></div>
<script type="text/javascript">
var myContext = cubism.context();
var myMetr = myContext.metric(function(start, stop, step, callback) {
d3.json("../json/600s.json.php?t0=" + start/1000 + "&t1=" + stop/1000 + "&ss=" + step/1000, function(er, dt) {
if (!dt) return callback(new Error("unable to load data, or has NaNs"));
callback(null, dt.val);
});
});
var myHoriz = myContext.horizon()
.metric(myMetr);
d3.select(".mag")
.call(myHoriz);
</script>
</body>
The d3.json() bit calls a server side .php that I've written that returns a .json version of my measurements. The .php takes the start, stop, step (which cubism's context.metric() uses) as the t0, t1, and ss items in its http query string and sends back a .json file. The divides by 1000 are because I made my .php expect parameters in s, not ms. And the dt.val is because the actual array of my measurements is in the "val" member of the json output, e.g.
{
"other":"unused members...",
"n":5,
"val":[
22292.078125,
22292.03515625,
22292.005859375,
22292.02734375,
22292.021484375
]
}
The problem is, now that I've got it pared down to (I think) the bare minimum, AND I actually understand all of it instead of just pasting from other examples and hoping for the best (in which scenario, most things I try to change just break things instead of improving them), I need to start adding parameters and functions back to make it visually more useful.
Two problems first of all are, this measurement hovers all day around 22,300, and only varies +/- 10 maybe all day, so the graph is just a solid green rectangle, AND the label just says constantly "22k".
I've fixed the label with .format(d3.format(".3f")) (versus the default .2s which uses SI metric prefixes, thus the "22k" above).
What I can't figure out is how to use either axis, scale, extent, or what, so that this only shows a range of numbers that are relevant to the viewer. I don't actually care about the positive-green and negative-blue and darkening colours aspects of the horizon chart. I just used it as proof-of-concept to get the constantly-shifting window of measurements from my .json data source, but the part I really need to keep is the serverDelay, step, size, and such features of cubism.js that intelligently grab the initial window of data, and incrementally grab more via the .json requests.
So how do I keep the cubism bits I need, but usefully change my all-22300s graph to show the important +/- 10 units?
update re Scott Cameron's suggestion of horizon.extent([22315, 22320])... yes I had tried that and it had zero effect. Other things I've changed so far from "minimal" above...
var myHoriz = myContext.horizon()
.metric(myMetr)
.format(d3.format(".2f"))
.height(100)
.title("base1 (m): ")
.colors(["#08519c", "#006d2c"])
// .extent([22315, 22320]) // no effect with or without this line
;
I was able to improve the graph by using metric.subtract inserting it above the myHoriz line like so: (but it made the numerical label useless now):
var myMetr2 = myMetr.subtract(22315);
var myHoriz = myContext.horizon()
.metric(myMetr2)
.format...(continue as above)
All the examples seem so concise and expressive and work fine verbatim but so many of the tweaks I try to make to them seem to backfire, I'm not sure why that is. And similarly when I refer to the API wiki... maybe 4 out of 5 things I use from the API work immediately, but then I always seem to hit one that seems to have no effect, or breaks the chart completely. I'm not sure I've wrapped my head around how so many of the parameters being passed around are actually functions, for one thing.
Next hurdles after this scale/extent question, will be getting the horizontal time axis back (after having chopped it out to make things more minimal and easier to understand), and switching this from an area-looking graph to more of a line graph.
Anyway, all direction and suggestion appreciated.
Here's the one with the better vertical scale, but now the numerical label isn't what I want:
Have you tried horizon.extent? It lets you specify the [min, max] value for the horizon chart. By default, a linear scale will be created to map values within the extent to the pixels within the chart's height (specified with `horizon.height or default to 30 pixels).