#StackBounty: #javascript #jquery #html #summernote Maintain cursor location when switching between normal and code view

Bounty: 50

When switching to code view in Summernote, the cursor is always moved all the way to end of the document. Is there any way to keep the cursor location when switching? Sometimes the people who use it want to write some custom HTML because it’s faster than using the editor’s buttons, but after switching to code view, they have to scroll up and try to find where they were before. It’s not very practical.

Here’s a simple stackblitz for this.

Basically, what I need to achieve is: when the cursor is here
enter image description here

I want to click the “code view” button and go here:
enter image description here


Get this bounty!!!

#StackBounty: #javascript #html #security #server-sent-events EventSource / SSE (Server-Sent-Events) – Security

Bounty: 100

I followed This Thread, but I as I have not fully understood the answer in my case, I would like to post again.

I am using EventSource in my Front-End and the Backend is using echo event to stream data relatively to a drone to my application.

var source = new EventSource(`blabla:3000/sse?channel=myProject${projectID}`);
source.addEventListener(`myDrone${droneID}`, function(e){
    console.log('Received an update message:', e.data);
});

In the backend, by default nothing is streaming, and a user on connection will request to the backend to start emitting events. This call is secured using jwt_token. So to make the server start stream, a token is needed.

The question I have is, when a server is already streaming.

Let’s say I am a not connected (so no valid token), and I decided to connect to the SSE stream because I know the channel name and the server is already streaming. If I start a new EventSource on blabla:3000/sse?channel=myProject${projectID}. Would I still be able to see all of the message sent trough this channel? I believe that yes.

How is it possible to secure those event streamed to be only on registered user ?

Ex : (read from top to bottom)

enter image description here

How can I prevent a user that know the channelName to receive all the event stream by the server ?

Since the front end and backend are hosted on the same domain at the moment, but this might change, so I need a broad answer.


Get this bounty!!!

#StackBounty: #javascript #html #css #swift #wkwebview WKWebView – prevent automatic scrolling triggered by user text selection

Bounty: 50

When a user performs a tap and hold gesture to select a word and then drags their finger towards either the top or bottom edges of the screen, the page automatically scrolls in order to accommodate the selection.

here is a short clip demonstrating it

I would like to prevent this behavior inside a WKWebView.

Here is what I have tried so far:

in a bridge.js file which is accessible to the webview:

var shouldAllowScrolling = true;

document.addEventListener('selectionchange', e => {
    shouldAllowScrolling = getSelectedText().length === 0;
    window.webkit.messageHandlers.selectionChangeHandler.postMessage(
        {
            shouldAllowScrolling: shouldAllowScrolling
        });
    console.log('allow scrolling = ', shouldAllowScrolling);
});

and then in a WKScriptMessageHandler implementation:

public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
    {
        switch message.name
        {
        case "selectionChangeHandler":
            let params = paramsDictionary(fromMessageBody: message.body)
            let shouldEnableScrolling = params["shouldAllowScrolling"] as? Bool ?? true
            cell?.webView.scrollView.isScrollEnabled = shouldEnableScrolling
            cell?.webView.scrollView.isUserInteractionEnabled = shouldEnableScrolling // not together with the line above 
        default:
            fatalError("(#function): received undefined message handler name: (message.name)")
        }
    }

Similarly, I have tried calling the preventDefault() function directly in the javascript file for a bunch of events, namely scroll and touchmove, like so:

document.addEventListener('touchmove', e => {
    if (!shouldAllowScrolling) {
        e.preventDefault()
    }
}, {passive: false});

both methods successfully prevent scrolling when some text is selected but do not override the behavior described at the very top of my question.

I can accept solutions in either Swift and JavaScript or a mix of both.


Get this bounty!!!

#StackBounty: #javascript #android #jquery #html #amp-html amp app banner does not show in android and IOS device working fine

Bounty: 50

I am using following code below which is not showing AMP app banner

Here is example: https://playground.amp.dev/?url=https%3A%2F%2Fpreview.amp.dev%2Fdocumentation%2Fexamples%2Fcomponents%2Famp-app-banner&format=websites&_gl=1*1tf5qvf*_ga*YW1wLTQwNW9GM3l3NXZwWkVtSC1kVFo3bEE.&mode=Galaxy+S5
https://cdn.ampproject.org/v0/amp-app-banner-0.1.js
<meta name="apple-itunes-app" content="app-id=828256236, app-argument=medium://p/9ea61abf530f">
<link rel="manifest" href="/amp-app-banner-manifest.json">

