How to fake highlight selection in textarea after losing focus [duplicate]

I want to put a fake highlight on selected text in a textarea after the textarea loses focus. I have explored a few options. The cleanest so far is cloning the textarea to div and wrapping selection with span. But that still has some quirks and doesn’t handle some edge cases. I have also tested a couple of jQuery libraries like this, but not as clean as I want. Is there any other clean way?

How to load data to a combo box or rad combo box in a Asp Repeater control using jquery

I want to reload data to a combo box (I’m using a rad combo box) in a asp.net repeater control which is in An update panel using jquery or javascript. I’m getting the required data from a web method and converting it to an object array like [id:1, name:john]. The attribute for id is ‘DataValueField’ and text is ‘DataTextField’. Is there a way I can do this in jquery ?

Uncaught TypeError: Cannot read properties of undefined (reading ‘value’)

I have been trying to integrate PayPal in my e-commerce project. It works fine in Paypal button but I have problems in making the transaction complete.

After clicking “Pay Now” in the sandbox, the money goes through but the transaction in my database was not completed.

Here’s my checkout.html file:

{% extends 'store/main.html' %}
{% load static %}
{% block content %}
     <div class="row">
        <div class="col-lg-6">
            <div class="box-element" id="form-wrapper">
                <form id="form">
                    <div id="user-info">
                        <div class="form-field">
                            <input required class="form-control" type="text" name="name" placeholder="Name..">
                        </div>
                        <div class="form-field">
                            <input required class="form-control" type="email" name="email" placeholder="Email..">
                        </div>
                    </div>
                    
                    <div id="shipping-info">
                        <hr>
                        <p>Shipping Information:</p>
                        <hr>
                        <div class="form-field">
                            <input class="form-control" type="text" name="address" placeholder="Address..">
                        </div>
                        <div class="form-field">
                            <input class="form-control" type="text" name="city" placeholder="City..">
                        </div>
                        <div class="form-field">
                            <input class="form-control" type="text" name="state" placeholder="State..">
                        </div>
                        <div class="form-field">
                            <input class="form-control" type="text" name="zip" placeholder="zip code..">
                        </div>
                    </div>

                    <hr>
                    <input id="form-button" class="btn btn-success btn-block" type="submit" value="Continue">
                </form>
            </div>

            <br>
            <div class="box-element hidden" id="payment-info">
                <small>Paypal Options</small>

                <div id="paypal-button-container"></div>
            </div>
            
        </div>

        <div class="col-lg-6">
            <div class="box-element">
                <a  class="btn btn-outline-dark" href="{% url 'cart' %}">&#x2190; Back to Cart</a>
                <hr>
                <h3>Order Summary</h3>
                <hr>
                {% for item in items %}
                    <div class="cart-row">
                        <div style="flex:2"><img class="row-image" src="{{item.product.imageURL}}"></div>
                        <div style="flex:2"><p>{{item.product.name}}</p></div>
                        <div style="flex:1"><p>₱{{item.product.price|floatformat:2}}</p></div>
                        <div style="flex:1"><p>x{{item.quantity}}</p></div>
                    </div>
                {% endfor %}
                <h5>Items:   {{order.get_cart_items}}</h5>
                <h5>Total:   ₱{{order.get_cart_total|floatformat:2}}</h5>
            </div>
        </div>
    </div>


<script src="https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD"></script>

<script>
    var total = '{{order.get_cart_total}}'
    // Render the PayPal button into #paypal-button-container
    paypal.Buttons({

        style:{
            //color: 'blue',
            shape: 'rect',
        },

        // Set up the transaction
        createOrder: function(data, actions) {
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: parseFloat(total).toFixed(2)
                    }
                }]
            });
        },

        // Finalize the transaction
        onApprove: function(data, actions) {
            return actions.order.capture().then(function(orderData) {
                submitFormData()
            });
        }


    }).render('#paypal-button-container');
</script>

