问:
Sidebar stick to bottom (CSS or JS) - reset to top
Added snippet like requested but the css was designed for broader screen.

const target = document.getElementById('content_left');
const init_rect = target.getBoundingClientRect();
const index_height = init_rect.height;
console.log('initial height '+index_height);
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;

window.onscroll = function()
    {
        const rect = target.getBoundingClientRect();
        const buffer = document.getElementById('buffer');

        console.log("viewport :"+viewportHeight);
        console.log("top: "+rect.top);
        console.log("bottom: "+rect.bottom);
        console.log("height: "+rect.height);
        top_diff = viewportHeight-index_height;
        console.log("topdiff: "+top_diff);
        if (rect.bottom < viewportHeight)
            {
                console.log('passed');
                target.style.position='fixed';
                buffer.style.display='block';
                buffer_position = buffer.getBoundingClientRect();
                target.style.left=buffer_position.left+"px";
                target.style.bottom="0px";

            }
    };```
<pre class="snippet-code-css lang-css prettyprint-override"><code>    body
        {
            margin:0px;
            padding:0px;

            width:100%;
            height;100%;

            background-color:#777b87;

            min-height: 100%;
            overflow-x:hidden;

            display:flex;
            flex-flow:row wrap;
            justify-content:center;
            max-width:1920px;
            margin:0 auto;
        }

        #content_left
                {
                    display:flex;
                    flex-flow:column nowrap;
                    width:300px;
                    padding:0px 10px 0px 10px;
          position:sticky;
          height:100%;
          bottom:0px;
                }

#content
        {
            width:calc(100% - 60px);

            padding:20px;
            margin: 0px 10px 0px 10px;
            border-radius: 5px;
            margin-top:10px;
            z-index:100;
            border:1px solid #CCC;

      width: calc(100% - 350px);
      max-width: 850px;
}
#buffer
{
  display:none;
  height:1px;
  width:300px;
  padding:0px 10px 0px 10px;
}</code>```

      START START START START  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST

      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST

      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  END  END END END END END END END

   aaaaaa bbbbb ccccc   aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb cccccaaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc

```
</div>
</div>
</p>
<p>I'm trying to build a page with a left sidebar that becomes sticky when the viewport reaches the bottom of that sidebar. I have tried using position:sticky but each time the viewport was reaching the bottom of the sidebar, the stickiness worked but the sidebar was set to top:0px.</p>
<p>I have then tried to do the same with javascript, I can trigger the changes when the bottom of the sidebar crosses the viewport but again, the sidebar gets positioned from the top and is not entirely visible. I suspect it has something to do with height settings but I can't isolate it.</p>
<p>I have created a codepen to show what is happening once content in inserted into the page:</p>
<p>https://codepen.io/LaurentWi/pen/OJwbrRw (it's too long to be copied here)</p>
<p>The html without the content is the following:</p>
```

```

<p>I have used a "buffer" div to keep the rest of the screen in the right position when content_left leaves the flow.</p>
<p>The CSS looks like this:</p>
```    body
    {
        margin:0px;
        padding:0px;

        width:100%;
        height;100%;

        background-color:#777b87;

        min-height: 100%;
        overflow-x:hidden;

        display:flex;
        flex-flow:row wrap;
        justify-content:center;
        max-width:1920px;
        margin:0 auto;
    }

    #content_left
            {
                display:flex;
                flex-flow:column nowrap;
                width:300px;
                padding:0px 10px 0px 10px;
      position:sticky;
      height:100%;
      bottom:0px;
            }

#content
    {
        width:calc(100% - 60px);

        padding:20px;
        margin: 0px 10px 0px 10px;
        border-radius: 5px;
        margin-top:10px;
        z-index:100;
        border:1px solid #CCC;

  width: calc(100% - 350px);
  max-width: 850px;
}
#buffer
{
  display:none;
  height:1px;
  width:300px;
  padding:0px 10px 0px 10px;
}
```
<p>And finally the JS:</p>
```const target = document.getElementById('content_left');
const init_rect = target.getBoundingClientRect();
const index_height = init_rect.height;
console.log('initial height '+index_height);
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;