{
  "prefer_related_applications": true,
  "related_applications": [
    {
      "platform": "play",
      "id": "com.medium.reader",
      "url": "android-app://com.medium.reader/https/medium.com/p/cb7f223fad86"
    }
  ]
}


Get this bounty!!!

#StackBounty: #javascript #c# #html #chromium #cefsharp Using CEFSharp to edit <textarea>

Bounty: 50

I am able to edit a regular textbox within an iFrame in CefSharp like so:

Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('ElementID').value=" + ''' + "1234" + ''');

However, because a textarea doesn’t have a value:

<iframe id="iFrame1" name="iFrame1">
    <textarea name="txtareaname" id="txtareaname1">sometexthere</textarea>
</iframe>

I am unable to execute a similar line of code to edit the text in the textarea:

textarea.Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('txtareaname1').value=" + ''' + "1234" + ''');

I have also tried:

textarea.Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('txtareaname1').innertext=" + ''' + "1234" + ''');

How do I adjust my code to edit this textarea?


Get this bounty!!!

#StackBounty: #html #firefox #multifile-uploader #filepicker HTML filepicker multi – get files in use

Bounty: 50

The following problem occured using Firefox v73 on Window 7:

In my code i use a multi-file-picker in html to upload up to 100-files parallal:

<input type="file" id="files" name="files" multiple>

The files will be sent to a REST-API which process them afterwards.
When i select a single file (in the file-explorer) which is currently in use, i get a error-message (probably by window) which tells me, that the file cannot be picked because it is in use.
If i try to pick multiple-files which contain one or more files in use, i have no error occuring but the upload seems to stop when the file-in-use is reached and waiting for the file to be released.
This leads to request to wait for a timeout (which is 1 minute in my case).

Is there any option to catch the problem (in use file) before trying to upload the files?

PS: I’ve tried the same in Chrome and it returns a error before sending the request to the REST-API.


Get this bounty!!!

#StackBounty: #javascript #html #canvas Detecting when mouse is outside of a certain position

Bounty: 50

When a mouse is hovering a image. It gets detect by this if statement:

if ((distance(circles[this.index].x, circles[this.index].y, mouse.x, mouse.y)) < circles[this.index].radius)

I also want to detect when a mouse it outside a image.
After that previous if statement I cannot use else the reason is because:

When I generate multiple images on screen and when my mouse if hovering over 1 image. It does hover of that image and the code detects it but it also doesnt hover of all the other images. That is the reason that is display 4 times “outside circle” and 1 time “inside circle”

As seen in the log:

Console.log output:

Mouse inside circle 
Mouse outside circle 4 
Mouse inside circle 
Mouse outside circle 4 

Im looking for a way the detect when the mouse is leaving a circle.

You can find the code I’m working with below:

PS: it it important that it detect in what (index) circle the mouse is and leaves.
I want to create a huge amount of pictures, but in the code below I used 5 for demo purpeses.

var mouse = {
    x: innerWidth / 2,
    y: innerHeight / 2
};

// Mouse Event Listeners
addEventListener('mousemove', event => {
    mouse.x = event.clientX;
    mouse.y = event.clientY;
});

//Calculate distance between 2 objects
function distance(x1, y1, x2, y2) {
    let xDistance = x2 - x1;
    let yDistance = y2 - y1;
    return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
}


// Sqaure to circle
function makeCircleImage(radius, src, callback) {
    var canvas = document.createElement('canvas');
    canvas.width = canvas.height = radius * 2;
    var ctx = canvas.getContext("2d");
    var img = new Image();
    img.src = src;
    img.onload = function() {
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        // we use compositing, offers better antialiasing than clip()
        ctx.globalCompositeOperation = 'destination-in';
        ctx.arc(radius, radius, radius, 0, Math.PI*2);
        ctx.fill();
        callback(canvas);
    };
}


function Circle( x, y, radius, index ) {
    //Give var for circle
    this.x = x;
    this.y = y;
    this.dx = 1;
    this.dy = 1;
    this.radius = radius;
    this.index = index;
}
// use prototyping if you wish to make it a class
Circle.prototype = {
//Draw circle on canvas
    draw: function () {
        var
            x = (this.x - this.radius),
            y = (this.y - this.radius);
        // draw is a single call
        c.drawImage( this.image, x, y );
    },

    //Updates position of images
    update: function () {
        var
            max_right = canvas.width + this.radius,
            max_left = this.radius * -1;
        this.x += this.dx;
        if( this.x > max_right ) {
            this.x += max_right - this.x;
            this.dx *= -1;
        }
        if( this.x < max_left ) {
            this.x += max_left - this.x;
            this.dx *= -1;
        }


        if ((distance(circles[this.index].x, circles[this.index].y, mouse.x, mouse.y)) < circles[this.index].radius) {
            // Mouse inside circle
            console.log("Mouse inside circle")

        } else{
            //The mouse is in one circle
            //And out of 4 other circles
            console.log("Mouse outside circle")
        }
    },
    init: function(callback) {
        var url = "https://t4.ftcdn.net/jpg/02/26/96/25/240_F_226962583_DzHr45pyYPdmwnjDoqz6IG7Js9AT05J4.jpg";
        makeCircleImage( this.radius, url, function(img) {
            this.image = img;
            callback();
        }.bind(this));
    }
};