<script type="text/javascript">
    var shipping = '{{order.shipping}}'
    var user = '{{request.user.is_authenticated}}'
    

    if(shipping == 'False'){
        document.getElementById('shipping-info').innerHTML = ''
    }

    if (user != "False"){
        document.getElementById('user-info').innerHTML = ''
    }

    if (shipping == 'False' && user != "False"){
        //Hide entire form if user is logged in and shipping is false
        document.getElementById('form-wrapper').classList.add('hidden');
        //Show payment if logged in user wants to buy an item that does not require shipping
        document.getElementById('payment-info').classList.remove('hidden');
    }

    var form = document.getElementById('form')
    
    form.addEventListener('submit', function(e){
        e.preventDefault()
        console.log('Form Submitted...')
        document.getElementById('form-button').classList.add("hidden");
        document.getElementById('payment-info').classList.remove("hidden");
    })

    /*document.getElementById('make-payment').addEventListener('click', function(e){
        submitFormData()
    })
    */

    function submitFormData(){
        console.log('Payment button clicked')

        var userFormData = {
            'name':null,
            'email':null,
            'total':total,
        }

        var shippingInfo = {
            'address':null,
            'city':null,
            'state':null,
            'zip':null,
        }

        if (shipping != 'False'){
            shippingInfo.address = form.address.value
            shippingInfo.city = form.city.value
            shippingInfo.state = form.state.value
            shippingInfo.zip = form.zip.value
        }

        if (user != 'True'){
            userFormData.name = form.name.value
            userFormData.email = form.email.value
        }

        var url = '/process_order/'
        fetch(url,{
            method:'POST',
            headers:{
                'Content-Type':'application/json',
                'X-CSRFToken':csrftoken,
            },
            body:JSON.stringify({'form':userFormData, 'shipping':shippingInfo})
        })

        .then((response) => response.json())
        .then((data) => {
            console.log('Success:', data);
            alert('Transaction Completed');

            cart ={}
            document.cookie = 'cart=' + JSON.stringify(cart) + ";domain=;path=/"

            window.location.href = "{% url 'store' %}"
        })
         
    }

</script>

{% endblock content %}

The error was in my console. This is the error:

Uncaught TypeError: Cannot read properties of undefined (reading 'value')
    at submitFormData (http://127.0.0.1:8000/checkout/:207:36)
    at http://127.0.0.1:8000/checkout/:140:5
    at e.n.dispatch (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:15659)
    at e.n.resolve (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:14716)
    at e.n.dispatch (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:16040)
    at e.n.resolve (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:14716)
    at https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:15526
    at e.n.dispatch (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:15659)
    at e.n.resolve (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:14716)
    at e.n.dispatch (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:16040)

Error: Cannot read properties of undefined (reading 'value')
    at Pr.error (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:71786)
    at Object.<anonymous> (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:80160)
    at JSON.parse (<anonymous>)
    at Ir.o (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:80019)
    at Ir (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:80172)
    at Yr.u.on (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:84738)
    at Yr (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:84858)
    at https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:91179
    at Function.e.try (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:18264)
    at https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:90976

Error: Cannot read properties of undefined (reading 'value')
    at Pr.error (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:71786)
    at Array.<anonymous> (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:80160)
    at JSON.parse (<anonymous>)
    at Ir.o (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:80019)
    at Ir (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:80172)
    at Yr.u.on (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:84738)
    at Yr (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:84858)
    at https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:91179
    at Function.e.try (https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:18264)
    at https://www.paypal.com/sdk/js?client-id=AVESrMsFLVbGdGrS_eWIIpWsK0Yu-W0_3kWU64V7t6LhL8mlMtduwiMZ4bt4yusZLInbf_Q7_64b0oAi&currency=USD:2:90976

It was saying that there’s an error in my submitFormData() or JavaScript. But I cannot find what is the problem.

Add class based on dynamical url parameter (click and load)

I have a php script that allows me to dynamically load content on my page based on the url paramter. Also, I have .htaccess set up so the query string prefix is hidden, meaning they look like example.com/games/demons-souls/[?page=]mods.

[?page=] is hidden via .htaccess. So far, so good.

<?php

if (!empty($_GET["page"])

    && preg_match("/^[a-z]+$/i", $_GET["page"]) == 1

    && file_exists($pageFile = __DIR__ . "/subpages/" . $_GET["page"] . ".php")) {

    include $pageFile;

}

else {

    include __DIR__ . "/subpages/game.php";

}

?>

Now I wanted to show which page is active in a tabpanel, where the active tab is let’s say black. So I’d need to activate the class tab.current. And to do this I need to somehow make my code recognize which url paramter is loaded and dynamically add the .current class to the appropriate tab. I hope I could explain it well enough.

I haven’t got the slightest idea how to accomplish this.

Please help.

Adjust width of absolute element based on relative parent layout changes

I’m making a ball bounce from div to div(with .bounce-on). In order to do that, I’m using absolute divs (with .orbit) positioned with JS to make the ball bounce from the middle to the middle of each div.

Here is the codepen: https://codepen.io/wearysigninup/pen/rNpNmoZ

.css-container{
  position:relative;
  text-align:center;
}

.orbit{
  top: -20px;
  position: absolute;
  width: 50px;
  height:50px;
  border: black 1px solid;
  border-radius:50%;
  transform: rotate(0deg);
}
<div class="css-container">
  <div class="orbit">
    <div id="ball"></div>    
  </div>
  ...
  <div class="orbit"></div>
</div>

<div class="line">
   <span class="bounce-on">bounce</span>·<span class="bounce-on">bounce</span> 
   <span class="bounce-on">bounce</span> <span class="bounce-on">bounce</span>·
   <span class="bounce-on">bounce</span>
</div>

I’d like to have the div.orbit adjust their width based on changes on .bounce-on without using javascript to recalculate stuff if possible. The timing of the animation is tied to music, and I’d like it to not get out of sync.

Could anyone help with that? Is there an html markup or some css calculations that would make this possible?

Right now, I’m listening to resizing event to adjust the size but it’s getting the bouncing out of sync.

To my knowdledge, what I’m asking is not possible. But I came pretty close with svg text. Only problem with using svg, is that the event endlers are inconsistently triggered and not well supported accross browsers. Also, not very accessible.

I’m hoping it’s somehow possible to mimic the svg behavior when resizing window with css, thus my question.

CORS Error with JS google maps api in .net core app

I am trying to render Google map using JS in .net core 5 view as follows:

<div id="map"></div>

@section Scripts{

<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&callback=initMap&libraries=&v=weekly" async></script>
<script>


    function initMap() {
        // The location of Uluru
        const uluru = { lat: -25.344, lng: 131.036 };
        // The map, centered at Uluru
        const map = new google.maps.Map(document.getElementById("map"), {
            zoom: 4,
            center: uluru,
        });
        // The marker, positioned at Uluru
        const marker = new google.maps.Marker({
            position: uluru,
            map: map,
        });
    }

</script>

}

I also enable CORS in Setup.cs

 services.AddCors();

and

app.UseCors(options => options.WithOrigins("The Published website URL").AllowAnyMethod());

But in Edge console I got the following error:

enter image description here

How to set vue treeselect value with JS

I have been searching for hours with no clue about what I am doing. I am using Vue Treeselect inside my js application.

Here is the code that I am using:

<script src="js/vue@^2"></script>
<script src="js/vue-treeselect.umd.min.js"></script>
<link rel="stylesheet" href="css/vue-treeselect.min.css">

<div id="treeselect_container">
    <treeselect id="treeselect_test" name="treeselect_test" @input="onInput" v-model="value" :multiple="false" :options="options" placeholder="Select Content..." />
    <script>
        Vue.component('treeselect', VueTreeselect.Treeselect)
        new Vue({
            el: '#treeselect_container',
            data: {
                value: null,
                options: [ {
          id: 'a',
          label: 'a',
          children: [ {
            id: 'aa',
            label: 'aa',
          }, {
            id: 'ab',
            label: 'ab',
          } ],
        }, {
          id: 'b',
          label: 'b',
        }, {
          id: 'c',
          label: 'c',
        } ]
            },
            methods: {
                onInput(value, id) {
                    console.log(value, id);
                }
            }
        })
    </script>
</div>

Basically I am using the onInput method to get the value for later use, but what I am confused about is how I can select a certain value from the vue treeselect.

I found out that changing the value: null for example to value: a changes the value but the ways that I am familiar with is to reload the page and either use session data or PHP post data. But that is very messy, I know that there are many simpler ways to do it but I failed to find them.

I am new to Vue and this is the only chunk of code that I added to my page everything else is PHP mixed with jquery and plain js. Any help goes a long way. Thanks.

Convert tabular json data to d3 hierarchal data for pack chart

I have a small dataset in JSON file which I want to convert into hierarchal data format to create a circular pack chart.
This is my dataset:

{
"Marks": [
{"student": "Maria", "AI": 95, "DB": 77, "CG": 31, "ITP": 97, "LIT": 45},
{"student": "Sam", "AI": 85, "DB": 37, "CG": 39, "ITP": 45, "LIT": 55}
]
}

This is the output I am looking for:

{
"name": "Marks",
 "children": [
  { "name": "Maria",
 "children": [
  { "name": "AI" , "marks" : 95},
  { "name": "DB" , "marks" : 77},
  { "name": "CG" , "marks" : 35},
  { "name": "ITP" , "marks" : 97},
  { "name": "LIT" , "marks" : 45},
]
},
{ "name": "Sam",
 "children": [
  { "name": "AI" , "marks" : 85},
  { "name": "DB" , "marks" : 37},
  { "name": "CG" , "marks" : 39},
  { "name": "ITP" , "marks" : 45},
  { "name": "LIT" , "marks" : 55},
]
}
]
}


Any idea how I can proceed with this?

return an object with similar structured but filtered

I have the following object:

const myObject = {
"-Lz8YxHiwp8QZW3TqAFn": Object {
  "first": "Breanna",
  "last": "Blah",
},
"-Lz8YxHqQXWoaGOFRLrO": Object {
  "first": "Joshua",
  "last": "Blah",
},
"-Lz8YxHsMItaaTVNyQRE": Object {
  "first": "Joziah",
  "last": "Blah",
},
"-Lz8YxHwuVBMWl0Go6C5": Object {
  "first": "Lino",
  "last": "Blah",
},
"-Lz8YxHy0S-QkDaE1PkX": Object {
  "first": "Rebecca",
  "last": "Blah",
},
"-Lz8YxI5IItUiXX6rFn_": Object {
  "first": "Rosario",
  "last": "Blah",
},
"-Lz8YxIB_YTBF8liL855": Object {
  "first": "Alissa",
  "last": "Blah",
}
}

then I have a set with the following:

const mySet = {
  "-Lz8YxMp-V0TfiwrkM49",
  "-Lz8YxNQP2WkkO0qpkRJ",
  "-Lz8YxHy0S-QkDaE1PkX",
  "-MmFNgjyopU3E8z5g-zU",
  "-Lz8YxLVi_uZp_RkcRIH",
  "-MuEgimJOIbPw3GyKBJ3",
  "-Lz8YxOFpVHx2xPI1mUu",
  "-Lz8YxJ-_wuk8bmEyvGT",
  "-Lz8YxKj5WXY1oNwylQ4",
  "-Lz8YxN87U1YM6_fKgq1",
  "-Lz8YxOI4qszJvZhrSde",
  "-Lz8YxI5IItUiXX6rFn_",
}

I need to return myObject with ONLY the objects that match an item in mySet.
I have done this with a map but it turns myObject into an array.
The following uses map and returns an array which I can’t use for this particular situation.

// const addGroupMembers = Object.entries(members)
//   .filter(([key]) => {
//     eachHit++;
//     console.log(key)
//     return attendanceGroupMembers.has(key);
//   })
//   .map(([_, members]) => {
//     eachHit++;
//     console.log('in map')
//     return members;
//   });

I would like to retain the myObject structure but with only the items found. Any idea how I can accomplish this?

Which version of bubbleSort is correct?

There are 2 versions I have come across

V1- the second for loop has an -i as shown below

    let bubbleSortV1 = (inputArr) => {
    let len = inputArr.length;
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < (len-1-i); j++) {

            console.log("im in here with j v1 = "+ j);
            if (inputArr[j] > inputArr[j + 1]) {
                let tmp = inputArr[j];
                inputArr[j] = inputArr[j + 1];
                inputArr[j + 1] = tmp;
            }
        }
        console.log("n");

    }
    return inputArr;
};

