Svelte {#await}..{:then} block duplicating html with new data - async-await

I'm trying to use Sveltes {#await}..{:then} block to show NASA's image of the day but I'm getting a strange intermittent outcome. On the first page load the image and data loads in just fine. When I change the date using the date-picker on the page, it's supposed to replace the current image and description with the image and description for the selected date that is retrieved asynchronously. However, what's happening is sometimes the html with the new data just get's appended to the bottom of the page so the image and description for the previously selected date is still there.
Can anyone tell me how I can make sure the previous data is removed? Or could this be some kind of race condition?
<script>
import { fade } from 'svelte/transition';
import Loader from '../components/Loader.svelte';
import {getContext} from 'svelte';
import { format, parseISO } from 'date-fns'
let todaysDate = format(new Date(), 'y-MM-dd');
let selectedDate = todaysDate;
async function getPhotoOfTheDay() {
let data = "";
if (selectedDate !== todaysDate) {
let response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=` + selectedDate);
data = await response.json();
} else {
console.log("use in memory data");
data = getContext('dailyImage');
}
return data;
}
$: imageData = getPhotoOfTheDay(selectedDate);
$: formattedDate = format(parseISO(selectedDate), 'MMMM d, y')
</script>
<svelte:head>
<title>All About Space: Photo of the day</title>
</svelte:head>
<div id="content">
<h1>Photo of the day on {formattedDate}</h1>
<p class="instructions">Choose a day to see the photo of the day for that date:
<input type="date" bind:value="{selectedDate}" max="{todaysDate}" >
</p>
{#if imageData===""}
<p>error.. no data for the selected date</p>
{:else}
{#await imageData}
<Loader show="true"/>
{:then image}
<div class="image-result" transition:fade="{{duration: 300}}">
<h2>{image.title}</h2>
<p>
<img src="{image.url}" alt="{image.title}" title="{image.title}"/>
{image.explanation}
</p>
</div>
{:catch error}
{error.message}
{/await}
{/if}
</div>
<style lang="stylus">
#content {
background: rgba(0,0,0,0.8);
backdrop-filter: blur(6px);
border-radius: 5px;
width: 75%;
margin: 0 auto;
padding: 1rem 2rem;
&:after {
clear: both;
content: "";
display: block;
width: 100%;
}
}
.instructions {
border-bottom: 1px solid gray;
padding-bottom: 2rem;
}
input {
padding: 0.5rem 1rem;
font-size: 1rem;
cursor: pointer;
border: 0;
border-radius: 3px;
}
img {
float: left;
padding: 0 1rem 1rem 0;
max-width: 50%;
}
</style>

There is an active bug for transitions in await blocks. It seems to be your issue: https://github.com/sveltejs/svelte/issues/1591

Related

How can I use a unique image as modal content with HTML/CSS/JS?

I would like it if you clicked on one image, another image would pop up as a modal. I would like the modal content to be a separate image from the trigger, but I borrowed this code from W3Schools and it is written for the same image.
I have tried putting a different image file as src in line 4 with modal-content (id=img01). I have tried changing the var img in line 8 to "img01". I have played around with those two lines in different combinations, but no luck.
I tried to make this as concise as possible, but not entirely sure which parts are the issue, so please forgive any extraneous code, and I can give more if you suspect there is something I'm not including.
Any help is greatly appreciated!!! :)
HTML
<img id="myImg" src="graphic.jpeg" alt="">
<div id="myModal" class="modal"> <span class="close">×</span>
<img class="modal-content" id="img01"> </div>
JS
var modal = document.getElementById('myModal');
var img = document.getElementById('myImg');
var modalImg = document.getElementById("img01");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
}
var span = document.getElementsByClassName("close")\[0\];
span.onclick = function() {
modal.style.display = "none";
}
CSS
img {
padding: 0;
display: block;
margin: 0 auto;
max-height: 100%;
max-width: 100%;
}
#img01 {
height: 100%;
width: auto;
}
#myImg {
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
}
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.9);
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
Modal image content is loaded in JS line modalImg.src = this.src.
Try modalImg.src = "sample/url"; instead of that.

Is it possible to determine number of children of any container using any SASS function?

Is it possible to determine number of children of any container using any SASS function?
For example, I have a container which has 3 columns:
<div class="columns columns_3">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
For this container, I want to implement a mixin which is +columns_3
But if the container has nth number of children, mixin will be +columns_n
What you want is to know how many childs haves an element and set the right class to it.
You need Javascript to detect the number of childs, HTML and CSS.
SCSS
.element {
$width: 100%;
width: $width;
div {
height: 100px;
float: left;
border:1px solid #000;
box-sizing: border-box;
}
#for $i from 1 through 12 {
&--#{$i} div {
width: $width/$i;
}
}
}
var element = document.getElementsByClassName('element')[0];
var childs = element.childElementCount;
element.classList.add("element--"+childs);
.element {
width: 100%;
}
.element div {
height: 100px;
float: left;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.element--4 div {
width: 25%;
}
<div class="element">
<!-- childs -->
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Well if you have a range, you could potentially use a for loop - depending what you need to do. For example:
$gridWidth = 100%;
#for $numItems from 1 through 12 {
.columns_#{$numItems} {
.column {
width: $gridWidth / $numItems;
}
}
}
I think you can make this :
#function number(val) { #return val };
#mixins +columns_#{number(10)} {
// Your code;
}
I'm not sure I understand what you explain.

SVG in css pseudo-class does not alway appear on print page

I am creating a stylesheet for print media that includes an inline SVG as the content of an element's pseudo-class (i.e., ::before, ::after).
When testing in Chrome, it seems to work just fine, but when the page is first loaded in Firefox and Safari, the SVG element does not appear in the print preview. It then appears on all subsequent attempts.
I am not exactly sure what is going on, but if I had to guess, my conjecture would be: when page hasn't been cached there is latency rendering the pseudo-element that is happening concurrently to the browser creating the print page.
I am very curious to know why this is happening, and if there is any solution where an SVG pseudo-element can be used reliably.
Here is a stripped down code example. Please see if you can reproduce this issue:
var button = document.querySelector('button');
button.addEventListener('click', function () {
window.print();
});
div {
text-align: center;
}
button {
margin: 2em;
padding: 1em 2em;
}
#media print {
button {
display: none;
}
div::before {
content: 'Pseudo-elements';
font-weight: bold;
margin-top: 1em;
}
div::after {
position: relative;
display: block;
margin-top: 1em;
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><circle cx='50' cy='50' r='50' /></svg>");
}
}
<div>
<button>
print
</button>
</div>
I can repro.
It seems to be a bug with the loading of the svg, I guess it would be the same with any image.
One workaround is to load it outside of your #print rules with display: none :
var button = document.querySelector('button');
button.addEventListener('click', function() {
window.print();
});
div {
text-align: center;
}
button {
margin: 2em;
padding: 1em 2em;
}
div::after {
display: none;
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><circle cx='50' cy='50' r='50' /></svg>");
}
#media print {
button {
display: none;
}
div::before {
content: 'Pseudo-elements';
font-weight: bold;
margin-top: 1em;
}
div::after {
opacity: 1;
position: relative;
display: block;
margin-top: 1em;
}
}
<div>
<button>
print
</button>
</div>
An other one would be to preload it via js before hand.

dompdf: top-margin after page break not working

I'm experimenting with Wordpress and (the recent version of) dompdf at the moment and ran into an annoying problem regarding the formating.
My Problem: The top-margin of the main content seems not to be considered on the second page generated, resulting in an overlapping with my logo. You can view the generated PDF under this link.
The relevant code from which the PDF is generated reads as follows (it is not perfect yet as i want to resolve the issue first):
function ppt_pdf_output() {
// post-ID of referring page needed
$post=get_post($_POST['postid']);
$output = '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>'.$post->post_title.'</title>
<style>
body {
margin: 30px 0 0 0;
font-family:sans-serif;
text-align:left;
}
img {
margin: 15px 0;
}
#header,
#footer {
position: fixed;
left: 0;
right: 0;
color: #aaa;
font-size: 0.9em;
line-height:1.2em;
}
#header {
top: -30px;
/*border-bottom: 0.1pt solid #aaa;*/
}
#footer {
bottom: 0;
border-top: 0.1pt solid #aaa;
}
#header table,
#footer table {
width: 100%;
border-collapse: collapse;
border: none;
text-align: center;
color: #000;
font-size: 24px;
}
.entry-content {
margin: 100px auto 35px auto;
top: 0; left: 0; bottom: 0; right: 0;
background-color: #d1d977;
width:90%; height:auto;
}
.entry-title {
font-size: 18px;
text-align: center;
}
#header td,
#footer td {
padding: 0;
width: 50%;
}
#footer .page-number {
text-align: center;
}
.page-number:before {
content: "Seite " counter(page);
}
.gallery-item {
display:inline-block;
}
br[style] {
display:none;
}
.gallery + p {
clear:left;
}
</style>
</head>
<body><div id="header">
<table>
<tr>
<td>ANTRAG</td>
<td style="text-align: right;"><img src="path/to/logo.png" /></td>
</tr>
</table>
</div>
<div id="footer">
<div class="page-number"></div>
</div>';
$output .='
<!--<h1 class="entry-title">'. $post->post_title .'</h1>-->
<div class="entry-content">' .
apply_filters('the_content',$post->post_content) . '</div>';
$output .= '</body></html>';
return $output;
}
As you can see, the formatting on the first page is as it should be (or at least as I intended it to be), but after the page break the content area (for visualization reasons provided with a green background) just starts at the beginning of the page, regardless of which number I give the margin.
Has anybody an idea how to resolve this issue? I've been working on this for countless hours and just don't know what to do at this point.
Any help would be greatly appreciated.
Kind regards
Olli
UPDATE: Of course I found this solution only just. I will try this and see if I can get the issue resolved with this.
UPDATE2: Still no luck. I'm now stuck with the following code (the output can be found under the link provided earlier):
function ppt_pdf_output() {
// post-ID of referring page needed
$post=get_post($_POST['postid']);
$output = '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>'.$post->post_title.'</title>
<style>
#page {
margin: 120px 50px 80px 50px;}
#header {
position: fixed;
top: -82px;
width: 100%;
height: 109px;
background: #aaa url("path/to/logo.png") no-repeat right;
}
#content {
width: 100%;
height: 85%;
background-color: #d1d977;
}
footer {
position: fixed;
bottom: -65px;
height: 30px;
background-color: #333399;
}
footer .page-number {
text-align: center;
}
.page-number:before {
content: "Seite " counter(page);
}
br[style] {
display:none;
}
</style>
</head>
<body><div id="header">
<h2>ANTRAG</h2>
</div>
<footer>
<div class="page-number"></div>
</footer>';
$output .='<h1>'. $post->post_title .'</h1>
<div id="content">' .
apply_filters('the_content',$post->post_content) . '</div>';
$output .= '</body></html>';
return $output;
}
It seems just so fragile. For example, as soon as I change the font-size of the h1 element, it gets overlapped by the logo. After the page break, it looks okay, but that just seems an coincidence - as soon as I change the font-size or the text, the text again gets overlapped. Will absolute positioning change anything or do you have any other tipps as how to resolve this anoying issue? Margins of any kind don't seem to work either.
You're on the right track. As you've seen, when an element is split across pages (as your content area is) some of the formatting information does not follow. This is by design.
The correct tact is to define the page margins so that they are large enough to hold your header/footer content and place the header/footer into that space. The content will then just fill the "body" of the document (i.e. the space inside the page margins). This is what you've attempted, but you haven't given enough space for the header. The header is positioned 82px inside the page margin but the height of the header is 109px. Because of this any content that has a small margin will still fall under the header.
Try this instead:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>"Kaffeefahrten" in Bornheim: hart durchgreifen, Senioren vor Betrügern schützen</title>
<style>
#page {
margin: 120px 50px 80px 50px;
}
#header {
position: fixed;
top: -115px;
width: 100%;
height: 109px;
background: #aaa url("path/to/logo.png") no-repeat right;
}
#content {
background-color: #d1d977;
}
footer {
position: fixed;
bottom: -65px;
height: 30px;
background-color: #333399;
}
footer .page-number {
text-align: center;
}
.page-number:before {
content: "Seite " counter(page);
}
br[style] {
display:none;
}
</style>
</head>
<body>
<div id="header">
<h2>ANTRAG</h2>
</div>
<footer>
<div class="page-number"></div>
</footer>
<h1>"Kaffeefahrten" in Bornheim: hart durchgreifen, Senioren vor Betrügern schützen</h1>
<div id="content">
...
</div>
</body>
</html>
Note that you also don't have to specify any height/width for the content element (unless you want to further constrict the space it uses).
With CSS3 you could go with your original styling and re-use the margins by applying the box-decoration-break property. However as of writing dompdf does not yet support this property.

jquery Auto search result is not updating the value to textbox after clicking

Below code display the list populated from database(DB code is not included). If I click on the search results, then the selected option will not show in textbox. Help please.
Below code works fine to show list of options from Database while typing characters. The issue is it will not show the selected drop down option into textbox.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery Auto Complete</title>
<script src="jquery/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
function lookup(inputString) {
if(inputString.length == 0) {
$('#suggestions').hide();
} else {
$.post("states.jsp", {queryString: ""+inputString+""}, function(data){
if(data.length >0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}
});
}
}
function fill(thisValue) {
$('#inputString').val(thisValue);
setTimeout("$('#suggestions').hide();", 200);
}
</script>
<style type="text/css">
body {
font-family: Helvetica;
font-size: 13px;
color: #000;
}
h3 {
margin: 0px;
padding: 0px;
}
.suggestionsBox {
position: relative;
left: 260px;
margin: 0px 0px 0px 0px;
width: 200px;
background-color: #7845DD;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border: 2px solid #000;
color: #fff;
}
.suggestionList {
margin: 0px;
padding: 0px;
}
.suggestionList li {
margin: 0px 0px 3px 0px;
padding: 3px;
cursor: pointer;
}
.suggestionList li:hover {
background-color: #DD45CD;
}
</style>
</head>
<body>
<div>
<form>
<div> <h3><font color="red">Indian States</states></font></h3>
<br /> Enter India State Name to see autocomplete
<input type="text" size="30" value="" id="inputString"
onkeyup="lookup(this.value);" onblur="fill();" />
</div>
<div class="suggestionsBox" id="suggestions" style="display: none;">
<div class="suggestionList" id="autoSuggestionsList">
</div>
</div>
</form>
</div>
</body>
</html>
<%
String name=request.getParameter("queryString");
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection con = DriverManager.getConnection("jdbc:sqlserver://localhost", "user", "password");
Statement st=con.createStatement();
//Add the data into the database
String sql = "SELECT EMP_EMPLOYEE_ID, EMP_FNAME, EMP_LNAME FROM UAP_EMPLOYEE where EMP_FNAME LIKE '%"+name+"%' OR EMP_LNAME LIKE '%"+name+"%';";
Statement stm = con.createStatement();
stm.executeQuery(sql);
ResultSet rs= stm.getResultSet();
while (rs.next ()){
out.println("<li onclick='fill("+rs.getString("EMP_FNAME")+");>"+rs.getString("EMP_FNAME")+" </i>");
}}catch(Exception e){
out.println("Exception is ;"+e);
}
%>
In this line
$('#autoSuggestionsList').html(data);
you are setting some html that I assume consists of a list of div tags with your auto-suggestions. If you want the user to be able to click on the list, you need to have a click handler attached to the suggestions that loads the value. Like
$(document).ready(function() {
$("#autoSuggestionsList div").on("click", function() {
//put your click actions here.. load the textbox, hide the list
});
}
The on command is live, meaning it will automatically be bound to elements that are loaded dynamically.
EDIT
Since you're using li instead of div, change the above to
$(document).ready(function() {
$("#autoSuggestionsList li").on("click", function() {
fill($(this).text());
});
}
EDIT 2
In the new code you added, this line is incorrect
out.println("<li onclick='fill("+rs.getString("EMP_FNAME")+");>"+rs.getString("EMP_FNAME")+" </i>");
It will produce incorrect HTML/Javascript that looks like this:
<li onclick='fill(some text);>some text</i>
Your code should look like this:
out.println("<li onclick='fill(\""+rs.getString("EMP_FNAME")+"\");'>"+rs.getString("EMP_FNAME")+" </li>");
It will produce the following correct HTML/JavascriptL
<li onclick='fill("some text");'>some text</li>

Resources