//Animate canvas
function animate() {
    c.clearRect(0, 0, window.innerWidth, window.innerHeight);
    circles.forEach(function( circle ) {
        circle.update();
    });
    circles.forEach(function( circle ) {
        circle.draw();
    });
    requestAnimationFrame(animate);
}

//Init canvas
var canvas = document.querySelector('canvas');
var c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

//init circle objects
var circles = [
    new Circle(10, 100, 50,0),
    new Circle(10, 200, 30,1),
    new Circle(10, 300, 50,2),
    new Circle(10, 400, 50,3),
    new Circle(10, 500, 50,4)
];
var ready = 0;

circles.forEach(function(circle) {
    circle.init(oncircledone);
});

function oncircledone() {
    if(++ready === circles.length) {
        animate()
    }
}
<canvas></canvas>


Get this bounty!!!

#StackBounty: #html #angular #typescript How to create multilevel dropdown list and bind with data coming from server

Bounty: 200

I am very new to Angular. I have got some work on Angular.

I need to bind Nested dropdown list for Json data which is coming from server by calling Rest Api.

Data has one attribute LgLevel, Specifies the level in the hierarchy of the group. Parent
will have level=0, Immediate Child=1, Grandchild=2 and so on. Child and Grandchild has ParentLocationGroup field, which shows inside which parent menu, child menu will be there.

This is my json data. I have huge data but not showing all.

{
"ArrayOfLocationGroup": {
  "LocationGroup": [
     {
        "Id": "628",
        "Name": "TEST1",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources"
        },
        "ParentLocationGroup": {
           "_uuid": "bdce4396-9c60-4831-90f2-6f793becb362",
           "__text": "570"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "0"
        }
     },
     {
        "Id": "630",
        "Name": "TEST2",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "PAM-TEST"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "631",
        "Name": "TEST3",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "PAA-TEST"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "697",
        "Name": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "TEST4"
        },
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "PAE-TEST"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "700",
        "Name": "TEST5",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "cuba"
        },
        "ParentLocationGroup": {
           "_uuid": "704af4cf-9feb-4f1b-aa00-d1c7926f7901",
           "__text": "694"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "2"
        }
     },
     {
        "Id": "706",
        "Name": "TEST5",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "VOIP-Test"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "718",
        "Name": "TEST7",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "719",
        "Name": "TEST8",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "MEM_RS"
        },
        "ParentLocationGroup": {
           "_uuid": "52073e2b-48b5-41a9-9c2b-d793835cf285",
           "__text": "718"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "2"
        }
     },
     {
        "Id": "752",
        "Name": "TEST9",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "ELDIT"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "753",
        "Name": "TEST10",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "GXYA"
        },
        "ParentLocationGroup": {
           "_uuid": "52073e2b-48b5-41a9-9c2b-d793835cf285",
           "__text": "718"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "2"
        }
     },
     {
        "Id": "760",
        "Name": "TEST11",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "STAGE2"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "761",
        "Name": "TEST12",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "INIT"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     },
     {
        "Id": "762",
        "Name": "TEST13",
        "GroupId": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "USIT"
        },
        "ParentLocationGroup": {
           "_uuid": "894055b6-b132-4dc2-a12a-971ecc0c7224",
           "__text": "628"
        },
        "LgLevel": {
           "_xmlns": "http://www.air-watch.com/servicemodel/resources",
           "__text": "1"
        }
     }
  ],
  "_xmlns:xsd": "http://www.w3.org/2001/XMLSchema"
}
}

I have tried it to develop but I found all examples of bootstrap with static data in html file and separate CSS file which was complicated to me.

I want to do it dynamically using TypeScript. How can I start working on it.

Edit1:

When I am using original data coming from service, getting below op

Dropdown
 GEOIS-LEO-TEST