The second version has no -i

let bubbleSortV2 = (inputArr) => {
    let len = inputArr.length;
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < (len-1); j++) {

            console.log("im in here with j v2 = "+ j);
            if (inputArr[j] > inputArr[j + 1]) {
                let tmp = inputArr[j];
                inputArr[j] = inputArr[j + 1];
                inputArr[j + 1] = tmp;
            }
        }
        console.log("n");

    }
    return inputArr;
};

The results of these two versions are as shown below with an example for reference
enter image description here

How to list and record all network requests and response times in Cypress

I am looking to convert all requests from cy.intercept() into json objects that include: {'method':'____', 'url':'____', 'response_time':'____'} so that they can be written to a json file for performance analysis.

I am currently able to show all of the request methods and URL’s but not their response times.

Current code to get network requests:

cy.intercept({method:'GET', url:'**'}).as('gets');
cy.intercept({method:'POST', url:'**'}).as('posts');
cy.visit('url');

Is it possible to iterate through these individual requests with their response times and save them within an array?

I have tried saving the value returned from intercept() as a variable but it doesn’t show all of the requests or their response times.

var gets = cy.intercept({method:'GET', url:'**'}).as('gets');
var posts = cy.intercept({method:'POST', url:'**'}).as('posts');
cy.visit('url');