window.onscroll = function()
{
    const rect = target.getBoundingClientRect();
    const buffer = document.getElementById('buffer');

    console.log("viewport :"+viewportHeight);
    console.log("top: "+rect.top);
    console.log("bottom: "+rect.bottom);
    console.log("height: "+rect.height);
    top_diff = viewportHeight-index_height;
    console.log("topdiff: "+top_diff);
    if (rect.bottom < viewportHeight)
        {
            console.log('passed');
            target.style.position='fixed';
            buffer.style.display='block';
            buffer_position = buffer.getBoundingClientRect();
            target.style.left=buffer_position.left+"px";
            target.style.bottom="0px";

        }
};
```

I would prefer a solution without JS if you have one but JS is fine as long as it is only vanilla JS.

I suspect that the problem is coming from the height because when the JS display the height of content_left, the value is ok until the element is in position fixed where the height value becomes the viewport height (see console in codepen). I have tried avoiding this by forcing the initial height but it didn't work either because the initial height (see code in JS) was always smaller than the reality. I'm a bit puzzled.

Any idea?

Body:
Added snippet like requested but the css was designed for broader screen.

const target = document.getElementById('content_left');
const init_rect = target.getBoundingClientRect();
const index_height = init_rect.height;
console.log('initial height '+index_height);
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;

window.onscroll = function()
    {
        const rect = target.getBoundingClientRect();
        const buffer = document.getElementById('buffer');

        console.log("viewport :"+viewportHeight);
        console.log("top: "+rect.top);
        console.log("bottom: "+rect.bottom);
        console.log("height: "+rect.height);
        top_diff = viewportHeight-index_height;
        console.log("topdiff: "+top_diff);
        if (rect.bottom < viewportHeight)
            {
                console.log('passed');
                target.style.position='fixed';
                buffer.style.display='block';
                buffer_position = buffer.getBoundingClientRect();
                target.style.left=buffer_position.left+"px";
                target.style.bottom="0px";

            }
    };

    body
        {
            margin:0px;
            padding:0px;

            width:100%;
            height;100%;

            background-color:#777b87;

            min-height: 100%;
            overflow-x:hidden;

            display:flex;
            flex-flow:row wrap;
            justify-content:center;
            max-width:1920px;
            margin:0 auto;
        }

        #content_left
                {
                    display:flex;
                    flex-flow:column nowrap;
                    width:300px;
                    padding:0px 10px 0px 10px;
          position:sticky;
          height:100%;
          bottom:0px;
                }

#content
        {
            width:calc(100% - 60px);

            padding:20px;
            margin: 0px 10px 0px 10px;
            border-radius: 5px;
            margin-top:10px;
            z-index:100;
            border:1px solid #CCC;

      width: calc(100% - 350px);
      max-width: 850px;
}
#buffer
{
  display:none;
  height:1px;
  width:300px;
  padding:0px 10px 0px 10px;
}

      START START START START  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST

      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST

      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST      TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  END  END END END END END END END

   aaaaaa bbbbb ccccc   aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb cccccaaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc      aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc    aaaaaa bbbbb ccccc

I'm trying to build a page with a left sidebar that becomes sticky when the viewport reaches the bottom of that sidebar. I have tried using position:sticky but each time the viewport was reaching the bottom of the sidebar, the stickiness worked but the sidebar was set to top:0px.

I have then tried to do the same with javascript, I can trigger the changes when the bottom of the sidebar crosses the viewport but again, the sidebar gets positioned from the top and is not entirely visible. I suspect it has something to do with height settings but I can't isolate it.

I have created a codepen to show what is happening once content in inserted into the page:

https://codepen.io/LaurentWi/pen/OJwbrRw (it's too long to be copied here)

The html without the content is the following:

I have used a "buffer" div to keep the rest of the screen in the right position when content_left leaves the flow.

The CSS looks like this:

    body
    {
        margin:0px;
        padding:0px;

        width:100%;
        height;100%;

        background-color:#777b87;

        min-height: 100%;
        overflow-x:hidden;

        display:flex;
        flex-flow:row wrap;
        justify-content:center;
        max-width:1920px;
        margin:0 auto;
    }

    #content_left
            {
                display:flex;
                flex-flow:column nowrap;
                width:300px;
                padding:0px 10px 0px 10px;
      position:sticky;
      height:100%;
      bottom:0px;
            }

#content
    {
        width:calc(100% - 60px);

        padding:20px;
        margin: 0px 10px 0px 10px;
        border-radius: 5px;
        margin-top:10px;
        z-index:100;
        border:1px solid #CCC;

  width: calc(100% - 350px);
  max-width: 850px;
}
#buffer
{
  display:none;
  height:1px;
  width:300px;
  padding:0px 10px 0px 10px;
}

And finally the JS:

const target = document.getElementById('content_left');
const init_rect = target.getBoundingClientRect();
const index_height = init_rect.height;
console.log('initial height '+index_height);
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;

window.onscroll = function()
{
    const rect = target.getBoundingClientRect();
    const buffer = document.getElementById('buffer');

    console.log("viewport :"+viewportHeight);
    console.log("top: "+rect.top);
    console.log("bottom: "+rect.bottom);
    console.log("height: "+rect.height);
    top_diff = viewportHeight-index_height;
    console.log("topdiff: "+top_diff);
    if (rect.bottom < viewportHeight)
        {
            console.log('passed');
            target.style.position='fixed';
            buffer.style.display='block';
            buffer_position = buffer.getBoundingClientRect();
            target.style.left=buffer_position.left+"px";
            target.style.bottom="0px";

        }
};

I would prefer a solution without JS if you have one but JS is fine as long as it is only vanilla JS.

I suspect that the problem is coming from the height because when the JS display the height of content_left, the value is ok until the element is in position fixed where the height value becomes the viewport height (see console in codepen). I have tried avoiding this by forcing the initial height but it didn't work either because the initial height (see code in JS) was always smaller than the reality. I'm a bit puzzled.

Any idea?


来源: stackexchange

问:
How to achieve fast video transmission between esp32 cam to a pc?
To make an autonomous drone and help it fly from one place to another without any human intervention, I plan to send data using two ESP32s and receive those data using my PC. I won't use the onboard navigation system inside the drone. I need suggestions regarding the signal-receiving unit (using wifi i will send the data), which will feed information directly to my PC. Kindly give me information on the best way to receive signals from ESP32 to PC, in the shortest amount of time and with a reasonable budget.

We were thinking about NodeMCU, but we aren't going to use it. Moreover, I am in the initial phase and have just started researching this. Also, I am pretty new to this, so any suggestions will help me to discover and also help me get what I want.

ContentLicense: CC BY-SA 4.0


问:
Map month wise data have percentage fixed in other table
I have one table MeritIncrease
Merit table

Other Year Table
MOM data

Using this two tables how can I get this output
Exp Output

```<code>SELECT *
FROM  MeritIncreases MT
LEFT JOIN ContractYear CY ON MT.FiscalYear = YEAR(DATEADD(mm,CY.PeriodNbr-1,@DealStart))+1
    AND Periodflag = 'M'
LEFT JOIN @temp_meritOld CV ON CV.FiscalYear = YEAR(DATEADD(mm,cy.PeriodNbr-1,@DealStart))+1
LEFT JOIN @temp_meritOld CV1 ON CV1.FiscalYear = YEAR(DATEADD(mm,cy.PeriodNbr-1,@DealStart))
</code>```

Body:
I have one table MeritIncrease
Merit table

Other Year Table
MOM data

Using this two tables how can I get this output
Exp Output

SELECT *
FROM  MeritIncreases MT
LEFT JOIN ContractYear CY ON MT.FiscalYear = YEAR(DATEADD(mm,CY.PeriodNbr-1,@DealStart))+1
    AND Periodflag = 'M'
LEFT JOIN @temp_meritOld CV ON CV.FiscalYear = YEAR(DATEADD(mm,cy.PeriodNbr-1,@DealStart))+1
LEFT JOIN @temp_meritOld CV1 ON CV1.FiscalYear = YEAR(DATEADD(mm,cy.PeriodNbr-1,@DealStart))


问:
How do I access attributes of a superclass from within a subclass?
```<code>class Queue:
    def __init__(self):
        self.__part_list = []

    def put(self, elem):
        self.__part_list.append(elem)
        print(self.__part_list)

    def get(self):
        val = self.__part_list[0]
        del self.__part_list[0]
        return val

    def isempty(self):
        if len(self.__part_list) == 0:
            return True
        else:
            return False

class SuperQueue(Queue):
    def __init__(self):
        Queue.__init__(self)

    def print_list(self):
        print(self.__part_list)

que2 = Queue()
que = SuperQueue()
que.put(1)
que.put("dog")
que.put(False)
que.print_list()
</code>```

AttributeError: 'SuperQueue' object has no attribute '_SuperQueue__part_list'

I can print part_list from within the superclass but not from within the subclass. I thought the subclass would inherit the list from the superclass but I cannot call it.

Body:
class Queue:
    def __init__(self):
        self.__part_list = []

    def put(self, elem):
        self.__part_list.append(elem)
        print(self.__part_list)

    def get(self):
        val = self.__part_list[0]
        del self.__part_list[0]
        return val

    def isempty(self):
        if len(self.__part_list) == 0:
            return True
        else:
            return False

class SuperQueue(Queue):
    def __init__(self):
        Queue.__init__(self)

    def print_list(self):
        print(self.__part_list)

que2 = Queue()
que = SuperQueue()
que.put(1)
que.put("dog")
que.put(False)
que.print_list()

AttributeError: 'SuperQueue' object has no attribute '_SuperQueue__part_list'

I can print part_list from within the superclass but not from within the subclass. I thought the subclass would inherit the list from the superclass but I cannot call it.


问:
Bash getopts not reading arguments to variables
Hi all I think I am going insane. I have the following at the beginning of a bash script:

```<code>#!/bin/bash

while getopts i:o:c:p:g: flag
do
    case "${flag}" in
        g) genome=${OPTARG};;
        p) poscol=${OPTARG};;
        c) chromcol=${OPTARG};;
        i) inf=${OPTARG};;
        o) outf=${OPTARG};;
    esac
done

echo ""
echo "This should be a list of the arguments:"
echo $inf
echo $outf
echo $poscol
echo $chromcol
echo $genome
echo "-----------------------"
</code>```

Yet when I run a test of the code, eg:

```<code>bash Code.sh -i test.txt -o test.txt -c 0 -p 1 -g testgenome
</code>```

bash returns:

```<code>This should be a list of the arguments:

-----------------------
</code>```

I literally just copied this section of code from a script where the arguments work fine. Does anyone have any idea what could be going on here? Thanks in advance.

Body:
Hi all I think I am going insane. I have the following at the beginning of a bash script:

#!/bin/bash

while getopts i:o:c:p:g: flag
do
    case "${flag}" in
        g) genome=${OPTARG};;
        p) poscol=${OPTARG};;
        c) chromcol=${OPTARG};;
        i) inf=${OPTARG};;
        o) outf=${OPTARG};;
    esac
done

echo ""
echo "This should be a list of the arguments:"
echo $inf
echo $outf
echo $poscol
echo $chromcol
echo $genome
echo "-----------------------"

Yet when I run a test of the code, eg:

bash Code.sh -i test.txt -o test.txt -c 0 -p 1 -g testgenome

bash returns:

This should be a list of the arguments:

-----------------------

I literally just copied this section of code from a script where the arguments work fine. Does anyone have any idea what could be going on here? Thanks in advance.


问:
Why doesn't the popup to ask for location permissions work in Android 12?
I'm doing a project in React Native to track people. The problem is that my code works on Android 9, but it never asks for permissions on Android 12.

const hasLocationPermission = async () => {
  try {
    if (Platform.OS === "android") {
      const hasFinePermission = await PermissionsAndroid.check(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
      );
      const hasCoarsePermission = await PermissionsAndroid.check(
        PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION
      );

      if (hasFinePermission && hasCoarsePermission) {
        return true;
      }

      try {
        const status = await PermissionsAndroid.requestMultiple([
          PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
          PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        ]);

        if (
          status[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
            PermissionsAndroid.RESULTS.GRANTED &&
          status[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
            PermissionsAndroid.RESULTS.GRANTED
        ) {
          return true;
        }

        if (
          status[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
            PermissionsAndroid.RESULTS.DENIED &&
          status[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
            PermissionsAndroid.RESULTS.DENIED
        ) {
          Alert.alert("Error", "Location permission denied by user.", {
            text: "OK",
            cancelable: false,
          });
        } else if (
          status[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
          status[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
        ) {
          Alert.alert("Error", "Location permission revoked by user.", {
            text: "OK",
            cancelable: false,
          });
        }
      } catch (err) {
        console.log(err);
      }

      return false;
    }
  } catch (err) {
    console.warn(err);
  }
};
```

I'm trying to access permissions in Android 12, but it only works on versions prior to Android 12

Body:
I'm doing a project in React Native to track people. The problem is that my code works on Android 9, but it never asks for permissions on Android 12.