only getting parent most record but as per your code all variables getting filled with values while debugging. This is my code

  ngOnInit() {

    this.employeeService.getGroups().subscribe((dataG:any) => {
      console.log("groups  "+dataG);
     this.sampleData=dataG; 
     this.getData();
    });
  }

  groupBy(xs, key) {
    return xs.reduce(function (rv, x) {
      (rv[x[key]] = rv[x[key]] || []).push(x);
      return rv;
    }, {});
  }

  getData() {
    this.locGroup = this.sampleData ;
    var formattedList = [];
    console.log(this.sampleData);

    this.locGroup.forEach(element => {

      var obj = {
        "Id": element.Id,
        "Name": element.Name,
        "GroupId": element.GroupId,
        "ParentLocationGroup": element.ParentLocationGroup,
        "LgLevel": element.LgLevel,
        "Child" : []
      }

      formattedList.push(obj);
    });

    console.log("flist "+ formattedList);
    var groupDataList = this.groupBy(formattedList, "LgLevel");
    var parents = groupDataList[0];
    var child = groupDataList[1];
    var childOfChild = groupDataList[2];

    child.forEach(c => {
      c.Child = childOfChild.filter(x => x.ParentLocationGroup == c.Id);
    })

    parents.forEach(item => {
    item.Child = child.filter(x => x.ParentLocationGroup == item.Id);
    })

    this.model = parents;
  }

These are my model classes to deserialize json

export interface LocationGroup {
    Id: string;
    Uuid: string;
    Name: string;
    GroupId: string;
    LocationGroupType: string;
    Country: string;
    Locale: string;
    ParentLocationGroup: string;
    CreatedOn: string;
    LgLevel: string;
    Users: string;
    Admins: string;
    Devices: string;
}

export interface ArrayOfLocationGroup {
    LocationGroup: LocationGroup[];
}

Here you can find my json
https://textuploader.com/16fty


Get this bounty!!!

#StackBounty: #javascript #html #css #css-animations #onscroll How to get exact scroll position when animating elements onScroll

Bounty: 100

I am trying to animate elements while scrolling based on the elements progress through the scene. I am running into the issue of the browser returning intermittent scroll positions making it difficult to be exact when starting and stopping element animation.

Minimal example:

Fiddle Fiddle Demo

const tweens = document.querySelectorAll('.tween');
const trigger = document.querySelector('.start');
const triggerRect = trigger.getBoundingClientRect();

let yScroll = window.scrollY;
let yCurrent = yScroll;
let AF = null;

const start = triggerRect.top - yScroll - 200;
const end = start + 400;

const updateScroll = () => {
    yScroll = window.scrollY;
  startAnimation();
}

const startAnimation = () => {
  if(!AF) AF = requestAnimationFrame(animate)
}

const cancelAnimation = () => {
  yCurrent = yScroll;
  cancelAnimationFrame(AF);
  AF = null;
}

const animate = () => {
  if(yCurrent === yScroll) cancelAnimation();
  else {
    updateElements();
    yCurrent = yScroll;
    AF = requestAnimationFrame(animate);
  }
}

const updateElements = () => {
  const pos = yCurrent - start;
  if(inScene()){
    tweens[0].style.transform = `translateX(${pos}px)`;
    tweens[1].style.transform = `translateY(${pos}px)`;
  }
}

const inScene = () => {
  return start <= yCurrent && end >= yCurrent ? true : false;
};


window.addEventListener('scroll', updateScroll);
.wrapper{
  position:relative;
  margin: 100vh 20px;
  background: rgb(240,240,240);
  height: 900px;
  border: 1px solid red;
}

.line{
  position:absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: red;
}

.start{
  top: 200px;
}

.end{
  bottom: 200px;
}

.tween{
  position:absolute;
  top:200px;
  width: 100px;
  height: 100px;
  background: blue;
}

.left{
  left: 0;
}

.right{
  right: 0;
}
<h1>Scroll Down</h1>
<div class="wrapper">
  <div class="line start trigger"></div>
  <div class="line end"></div>
  <div class="tween left"></div>
  <div class="tween right"></div>
</div>

As you can see the elements are supposed to stop on the lines but when you scroll they never really do. And the faster you scroll the worse it becomes.

So is there a technique to either return the correct scroll position or somehow debounce the elements so then can reach the full range when scrolling instead of constantly coming up short of their intended position?

I know this is possible because scrolling libraries like ScrollMagic do a pretty good job of handling this but I don’t really want to deconstruct then entire ScrollMagic framework to find out how they achieve it. I would use the ScrollMagic framework itself but I am trying to have a momentum style scrolling container wrapping the page and translating it on scroll along with elements inside this container and using ScrollMagic it is pretty buggy. So I figured I would post the question here and see if anyone had any experience or insight on the situation.