cy.writefile('file1.json', gets);
cy.writefile('file2.json', posts);

Thanks in advance.

Paperjs tool seems to be working, but does not display anything

I’m trying to get a multiple tool paperjs example going that is a bit of a vector based “paint program”.

I’m trying to do this with a toolStack class from a Stack Overflow suggestion. The original post has two placeholder tools and I added another. The two native tools work fine and display, my third tool “multiLine” (which runs fine as a stand along file) seems to be working, does not throw errors in the browser, and from inspecting the results seems to have data in the structures. However the third tool doesn’t display.

I realize the syntax is different in different section of the code. Both syntaxes seem to work fine. I’m new to Javascripting so don’t know if this is an issue. Thanks in advance for any eyes or suggestions about the code.

Paul

<!-- Multiple Tools Paper Example -->

<!DOCTYPE html>
<html>
<style>
    html,
    body,
    canvas {
      width: 100%;
      height: 100%;
      margin: 0;
    }
</style>
<script>
    window.onload = () => {
      // Setup Paper
    
      paper.setup(document.querySelector('canvas'))
    
      // Toolstack
    
      class ToolStack {
        constructor(tools) {
          this.tools = tools.map(tool => tool())
        }
    
        activateTool(name) {
          const tool = this.tools.find(tool => tool.name === name)
          tool.activate()
        }
        
        
    
        // add more methods here as you see fit ...
      } 


  // Tool Path, draws paths on mouse-drag
    
      const toolPath = () => {
        const tool = new paper.Tool()
        tool.name = 'toolPath'
    
        let path
        
    
        tool.onMouseDown = function(event) {
          path = new paper.Path()
          path.strokeColor = '#4242ff'
          path.strokeWidth = 15;
          path.add(event.point)
        }
    
        tool.onMouseDrag = function(event) {
          path.add(event.point)
          console.log(path);
        }
    
        return tool
      }
    
      // Tool Circle, draws a 30px circle on mousedown
    
      const toolCircle = () => {
        const tool = new paper.Tool()
        tool.name = 'toolCircle'
    
       
    
        let path
    
        tool.onMouseDown = function(event) {
          path = new paper.Path.Circle({
            center: event.point,
            radius: 30,
            fillColor: '#9C27B0'
          })
        }
    
        return tool
      }
      
      
      // This is the tool I added which does not display
      const multiLine = () => {
        const tool = new paper.Tool()
        tool.name = 'multiLine'
      
        var values = {
                        //lines: 5,
                        lines: 4,
                        //size: 40,
                        size: 10,
                        smooth: true
                    };        
            
        var paths;     
        
        
//          tool.onMouseDown = function(event) {   // this worked for debugging the tool
//        path = new paper.Path()               
//            path.strokeColor = '#ff4242'
//            path.strokeWidth = 10  
//        path.add(event.point)
//      }
//  
//     tool.onMouseDrag = function(event) {
//        path.add(event.point)
//          }
      
      
        tool.onMouseDown = function(event) {
                        paths = [];
                        for (var i = 0; i < values.lines; i++){
                            var path = new paper.Path();
                            path.strokeColor = '#FF2222';
                            path.strokeWidth = 25;
                            paths.push(path);
                            console.log(i);
                        }
                    }
                                                
       tool.onMouseDrag = function(event){
                      
                        var offset = event.delta;
                        offset.angle = offset.angle + 90;
                        
                        var lineSize = values.size / values.lines;
                        for (var i = 0; i < values.lines; i++) {
                            var path = paths[values.lines - 1 - i];
                            //offset.length = lineSize * i + lineSize / 2;
                            
                            offset.length = (-i * lineSize)  * (Math.max(event.delta.length /15, 1));
                            path.add(event.middlePoint + offset);
                           // path.smooth();
                            console.log(paths[1]);
                        }
                    }
            return tool
            }        
                    
      
    
    
      // Construct a Toolstack, passing your Tools
    
      const toolStack = new ToolStack([toolPath, toolCircle, multiLine])
    
      // Activate a certain Tool
    
      toolStack.activateTool('toolPath')
    
      // Attach click handlers for Tool activation on all
      // DOM buttons with class '.tool-button'
    
      document.querySelectorAll('.tool-button').forEach(toolBtn => {
        toolBtn.addEventListener('click', e => {
          toolStack.activateTool(e.target.getAttribute('data-tool-name'))
        })
      })
    }
    
    //       function onKeyDown(event) {