const hasLocationPermission = async () => {
  try {
    if (Platform.OS === "android") {
      const hasFinePermission = await PermissionsAndroid.check(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
      );
      const hasCoarsePermission = await PermissionsAndroid.check(
        PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION
      );

      if (hasFinePermission && hasCoarsePermission) {
        return true;
      }

      try {
        const status = await PermissionsAndroid.requestMultiple([
          PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
          PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        ]);

        if (
          status[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
            PermissionsAndroid.RESULTS.GRANTED &&
          status[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
            PermissionsAndroid.RESULTS.GRANTED
        ) {
          return true;
        }

        if (
          status[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
            PermissionsAndroid.RESULTS.DENIED &&
          status[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
            PermissionsAndroid.RESULTS.DENIED
        ) {
          Alert.alert("Error", "Location permission denied by user.", {
            text: "OK",
            cancelable: false,
          });
        } else if (
          status[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
          status[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
        ) {
          Alert.alert("Error", "Location permission revoked by user.", {
            text: "OK",
            cancelable: false,
          });
        }
      } catch (err) {
        console.log(err);
      }

      return false;
    }
  } catch (err) {
    console.warn(err);
  }
};

I'm trying to access permissions in Android 12, but it only works on versions prior to Android 12


问:
My code running wrong and making A instead of not answered
When I pdf is generated instead of not answering it is appearing as a for this code

 function generatePDF() {
  // Create a new PDF document
  var doc = new jsPDF();

    // Define an array of questions
    var questions = [
      "Question 1", "Question 2", "Question 3", "Question 4", "Question 5",
      "Question 6", "Question 7", "Question 8", "Question 9", "Question 10",
      "Question 11", "Question 12", "Question 13", "Question 14", "Question 15",
      "Question 16", "Question 17", "Question 18", "Question 19", "Question 20",
      "Question 21", "Question 22", "Question 23", "Question 24", "Question 25",
      "Question 26", "Question 27", "Question 28", "Question 29", "Question 30",
      "Question 31", "Question 32", "Question 33", "Question 34", "Question 35",
      "Question 36", "Question 37", "Question 38", "Question 39", "Question 40",
      "Question 41", "Question 42", "Question 43", "Question 44", "Question 45",
      "Question 46", "Question 47", "Question 48", "Question 49", "Question 50",
      "Question 51", "Question 52", "Question 53", "Question 54", "Question 55",
      "Question 56", "Question 57", "Question 58", "Question 59", "Question 60",
      "Question 61", "Question 62", "Question 63", "Question 64", "Question 65",
      "Question 66", "Question 67", "Question 68", "Question 69", "Question 70",
      "Question 71", "Question 72", "Question 73", "Question 74", "Question 75",
      "Question 76", "Question 77", "Question 78", "Question 79", "Question 80",
      "Question 81", "Question 82", "Question 83", "Question 84", "Question 85",
      "Question 86", "Question 87", "Question 88", "Question 89", "Question 90"
    ];

  for (var i = 0; i < questions.length; i++) {
    // Check if there is a radio button selected for the current question
    var radioButton = document.querySelector(`input[name="${i + 1}"]:checked`);
    if (radioButton) {
      var answer = radioButton.value;
    } else {
      // Check if there is an input text field for the current question
      var inputField = document.querySelector(`input[name="${i + 1}"]`);
      if (inputField) {
        var answer = inputField.value;
      } else {
        var answer = "Not answered";
      }
    }

    // Wrap the text in cells
    doc.cell(20, 20 + i * 10, 100, 10, questions[i], i);
    doc.cell(50, 20 + i * 10, 100, 10, "Answer: " + answer, i);
  }

  // Save the PDF
  doc.save("Question and answers.pdf");
}
```
<p>I was expecting it will generate not answered if questions are left blank but it is showing as a (option) for this div</p>
<pre class="lang-html prettyprint-override"><code><div id="question75" class="question" style="display:none;">
    <p>Question 75</p>
    <div id="answers" class="answers">
      <label>
        <input type="radio" name="75" value="A">
        a
      </label>
      <label>
        <input type="radio" name="75" value="B">
        b
      </label>
      <label>
        <input type="radio" name="75" value="C">
        c
      </label>
      <label>
        <input type="radio" name="75" value="D">
        d
      </label>
    </div>
</div>
</code>```

Body:
When I pdf is generated instead of not answering it is appearing as a for this code

 function generatePDF() {
  // Create a new PDF document
  var doc = new jsPDF();

    // Define an array of questions
    var questions = [
      "Question 1", "Question 2", "Question 3", "Question 4", "Question 5",
      "Question 6", "Question 7", "Question 8", "Question 9", "Question 10",
      "Question 11", "Question 12", "Question 13", "Question 14", "Question 15",
      "Question 16", "Question 17", "Question 18", "Question 19", "Question 20",
      "Question 21", "Question 22", "Question 23", "Question 24", "Question 25",
      "Question 26", "Question 27", "Question 28", "Question 29", "Question 30",
      "Question 31", "Question 32", "Question 33", "Question 34", "Question 35",
      "Question 36", "Question 37", "Question 38", "Question 39", "Question 40",
      "Question 41", "Question 42", "Question 43", "Question 44", "Question 45",
      "Question 46", "Question 47", "Question 48", "Question 49", "Question 50",
      "Question 51", "Question 52", "Question 53", "Question 54", "Question 55",
      "Question 56", "Question 57", "Question 58", "Question 59", "Question 60",
      "Question 61", "Question 62", "Question 63", "Question 64", "Question 65",
      "Question 66", "Question 67", "Question 68", "Question 69", "Question 70",
      "Question 71", "Question 72", "Question 73", "Question 74", "Question 75",
      "Question 76", "Question 77", "Question 78", "Question 79", "Question 80",
      "Question 81", "Question 82", "Question 83", "Question 84", "Question 85",
      "Question 86", "Question 87", "Question 88", "Question 89", "Question 90"
    ];

  for (var i = 0; i < questions.length; i++) {
    // Check if there is a radio button selected for the current question
    var radioButton = document.querySelector(`input[name="${i + 1}"]:checked`);
    if (radioButton) {
      var answer = radioButton.value;
    } else {
      // Check if there is an input text field for the current question
      var inputField = document.querySelector(`input[name="${i + 1}"]`);
      if (inputField) {
        var answer = inputField.value;
      } else {
        var answer = "Not answered";
      }
    }

    // Wrap the text in cells
    doc.cell(20, 20 + i * 10, 100, 10, questions[i], i);
    doc.cell(50, 20 + i * 10, 100, 10, "Answer: " + answer, i);
  }

  // Save the PDF
  doc.save("Question and answers.pdf");
}

I was expecting it will generate not answered if questions are left blank but it is showing as a (option) for this div

Question 75

        <input type="radio" name="75" value="A">
        a

        <input type="radio" name="75" value="B">
        b

        <input type="radio" name="75" value="C">
        c

        <input type="radio" name="75" value="D">
        d


问:
ETL package works in Dev but not in Production
I have an on-premise SQL Server running a job with an ETL package and pointing to a SQL Server database in Azure.

In DEV, it works fine, but then when we copy the package to PROD and try to run it, it fails.

The error message returned by the job is the following:

```<code>Error: 2023-01-06 08:10:53.83     Code: 0xC0208452     Source: ETL Destino ADO NET [8]
Description: ADO NET Destination has failed to acquire the connection with the following error message: "One or more errors occurred.".  End Error

Error: 2023-01-06 08:10:53.83     Code: 0xC0047017     Source: ETL SSIS.Pipeline     Description: Destino de ADO NET failed validation and returned error code 0xC0208452.  End Error

Error: 2023-01-06 08:10:53.83     Code: 0xC004700C     Source: ETL SSIS.Pipeline     Description: One or more component failed validation.  End Error

Error: 2023-01-06 08:10:53.83     Code: 0xC0024107     Source: ETL    Description: There were errors during task validation.  End Error

DTExec: The package execution returned DTSER_FAILURE (1).  Started:  8:10:51 AM Finished: 8:10:53 AM Elapsed:  1.953 seconds.  The package execution failed.  The step failed.**
</code>```

It runs under the SQL Server Agent service account, which has db_owner permissions within the Azure database. The same permissions as the Development account, which does work.

The source instances are both SQL Server 2017, CU25.

The packages are located locally in both of the servers.

Does anyone have any idea?

Any ideas/help would be greatly appreciated.

Body:
I have an on-premise SQL Server running a job with an ETL package and pointing to a SQL Server database in Azure.

In DEV, it works fine, but then when we copy the package to PROD and try to run it, it fails.

The error message returned by the job is the following:

Error: 2023-01-06 08:10:53.83     Code: 0xC0208452     Source: ETL Destino ADO NET [8]
Description: ADO NET Destination has failed to acquire the connection with the following error message: "One or more errors occurred.".  End Error

Error: 2023-01-06 08:10:53.83     Code: 0xC0047017     Source: ETL SSIS.Pipeline     Description: Destino de ADO NET failed validation and returned error code 0xC0208452.  End Error

Error: 2023-01-06 08:10:53.83     Code: 0xC004700C     Source: ETL SSIS.Pipeline     Description: One or more component failed validation.  End Error

Error: 2023-01-06 08:10:53.83     Code: 0xC0024107     Source: ETL    Description: There were errors during task validation.  End Error

DTExec: The package execution returned DTSER_FAILURE (1).  Started:  8:10:51 AM Finished: 8:10:53 AM Elapsed:  1.953 seconds.  The package execution failed.  The step failed.**

It runs under the SQL Server Agent service account, which has db_owner permissions within the Azure database. The same permissions as the Development account, which does work.

The source instances are both SQL Server 2017, CU25.

The packages are located locally in both of the servers.

Does anyone have any idea?

Any ideas/help would be greatly appreciated.


问:
chrome extension v3 get selected text, display contextmenu and send to restful api
I'm new to Chrome extension development and I have searched for an extension example on how to do this but most examples are for manifest v2 and I need it for v3. I have tried converting the v2 examples I have found but have had no success.

The extension should do the following:

When the user selects text on the page and right-clicks it should display a context-menu (ex: Option 1, Option 2, etc)

When the user clicks on one of the context-menu options the extension sends the selected text, the URL of the page and the selected context-menu option to a restful API.

Thanks


问:
how to understand optical flow's corner detection and calcOpticalFlowPyrLK() in opencv
Hello guys this is my first question at all,

I am a student and beginner in C++ I have been dealing exclusively with the Lucas-Kanade Alg. for the last few days and I am reaching the limits of my cognitive capacity. I am not aware of anyone who could help me therefore I ask you. In the video I want to use, the ROI is placed on a person's chest to capture upward and downward motion at the sagital plane. From the obtained information of the pixel arrangement of each frame, the duration of the inspiration time can be determined.

The following problem:

In a short test video, an ROI in the first frame is selected by hand to determine the optical flow vectors [p0_prev] of the goodFeaturesToTrack() function there, which serves as a parameter for determining the pixels location of the next frame in calcOpticalFlowPyrLK[p1_next]  - got this after reading the opencv doc, check. p0  and p1 are velocity vectors, fine. But that is nearly all i understand in terms of p0 and p1.

My thoughts:

  goodFeaturesToTrack(old_gray, p0, 100 , 0.1, 3, dist, 3, false, 0.04);

I use "100" because the ROI is big and size(p1) will be same size as p0 the more values i get, the more detail my movement detection, right ? maybe i can use even more ?

**Are all relevant values of the ROI preserved in p0? How can I ensure this ? **

Is it possible to improve the quality of p0 in the parameters ?.
i want to compare p0,p1 where status i ==  0 or 1 statisticly in each framepair via correlatio n[Matlab]after the algo finished its work.

i want to add forward backword error detection, but i am not able to implement it :( I think it goes with 2x calcopticalflow.

`           calcOpticalFlowPyrLK(old_gray, frame_gray, p0, p1, status, err, Size(5,5), 2, criteria);

`How can I adjust Size(5,5) in a meaningful way or what effects does it have on the quality of p1 - is it a good idea to make the size bigger?

i want to get the "good corners" from status == 1 to improve the algo and select the good ones

What is the relation between max_corners from goodFeaturesToTrack and Size(a*a) from calcOpticalFlowPyrLK ?

**How can I ensure that my features are properly defined to be sufficient and compatible for the set ROI?
**

Problems in the code:

p0 decrements in time (and so does p1) - WHY?

every member of p1 gets the status == 1 - WHY? i think this is wrong,

In case of the Universtiys lecture i need to export the y-values and plot them in Matlab to compare them with a signal given from a different system - thats why i need to have valuable informations...

Full Code

```<code>void Termin_2_3_3(string video, string filename) {

    // load video
    VideoCapture own(video);

    int frame_width = own.get(CAP_PROP_FRAME_WIDTH);
    int frame_height = own.get(CAP_PROP_FRAME_HEIGHT);
    double fps = own.get(CAP_PROP_FPS);

    VideoWriter video_written("Tracking" + video, VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, Size(frame_width, frame_height));

    cout << "Anzahl der Frames im Video =  " << fps << endl;

    ofstream frame_ofs;

    frame_ofs.open(filename + ".dat"); // save the video

    if (!own.isOpened()) {
        //error in opening the video
        cerr << "Unable to open video!" << endl;

    }

    Mat first_frame, old_gray;

    vector<Point2f> p0, p1;

    // Take first frame and find corners in it
    for (int i = 0; i <= 2; i++)
    {
        own >> first_frame;

    }

    Rect ROI = selectROI("ROI", first_frame);
    destroyWindow("ROI");

    // Center of the ROI pixel x/y axis
    cout << "ROI.x MP =   " << ROI.x << " ROI.y MP =  " << ROI.y << endl;

    cvtColor(first_frame, old_gray, COLOR_BGR2GRAY);

    // Create source for further processing and copy in old_gray incl ROI
    Mat src;
    old_gray.copyTo(src);

    // create empty masks
    Mat m1 = Mat::zeros(old_gray.size(), CV_8UC1);
    Mat dist = Mat::zeros(src.size(), CV_8UC1);
    Mat output;

    /*Circe->(current image being edited on, center, radius, color, thickness, linetype, shift)
    Circle is then on black m1 image*/
    circle(m1, Point(ROI.x + 30, ROI.y + 30), 50, Scalar(255, 0, 0), -1, 8, 0);

    // src = Place gray image with ROI on still black images or empty masks m1 and dist
    src.copyTo(dist, m1);

    /*find strong corner by optical flow
    -> (input_image, outputVektor der Kanten, MaximumKanten, QualityLevel, MinDistancePixel, Maske)*/
    goodFeaturesToTrack(old_gray, p0, 100 , 0.1, 3, dist, 3, false, 0.04);
    // goodFeaturesToTrack(image_old, corner_old, 5, 0.1, 7, mask, 3, false, 0.04);

    cout << "Anzahl der Werte nach goodFeatures " << p0.size() << endl;
    cout << "Werte für p0 nach goodFeatures " << p0 << endl;

    // Create a mask image for drawing purposes
    Mat mask = Mat::zeros(old_gray.size(), old_gray.type());

    //Variables for the loops   int a = 30;
    int b = 1;
    int i = 0;

    while (i <= 4000)
    {
        Mat frame, frame_gray;

        //Shift next frame (once completely in frame)
        own >> frame;

            if (frame.empty())
            break;

        //convert
        cvtColor(frame, frame_gray, COLOR_BGR2GRAY);

        // calculate optical flow
        vector<uchar> status;
        vector<float> err;

        TermCriteria criteria = TermCriteria((TermCriteria::COUNT) + (TermCriteria::EPS), 20, 0.03);
        try
        {
            //
            // Edge detection incl. optical flow vectors
            calcOpticalFlowPyrLK(old_gray, frame_gray, p0, p1, status, err, Size(5,5), 2, criteria);
            /* https://docs.opencv.org/4.6.0/dc/d6b/group__video__track.html#ga473e4b886d0bcc6b65831eb88ed93323 */
        }
        catch (Exception e)
        {
            e.formatMessage();
        }
        cout << "Number/Size of p0 after  calcOptical " << p0.size() << endl << endl;
        cout << "Number/Size of p1 after  calcOptical " << p1.size() << endl << endl;
        cout << "Number/Size ROI  " << ROI.size() << endl << endl;

        vector<Point2f> good_new;
        float x = 0, y = 0; // Set x and y for new position of ROI
        float anzahl_zuverl = 0;

        for (uint i = 0; i < p1.size(); i++)
        {
            // Select good points of flow vectos from ROI
            if (status[i] == 1) {

                // append p1[i] in good_new
                good_new.push_back(p1[i]);

                x += p1[i].x - p0[i].x;
                y += p1[i].y - p0[i].y;

                anzahl_zuverl++;

            }

        }

        cout << "x =  " << x << " y =  " << y << endl << endl;

        cout << "Number of good_new " << good_new.size() << endl << endl;

        // y s  ave values for export
        frame_ofs << y << endl;

        // Make ROI move direction
        x = x / p1.size();
        y = y / p1.size();
        ROI.x += round(x);
        ROI.y += round(y);

        rectangle(frame, ROI, Scalar(255, 0, 255), 2);

        i++;

        imshow("Frame", frame);
        int keyboard = waitKey(30);
        if (keyboard == 'q' || keyboard == 27)
            break;

        // Now update the previous frame and previous points
        old_gray = frame_gray.clone();
        p0 = good_new;

        video_written.write(frame);

    }

}
</code>```

enter image description here

I dont have any experience in Python, but i found a lot example codes which i am not able to read propperly.

Problem is the opencv doc is just definitions. I changed the values of the parameters a lot but could not rly see a related difference.

Rookie problems guys, sry :P

Body:
Hello guys this is my first question at all,

I am a student and beginner in C++ I have been dealing exclusively with the Lucas-Kanade Alg. for the last few days and I am reaching the limits of my cognitive capacity. I am not aware of anyone who could help me therefore I ask you. In the video I want to use, the ROI is placed on a person's chest to capture upward and downward motion at the sagital plane. From the obtained information of the pixel arrangement of each frame, the duration of the inspiration time can be determined.

The following problem:

In a short test video, an ROI in the first frame is selected by hand to determine the optical flow vectors [p0_prev] of the goodFeaturesToTrack() function there, which serves as a parameter for determining the pixels location of the next frame in calcOpticalFlowPyrLK[p1_next]  - got this after reading the opencv doc, check. p0  and p1 are velocity vectors, fine. But that is nearly all i understand in terms of p0 and p1.

My thoughts:

  goodFeaturesToTrack(old_gray, p0, 100 , 0.1, 3, dist, 3, false, 0.04);

I use "100" because the ROI is big and size(p1) will be same size as p0 the more values i get, the more detail my movement detection, right ? maybe i can use even more ?

**Are all relevant values of the ROI preserved in p0? How can I ensure this ? **

Is it possible to improve the quality of p0 in the parameters ?.
i want to compare p0,p1 where status i ==  0 or 1 statisticly in each framepair via correlatio n[Matlab]after the algo finished its work.

i want to add forward backword error detection, but i am not able to implement it :( I think it goes with 2x calcopticalflow.

`           calcOpticalFlowPyrLK(old_gray, frame_gray, p0, p1, status, err, Size(5,5), 2, criteria);

`How can I adjust Size(5,5) in a meaningful way or what effects does it have on the quality of p1 - is it a good idea to make the size bigger?

i want to get the "good corners" from status == 1 to improve the algo and select the good ones

What is the relation between max_corners from goodFeaturesToTrack and Size(a*a) from calcOpticalFlowPyrLK ?

**How can I ensure that my features are properly defined to be sufficient and compatible for the set ROI?
**

Problems in the code:

p0 decrements in time (and so does p1) - WHY?

every member of p1 gets the status == 1 - WHY? i think this is wrong,

In case of the Universtiys lecture i need to export the y-values and plot them in Matlab to compare them with a signal given from a different system - thats why i need to have valuable informations...

Full Code

void Termin_2_3_3(string video, string filename) {

    // load video
    VideoCapture own(video);

    int frame_width = own.get(CAP_PROP_FRAME_WIDTH);
    int frame_height = own.get(CAP_PROP_FRAME_HEIGHT);
    double fps = own.get(CAP_PROP_FPS);

    VideoWriter video_written("Tracking" + video, VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, Size(frame_width, frame_height));

    cout << "Anzahl der Frames im Video =  " << fps << endl;

    ofstream frame_ofs;

    frame_ofs.open(filename + ".dat"); // save the video

    if (!own.isOpened()) {
        //error in opening the video
        cerr << "Unable to open video!" << endl;

    }

    Mat first_frame, old_gray;

    vector<Point2f> p0, p1;

    // Take first frame and find corners in it
    for (int i = 0; i <= 2; i++)
    {
        own >> first_frame;

    }

    Rect ROI = selectROI("ROI", first_frame);
    destroyWindow("ROI");

    // Center of the ROI pixel x/y axis
    cout << "ROI.x MP =   " << ROI.x << " ROI.y MP =  " << ROI.y << endl;

    cvtColor(first_frame, old_gray, COLOR_BGR2GRAY);

    // Create source for further processing and copy in old_gray incl ROI
    Mat src;
    old_gray.copyTo(src);

    // create empty masks
    Mat m1 = Mat::zeros(old_gray.size(), CV_8UC1);
    Mat dist = Mat::zeros(src.size(), CV_8UC1);
    Mat output;

    /*Circe->(current image being edited on, center, radius, color, thickness, linetype, shift)
    Circle is then on black m1 image*/
    circle(m1, Point(ROI.x + 30, ROI.y + 30), 50, Scalar(255, 0, 0), -1, 8, 0);

    // src = Place gray image with ROI on still black images or empty masks m1 and dist
    src.copyTo(dist, m1);

    /*find strong corner by optical flow
    -> (input_image, outputVektor der Kanten, MaximumKanten, QualityLevel, MinDistancePixel, Maske)*/
    goodFeaturesToTrack(old_gray, p0, 100 , 0.1, 3, dist, 3, false, 0.04);
    // goodFeaturesToTrack(image_old, corner_old, 5, 0.1, 7, mask, 3, false, 0.04);

    cout << "Anzahl der Werte nach goodFeatures " << p0.size() << endl;
    cout << "Werte für p0 nach goodFeatures " << p0 << endl;

    // Create a mask image for drawing purposes
    Mat mask = Mat::zeros(old_gray.size(), old_gray.type());

    //Variables for the loops   int a = 30;
    int b = 1;
    int i = 0;

    while (i <= 4000)
    {
        Mat frame, frame_gray;

        //Shift next frame (once completely in frame)
        own >> frame;

            if (frame.empty())
            break;

        //convert
        cvtColor(frame, frame_gray, COLOR_BGR2GRAY);

        // calculate optical flow
        vector<uchar> status;
        vector<float> err;

        TermCriteria criteria = TermCriteria((TermCriteria::COUNT) + (TermCriteria::EPS), 20, 0.03);
        try
        {
            //
            // Edge detection incl. optical flow vectors
            calcOpticalFlowPyrLK(old_gray, frame_gray, p0, p1, status, err, Size(5,5), 2, criteria);
            /* https://docs.opencv.org/4.6.0/dc/d6b/group__video__track.html#ga473e4b886d0bcc6b65831eb88ed93323 */
        }
        catch (Exception e)
        {
            e.formatMessage();
        }
        cout << "Number/Size of p0 after  calcOptical " << p0.size() << endl << endl;
        cout << "Number/Size of p1 after  calcOptical " << p1.size() << endl << endl;
        cout << "Number/Size ROI  " << ROI.size() << endl << endl;

        vector<Point2f> good_new;
        float x = 0, y = 0; // Set x and y for new position of ROI
        float anzahl_zuverl = 0;

        for (uint i = 0; i < p1.size(); i++)
        {
            // Select good points of flow vectos from ROI
            if (status[i] == 1) {

                // append p1[i] in good_new
                good_new.push_back(p1[i]);

                x += p1[i].x - p0[i].x;
                y += p1[i].y - p0[i].y;

                anzahl_zuverl++;

            }

        }

        cout << "x =  " << x << " y =  " << y << endl << endl;

        cout << "Number of good_new " << good_new.size() << endl << endl;

        // y s  ave values for export
        frame_ofs << y << endl;

        // Make ROI move direction
        x = x / p1.size();
        y = y / p1.size();
        ROI.x += round(x);
        ROI.y += round(y);

        rectangle(frame, ROI, Scalar(255, 0, 255), 2);

        i++;

        imshow("Frame", frame);
        int keyboard = waitKey(30);
        if (keyboard == 'q' || keyboard == 27)
            break;

        // Now update the previous frame and previous points
        old_gray = frame_gray.clone();
        p0 = good_new;

        video_written.write(frame);

    }

}

enter image description here

I dont have any experience in Python, but i found a lot example codes which i am not able to read propperly.

Problem is the opencv doc is just definitions. I changed the values of the parameters a lot but could not rly see a related difference.

Rookie problems guys, sry :P


问:
Reverse Proxy Httpd Nodejs Pm2
I'm trying to set up a reverse proxy to a Node.Js Express web server. Basically I'm trying to redirect any traffic coming to mywebsite.com and have httpd redirect them to node.js app endpoints. So if I would do mywebsite.com/test then it would run the /test function in my node app.

I'm running on EC2 (Amazon Linux 2 AMI)

My backend is at:

```<code>/home/ec2-user/mywebsite/mywebsite_backend/dist
</code>```

I'm running the with pm2, which is a monitoring software for node.

Here's the configuration to /etc/httpd/conf.d/mywebsite.com.conf

```<code><VirtualHost *:80>
  ServerName mywebsite.com
  ServerAlias www.mywebsite.com
  ProxyPreserveHost On
  ProxyPass /home/ec2-user/mywebsite/mywebsite_backend/dist http://localhost:8055/
  ProxyPassReverse /home/ec2-user/mywebsite/mywebsite_backend/dist http://localhost:8055/
  ErrorLog /etc/httpd/conf.d/error.log
  CustomLog /etc/httpd/conf.d/custom.log combined
  DocumentRoot /home/ec2-user/mywebsite/mywebsite_backend/dist

</VirtualHost>
</code>```

When I try to open: https://mywebsite.com from a browser I get apache testpage.

When I try https: https://mywebsite.com/test' I get "Not Found". I'm guessing that this is because there's no :443 virtualhost?

When I try http aka non-secure: http://mywebsite.com I get "Forbidden".

Edit1: It seems that Apache is by default looking in /var/www/html. I added a index.html page there and now I can see it when visiting mywebsite.com.

Edit2:
When doing curl http://localhost:8055/test on the server the response is:

curl: (52) Empty reply from server

When doing curl https://localhost:8055/test on the server the response is:

curl: (60) SSL: no alternative certificate subject name matches target
host name 'localhost' More details here:
https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could
not establish a secure connection to it. To learn more about this
situation and how to fix it, please visit the web page mentioned
above.

I've made the SSL certificates for my express server with Let's encrypt and I'm pointing to the generated files in my code and it works locally, but it seems I have a problem with SSL with apache?

Edit3:

curl -k http://localhost:8055/test

Does not work.

I've tried now pingin my node app with

curl -k https://localhost:8055/test

It works.

Edit4: Looking at the error logs /etc/httpd/conf.d/error.log it seems that there are permission problems with the code being in /home directory. I will move it to /var/www/html/

Title: Reverse Proxy Httpd Nodejs Pm2

Body:
I'm trying to set up a reverse proxy to a Node.Js Express web server. Basically I'm trying to redirect any traffic coming to mywebsite.com and have httpd redirect them to node.js app endpoints. So if I would do mywebsite.com/test then it would run the /test function in my node app.

I'm running on EC2 (Amazon Linux 2 AMI)

My backend is at:

/home/ec2-user/mywebsite/mywebsite_backend/dist

I'm running the with pm2, which is a monitoring software for node.

Here's the configuration to /etc/httpd/conf.d/mywebsite.com.conf

<VirtualHost *:80>
  ServerName mywebsite.com
  ServerAlias www.mywebsite.com
  ProxyPreserveHost On
  ProxyPass /home/ec2-user/mywebsite/mywebsite_backend/dist http://localhost:8055/
  ProxyPassReverse /home/ec2-user/mywebsite/mywebsite_backend/dist http://localhost:8055/
  ErrorLog /etc/httpd/conf.d/error.log
  CustomLog /etc/httpd/conf.d/custom.log combined
  DocumentRoot /home/ec2-user/mywebsite/mywebsite_backend/dist

</VirtualHost>

When I try to open: https://mywebsite.com from a browser I get apache testpage.

When I try https: https://mywebsite.com/test' I get "Not Found". I'm guessing that this is because there's no :443 virtualhost?

When I try http aka non-secure: http://mywebsite.com I get "Forbidden".

Edit1: It seems that Apache is by default looking in /var/www/html. I added a index.html page there and now I can see it when visiting mywebsite.com.

Edit2:
When doing curl http://localhost:8055/test on the server the response is:

curl: (52) Empty reply from server

When doing curl https://localhost:8055/test on the server the response is:

curl: (60) SSL: no alternative certificate subject name matches target
host name 'localhost' More details here:
https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could
not establish a secure connection to it. To learn more about this
situation and how to fix it, please visit the web page mentioned
above.

I've made the SSL certificates for my express server with Let's encrypt and I'm pointing to the generated files in my code and it works locally, but it seems I have a problem with SSL with apache?

Edit3:

curl -k http://localhost:8055/test

Does not work.

I've tried now pingin my node app with

curl -k https://localhost:8055/test

It works.

Edit4: Looking at the error logs /etc/httpd/conf.d/error.log it seems that there are permission problems with the code being in /home directory. I will move it to /var/www/html/


问:
Adding DropDown list in jQuery DataTable
I want to display table's data with jQuery DataTable and sometimes apply an extra data filtering, using the output of a dropdown select input.

The main code for fetching data (fetch.php) is:

```<code><?php
include('db.php');
include('function.php');
$query = '';
$output = array();
$query .= "SELECT * FROM Part_tb ";
if(isset($_POST["search"]["value"]))
{
    $query .= 'WHERE part_manufacturer LIKE "%'.$_POST["search"]["value"].'%" ';
    $query .= 'OR part_id LIKE "%'.$_POST["search"]["value"].'%" ';
}
if(isset($_POST["order"]))
{
    $query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' ';
}
else
{
    $query .= 'ORDER BY part_id ASC ';
}
if($_POST["length"] != -1)
{
    $query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
}
$statement = $connection->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$data = array();
$filtered_rows = $statement->rowCount();
foreach($result as $row)
{
    $sub_array = array();
    $sub_array[] = $row["part_manufacturer"];
    $sub_array[] = $row["part_id"];
    $sub_array[] = $row["part_category"];
    $sub_array[] = $row["part_stock"];
    $data[] = $sub_array;
}
$output = array(
    "draw"              =>  intval($_POST["draw"]),
    "recordsTotal"      =>  $filtered_rows,
    "recordsFiltered"   =>  get_total_all_records(),
    "data"              =>  $data
);
echo json_encode($output);
?>
</code>```

while the DataTable is defined in index.php as follows:

```<code>    var dataTable = $('#user_data').DataTable({
        "processing":true,
        "serverSide":true,
        "order":[],
        "ajax":{
            url:"actions/fetch.php",
            type:"POST"
        },
        "columnDefs":[
            {
                "targets":[0, 1],
                "orderable":false,
            },
        ],

    });
</code>```

In index.php, i've created 3 dependent dropdown lists, which load data from other tables. Now, i want to take the id of 3rd dropdown list and update the data of Part_tb in fetch.php accordingly. Below, you can see that when 3rd dropdown change, i call a function load_parts():

```<code>  $(document).on('change', '#sub3_category_item', function(){
    load_parts();
  });

    function load_parts()
    {
    var action = 'fetch_data';
    var filter_part_id = $('#sub2_category_item').val();
        $.ajax({
            url:"actions/fetch.php",
            method:"post",
            data:{action:action, filter_part_id:filter_part_id},
            success:function(data)
            {
                $('#user_data').DataTable().ajax.reload();
            }
        });
    }
</code>```

The problem is that i can't filter the data of fetch.php according to the selected id of #sub2_category_item. Could you help me on that?

I've modified the index.php as follows:

```<code>      $(document).on('change', '#sub3_category_item', function(){
    var filter_part_id = $('#sub3_category_item').val();
    $('#user_data').DataTable().destroy();
    fill_datatable(filter_part_id);
    });

    fill_datatable();

    function fill_datatable(filter_part_id = '')
    {
    var dataTable = $('#user_data').DataTable({
        "processing":true,
        "serverSide":true,
        "order":[],
        "searching" : false,
        "ajax":{
            url:"actions/fetch.php",
            type:"POST",
            data:{filter_part_id:filter_part_id}
        }

    });

</code>```

and fetch.php:

```<code>$query .= "SELECT * FROM Part_tb ";
if(isset($_POST['filter_part_id']) && $_POST['filter_part_id'] != '')
{
   $query .= "SELECT * FROM Part_tb WHERE part_id IN (SELECT pcfit_name from Part_car_fit_tb WHERE pcfit_id ='".$_POST["filter_part_id"]."') ";
}
</code>```

but dataTable crashes, when #sub3_category_item is selected. Any idea, how to filter datatable with the value $_POST["filter_part_id"]?

Body:
I want to display table's data with jQuery DataTable and sometimes apply an extra data filtering, using the output of a dropdown select input.

The main code for fetching data (fetch.php) is:

<?php
include('db.php');
include('function.php');
$query = '';
$output = array();
$query .= "SELECT * FROM Part_tb ";
if(isset($_POST["search"]["value"]))
{
    $query .= 'WHERE part_manufacturer LIKE "%'.$_POST["search"]["value"].'%" ';
    $query .= 'OR part_id LIKE "%'.$_POST["search"]["value"].'%" ';
}
if(isset($_POST["order"]))
{
    $query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' ';
}
else
{
    $query .= 'ORDER BY part_id ASC ';
}
if($_POST["length"] != -1)
{
    $query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
}
$statement = $connection->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$data = array();
$filtered_rows = $statement->rowCount();
foreach($result as $row)
{
    $sub_array = array();
    $sub_array[] = $row["part_manufacturer"];
    $sub_array[] = $row["part_id"];
    $sub_array[] = $row["part_category"];
    $sub_array[] = $row["part_stock"];
    $data[] = $sub_array;
}
$output = array(
    "draw"              =>  intval($_POST["draw"]),
    "recordsTotal"      =>  $filtered_rows,
    "recordsFiltered"   =>  get_total_all_records(),
    "data"              =>  $data
);
echo json_encode($output);
?>

while the DataTable is defined in index.php as follows:

    var dataTable = $('#user_data').DataTable({
        "processing":true,
        "serverSide":true,
        "order":[],
        "ajax":{
            url:"actions/fetch.php",
            type:"POST"
        },
        "columnDefs":[
            {
                "targets":[0, 1],
                "orderable":false,
            },
        ],

    });

In index.php, i've created 3 dependent dropdown lists, which load data from other tables. Now, i want to take the id of 3rd dropdown list and update the data of Part_tb in fetch.php accordingly. Below, you can see that when 3rd dropdown change, i call a function load_parts():

  $(document).on('change', '#sub3_category_item', function(){
    load_parts();
  });

    function load_parts()
    {
    var action = 'fetch_data';
    var filter_part_id = $('#sub2_category_item').val();
        $.ajax({
            url:"actions/fetch.php",
            method:"post",
            data:{action:action, filter_part_id:filter_part_id},
            success:function(data)
            {
                $('#user_data').DataTable().ajax.reload();
            }
        });
    }

The problem is that i can't filter the data of fetch.php according to the selected id of #sub2_category_item. Could you help me on that?

I've modified the index.php as follows:

      $(document).on('change', '#sub3_category_item', function(){
    var filter_part_id = $('#sub3_category_item').val();
    $('#user_data').DataTable().destroy();
    fill_datatable(filter_part_id);
    });

    fill_datatable();

    function fill_datatable(filter_part_id = '')
    {
    var dataTable = $('#user_data').DataTable({
        "processing":true,
        "serverSide":true,
        "order":[],
        "searching" : false,
        "ajax":{
            url:"actions/fetch.php",
            type:"POST",
            data:{filter_part_id:filter_part_id}
        }

    });

and fetch.php:

$query .= "SELECT * FROM Part_tb ";
if(isset($_POST['filter_part_id']) && $_POST['filter_part_id'] != '')
{
   $query .= "SELECT * FROM Part_tb WHERE part_id IN (SELECT pcfit_name from Part_car_fit_tb WHERE pcfit_id ='".$_POST["filter_part_id"]."') ";
}

but dataTable crashes, when #sub3_category_item is selected. Any idea, how to filter datatable with the value $_POST["filter_part_id"]?


问:
Workbox and service worker, how do I get the errors in the service worker to the client?
I switched to Workbox to avoid trouble with updating the client. I like it very much, but I do not understand how to implement error handling. I know how to do it without Workbox, but I thought that errors automatically would be sent from the service worker to the client when using Workbox.

However it does not.

When I noticed this I tried the usual serviceWorker.onerror but I could not get it to work with Workbox. Could anyone please point me to a piece of code implementing this?

EDIT: I am using Workbox both in the client and the service worker.


问:
Trouble while trying to return page with error messages from entity fields
I have field like this:

```<code>@Min(value = 0, message = "Amount must be positive")
private double amount;
</code>```

When I populate form and insert for example -1 for that field I get message on stack trace that I entered wrong value and this on HTML page: This application has no explicit mapping for /error, so you are seeing this as a fallback. So that works fine, but I want to create a error for user so he actually know what error he got, I want to display error on HTML page for him.

Followed by some tutorial in my Thymeleaf I have added this:

```<code><div>
   <label for="amount">Amount</label> <input type="text" th:field="*{amount}" id="amount">
    <p th:if="${#fields.hasErrors('amount')}"
       th:class="${#fields.hasErrors('amount')}? error">Invalid amount</p>
</div>
</code>```

And in my controller I have this:

```<code> if (result.hasErrors()) {
        return "new_transaction";
    }
</code>```

Now I will provide both controllers, one for showing form and one for processing form.

Controller to show form:

```<code>@GetMapping("/showNewTransactionForm/{id}")
public String showNewTransactionForm(@PathVariable(value = "id") long id, Transaction transaction, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();
    model.addAttribute("userId", userId);

    model.addAttribute("transaction", transaction);
    model.addAttribute("transactionType", TransactionType.values());
    model.addAttribute("expenseCategories", ExpenseCategories.values());
    model.addAttribute("incomeCategories", IncomeCategories.values());

    return "new_transaction";

}
</code>```

Controller to process form:

```<code> @PostMapping("/saveExpense/{walletId}")
public String saveExpense(@PathVariable(value = "walletId") long walletId,
                          @ModelAttribute("wallets") Transaction transaction, BindingResult result) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();
    if (result.hasErrors()) {
        return "new_transaction";
    }

    Wallet wallet = walletService.getWalletById(walletId);

    transaction.setWallet(wallet);
    transactionService.saveExpense(transaction, walletId, userId);
    return "redirect:/api/wallet/userWallet/balance/" + userId;
}
</code>```

And I obviously have a problem to return a right point here:

```<code>if (result.hasErrors()) {
        return "new_transaction";
    }
</code>```

Instead of new_transaction I tried with return "redirect:/api/transaction/showNewTransactionForm/" + userId;  but as before I get a error message in stacktrace but on html is Whitelabel Error Page

Body:
I have field like this:

@Min(value = 0, message = "Amount must be positive")
private double amount;

When I populate form and insert for example -1 for that field I get message on stack trace that I entered wrong value and this on HTML page: This application has no explicit mapping for /error, so you are seeing this as a fallback. So that works fine, but I want to create a error for user so he actually know what error he got, I want to display error on HTML page for him.

Followed by some tutorial in my Thymeleaf I have added this:

   Amount <input type="text" th:field="*{amount}" id="amount">

Invalid amount

And in my controller I have this:

 if (result.hasErrors()) {
        return "new_transaction";
    }

Now I will provide both controllers, one for showing form and one for processing form.

Controller to show form:

@GetMapping("/showNewTransactionForm/{id}")
public String showNewTransactionForm(@PathVariable(value = "id") long id, Transaction transaction, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();
    model.addAttribute("userId", userId);

    model.addAttribute("transaction", transaction);
    model.addAttribute("transactionType", TransactionType.values());
    model.addAttribute("expenseCategories", ExpenseCategories.values());
    model.addAttribute("incomeCategories", IncomeCategories.values());

    return "new_transaction";

}

Controller to process form:

 @PostMapping("/saveExpense/{walletId}")
public String saveExpense(@PathVariable(value = "walletId") long walletId,
                          @ModelAttribute("wallets") Transaction transaction, BindingResult result) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();
    if (result.hasErrors()) {
        return "new_transaction";
    }

    Wallet wallet = walletService.getWalletById(walletId);

    transaction.setWallet(wallet);
    transactionService.saveExpense(transaction, walletId, userId);
    return "redirect:/api/wallet/userWallet/balance/" + userId;
}

And I obviously have a problem to return a right point here:

if (result.hasErrors()) {
        return "new_transaction";
    }

Instead of new_transaction I tried with return "redirect:/api/transaction/showNewTransactionForm/" + userId;  but as before I get a error message in stacktrace but on html is Whitelabel Error Page