Any guidance would be appreciated as I have been mulling over this for a while.


Get this bounty!!!

#StackBounty: #jquery #html #fancybox #fancybox-2 Fancybox 2.1 loading AJAX template leaving large gap at the top, but this problem doe…

Bounty: 100

On my eCommerce website, I am using Fancybox to load the shopping cart upon someone clicking the add to cart button. This works without issues. The page does not jump to the top in the background, and the modal cart window is always displayed in the center, or at the top when the page height is not enough. There is only ever a Top: 20px on this cart modal and you cannot scroll up any further.

Here is the code I’m using for the Fancybox modal shopping cart (which works perfectly):

(function ($, F) {

    // Opening animation - fly from the top
    F.transitions.dropIn = function() {

        var endPos = F._getPosition(true);

        endPos.top = (parseInt(endPos.top, 10) - 50) + 'px';
        endPos.opacity = 0;

        F.wrap.css(endPos).show().animate({
            top: '+=50px',
            opacity: 1
        }, {
            duration: F.current.openSpeed,
            complete: F._afterZoomIn
        });
    };

    // Closing animation - fly to the top
    F.transitions.dropOut = function() {
        F.wrap.removeClass('fancybox-opened').animate({
            top: '-=50px',
            opacity: 0
        }, {
            duration: F.current.closeSpeed,
            complete: F._afterZoomOut
        });
    };

}(jQuery, jQuery.fancybox));

$(".cart-button").fancybox({
maxWidth    : 700,
maxHeight   : 600,
fitToView   : false,
width       : '100%',
height      : '70%',
autoSize    : false,
autoDimensions: false,
autoCenter : true,
closeClick  : false,
openMethod:'dropIn',
openSpeed:200,
closeMethod:'dropOut',
closeSpeed:200,
helpers : {
  overlay : {
      locked : true // try changing to true and scrolling around the page
  }
}
});

Now I need to use Fancybox in another way which involves loading a page template via AJAX when a button is clicked. Unlike the modal cart, this page template is long enough that it will always exceed the visible page height. The issue is that it keeps assigning Top: 632px (varies) to the Fancybox modal, whichthen leaves a large empty spot at the top. That said, it does display the Fancybox modal at the top of the screen with a 20px space at the top (like the cart), however, the user can keep scrolling up to view the additional 600+px of empty space a the top (the dark overlay is seen in this space). This problem seems to only happen on Desktop, as it behaves just fine on mobile.

Here is the code I’m using for loading the template via Fancybox:

$(document).ready(function() {
  $(".trees-modal-button").click(function(e) {
    e.preventDefault();
    $.fancybox({
        maxWidth    : 700,
        maxHeight   : 600,
        fitToView   : false,
        width       : '100%',
        height      : '70%',
        autoSize    : false,
        autoDimensions: false,
        autoCenter : true,
        closeClick  : false,
        openMethod:'dropIn',
        openSpeed:200,
        closeMethod:'dropOut',
        closeSpeed:200,
        helpers : {
          overlay : {
              locked : true // try changing to true and scrolling around the page
          }
        },
        content: `<div class="loading-directive" style="display: block; position: relative; margin: 
        auto;">
         <div class="loader">
           <svg class="circular">
            <circle class="path" cx="32" cy="32" r="30" fill="none" stroke-width="4">
            </circle>
           </svg>
         </div>
       </div>`
      });

    $.get('/pages/tree-planting-temp-noindex', null, function(data) {
        $.fancybox({
          maxWidth  : 700,
          maxHeight : 600,
          fitToView : false,
          width     : '100%',
          height        : '70%',
          autoSize  : false,
          autoDimensions: false,
          autoCenter : true,
          closeClick    : false,
          openMethod:'dropIn',
          openSpeed:200,
          closeMethod:'dropOut',
          closeSpeed:200,
          content: data,
          helpers : {
            overlay : {
                locked : true // try changing to true and scrolling around the page
            }
          }
        });
      }
    )
  })
}) 

It first opens the modal popup with a loading animation, and then displays the template when ready. I used the same Fancybox variables as the shopping cart, so I’m not sure what the issue is.

Worth mentioning that if I force the CSS to be Top: 20px to override the large value generated by the Fancybox modal, the modal will just pop to the very top of the page, and then you have to scroll up to see top of the modal.

Your help is most appreciated.


Get this bounty!!!