//                          if (event.key == 'd'){
//                              project.activeLayer.removeChildren();
//                          }
//                          if (event.key == 'z'){
//                              project.activeLayer.removeChildren(project.activeLayer.lastChild.index);
//                          }
//  
//                      }
</script>
<head>
<title>
StackExchange Multiple Tools
</title>
<meta name="generator" content="BBEdit 14.1" /> 
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.5/paper-core.js">
</script>
<button class="tool-button" data-tool-name="toolPath">
Draw Paths 
</button>
<button class="tool-button" data-tool-name="toolCircle">
Stamp Circles 
</button>
<button class="tool-button" data-tool-name="multiLine">
Multi Lines
</button>
<canvas resize>
</canvas>
</body>
</html>

positioning elements right property based on other dynamic values with CSS JS

I have a primary menu with two sub-menus nested inside. the sub menus are revealed on a hover, and have a dynamically changing width based on the content inside. I need the sub menus position relative to the main menu to be: the left border of the sub menu is touching the right border of the main menu and they are not overlapping. Common functionality of a sub menu on hover reveal I suppose.

So I believe the math for the css right positioning is something like:

right: -elements current width in px

I don’t believe theres a way in css to insert the elements current width value into the right position so I have tried with JS

    let subMenuBounds = subMenuOne.getBoundingClientRect()
    let subMenuTwoBounds = subMenuOne.getBoundingClientRect()

    subMenuOne.style.right = `-${subMenuBounds}px`
    subMenuTwo.style.right = `-${subMenuTwoBounds}px`

the problem with this is the subMenus have no bounds until I hover over the menu, because the display is set to: none.

any solution to this?

    let subMenuBounds = subMenuOne.getBoundingClientRect()
    let subMenuTwoBounds = subMenuOne.getBoundingClientRect()

    subMenuOne.style.right = `-${subMenuBounds}px`;
    subMenuTwo.style.right = `-${subMenuTwoBounds}px`;
.sub-menu-one,
.sub-menu-two {
  height: auto;
  width: auto;
  min-width: 12rem;
  position: absolute;
  top: 0;
  right: ??;
  border-radius: 5px;
  display: none;
  opacity: 0;
  transition: all 350ms;
  border: 1px solid #e4e4e4;
  background-color: #2e1a04;
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
  z-index: 3;
}

.menu-row:nth-child(2):hover > .sub-menu-one,
.menu-row:nth-child(3):hover > .sub-menu-two {
  opacity: 1;
  transition-delay: 350ms;
  display: block;
}
<div class="menu">
        <div class="menu-container">
            <div class="menu-row">
                <i class="fa-solid fa-book"></i>
                <h2>Syno &bull; Checker</h2>
                <span id="menu-close-btn">X</span>
            </div>
            <div class="menu-row">
                <p>Definition</p>
                <i class="fa-solid fa-caret-right"></i>
                <div class='sub-menu-one'>
                    <div>
                        <blockquote>
                            <p id="selected-word"></p>
                        </blockquote>
                    </div>
                    <div class="definition"></div>
                </div>
            </div>
            <div class="menu-row">
                <p>Synonyms</p>
                <i class="fa-solid fa-caret-right"></i>
                <div class='sub-menu-two'>
                    <div>
                        <blockquote>
                            <p id="selected-word-two"></p>
                        </blockquote>
                    </div>
                    <div class="options"></div>
                </div>
            </div>
        </div>
    </div>

Fix/modernize website log in that queries another site for authentication

First, please look at https://staging.upstatetoday.com/letmein

I have inherited a very old log in mechanism that has begun to not work lately – Firefox refuses to log users in, other browsers can be iffy, too. The site is wordpress, but the login is a different server (paywall).

Correct behavior is: insert username and password, click login button, page refreshes and sends user to the homepage if authentication is valid; alert drops that the username/password is incorrect if invalid.

This only seems to happen corectly in Chrome on the desktop, and sometimes in Edge. Firefox just refreshes the page. There are no js errors.

The login button is supposed to call a JS function that stores the current url (not needed in this implementation) then calls a function (in the wordpress functions.php file) that queries a separate site with the username and password and receives an XML response. That response is evaluated for a Yes and the user is allowed in or not, based on that xml response. If the user is allowed, the JS function returns the user to the page where they last were. If they are not allowed, the JS function alerts with bad user or pass msg.

Anyone can go to any post or page, but the single.php template is modified to check for authentication. If they are authenticated, they see the post. If not, they see a notice to subscribe or log in.

But, There’s more going on in the code that is not needed (?) and I think there is unnecessary duplication of the process.

You can see the dialog at the link on top. Please ignore the styling (coming later).

I have moved code, tried snippets, php sessions, but nothing is working in Firefox at all, and with no error messages, I do not know how to proceed.

This is the code for the login dialog:

<?php if(!isset($_SESSION['auth']) ) { ?>
    <a href="https://seneca.newzware.com/ss70v2/seneca/common/template.jsp?" target="new">Forgot user name/password? Click Here</a> 

    <form>
    <div class="form-group">
        <label for="pwd">User name:</label>
        <input type="text"  autocomplete="user-name" class="form-control" id="user-name" placeholder="Enter user name" style="width:200px; margin-bottom:5px;"/></div>
        
    <div class="form-group">
        <label for="pwd">Password:</label>
            <input type="password" autocomplete="current-password" class="form-control" id="pwd" placeholder="Enter password" style="width: 200px;margin-bottom:5px;"/> <button type="submit" class="btn btn-primary" id="sub-sign-in" style="color:blue;font-size:1.0em">Log in to Upstate Today</button>  </div>
    </form>
        <a href="https://seneca.newzware.com/ss70v2/seneca/common/template.jsp?#v3-registration-div" target="new"><button class="btn btn-default">Register or Renew Subscription </button> </a> 

<?php } else { ?>   
"<script type="text/javascript">   
    function Redirect() 
    {  
        window.location="https://staging.upstatetoday.com"; 
    } 
    document.write("You will be redirected to the homepage in 5 seconds"); 
    setTimeout('Redirect()', 5000);   
</script>"
<?php } ?>

This is the js that is called by “sub-sign-in” :

jQuery(document).ready(function( $ ){
  var pageURL = $(location).attr("href");
    localStorage.setItem("page_url", pageURL);
  console.log('ready');
  $('#sub-sign-in').click(function(){
    console.log('enter');
      var user_name=$('#user-name').val();
      var password=$('#pwd').val();
    $.ajax({
      type: "POST",
      url: '/wp-admin/admin-ajax.php',
      data: ({
        action: "check_address",
        name: user_name,
        pass:password
      }),
      success: function (response){
        console.log(response);
        var pg_url = localStorage.getItem("page_url");
        if(response == 'Yes0'){
         window.location.replace(pg_url);
        }
        else{
        alert('wrong username or password');
        }
      },
    error: function(error){
    console.log(error);
    }
    });
  });
});

This is the code from the child theme functions.php



function register_my_session()
{
  if( !session_id() )
  {
    session_start();
      }
}

add_action('init', 'register_my_session');

  /*     session_write_close(); */


function check_address()
{
$name = $_POST["name"];
$password = $_POST["pass"];
/*$edition = $_POST["edition"];
$subdate = $_POST["subscriptiondate"]*/
$response = wp_remote_get( 'https://seneca.newzware.com/authentication/auth70_xml.jsp?site=seneca&login_id='.$name.'&password='.$password);
$xml = simplexml_load_string($response['body']);
$isValid = (string) $xml->authenticated;
if(!session_id()) {
session_start();
}
if($isValid == 'Yes'){
$_SESSION['auth'] = '1';
}
echo $isValid;


}
add_action( 'wp_ajax_check_address', 'check_address' );
add_action( 'wp_ajax_nopriv_check_address', 'check_address' );
add_action( 'wp_enqueue_scripts', 'hello_elementor_child_enqueue_scripts', 20 );

function wpb_widgets_init() {
 
    register_sidebar( array(
        'name'          => 'Custom Header Widget Area',
        'id'            => 'newzware-widget',
        'before_widget' => '<div class="newzware-widget">',
        'after_widget'  => '</div>',
        'before_title'  => '<h2 class="newzware-title">',
        'after_title'   => '</h2>',
    ) );
 
}
add_action( 'widgets_init', 'wpb_widgets_init' );
 

This is the single post content that includes whether the user can read that post or not (ie, is authenticated):


<?php
/**
 * The template for displaying singular post-types: posts, pages and user-defined custom post types.
 *
 * @package HelloElementor
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}
?>


<?php
while ( have_posts() ) :
    the_post();
    ?>

<main id="content" <?php post_class( 'site-main' ); ?> role="main">
    <?php if ( apply_filters( 'hello_elementor_page_title', true ) ) : ?>
        <header class="page-header">
            <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
        </header>
    <?php endif; ?>
    <!-- Newzware Protection Code -->   
    
    <?php
        $key = 'Free Story';
        $themeta = get_post_meta($post->ID, $key, TRUE);
        if($themeta != '') {
        $free_story = 1; 
        }
    ?>

    <?php if($_SESSION['auth'] == '1' OR current_user_can( 'read_post' ) OR $free_story == '1' ) { ?>   
    
    <!-- end part 1Newzware Protection Code --> 
    
    <div class="page-content">
        <?php the_content(); ?>
        
    <!-- beginpart 2 Newzware Protection Code -->       
<?php } else { ?>

<div class='ifsub-panel'> <div class='ifsubpanel-heading' style='background:#2318A4; color:#fff; text-align:center;'><b>Subscribe To The Journal</b></div><div class='ifsubpanel-body'>  <p style='text-align:center'>
If you are already registered with <a href="https://upstatetoday.com">UpstateToday.com</a>, please click the LOGIN button in the upper left corner of this window to log in and continue reading.<br><br>
            
If you'd like to subscribe,<br>
<a href='https://seneca.newzware.com/ss70v2/seneca/common/template.jsp?nwmodule=nonsubscribers&nwpage=nonsubstart'><b class="text-danger"> Please click here for options. We'd love for you to join our family.</b></a></p>
</div></div>
        

    
    <?php } ?>
    
    
    <!-- End Newzware Protection Code -->       
        <div class="post-tags">
            <?php the_tags( '<span class="tag-links">' . __( 'Tagged ', 'hello-elementor' ), null, '</span>' ); ?>
        </div>
        <?php wp_link_pages(); ?>
    </div>

    <?php comments_template(); ?>
</main>

    <?php
endwhile;



I want to make this work reliably in desktop and mobile browsers. I’d love to have a user tap a login button, go to a page with the dialog, log in, then return to the home page.

Thanks for your time and pointers.