Category: javascript
Category Added in a WPeMatico Campaign
ScrollIntoView Problem in keyboard navigation in javascript?
I create a autocomplete component. I add keyboard navigation. I write a function to scrollIntoView the highlighted item into screen.
const scrollOptionIntoView = (direction: number) => {
        if (listRef.current && highlightedIndex >= 0) {
            const optionElement = listRef.current.children[highlightedIndex] as HTMLElement;
            if (optionElement) {
                const { offsetTop, offsetHeight } = optionElement;
                const { scrollTop, clientHeight } = listRef.current;
                const optionTop = offsetTop - offsetHeight;
                const optionBottom = offsetTop + offsetHeight + scrollTop;
                if (optionTop < scrollTop) {
                    listRef.current.scrollTop = optionTop;
                } else if (optionBottom > scrollTop + clientHeight) {
                    listRef.current.scrollTop = optionBottom - clientHeight;
                }
            }
        }
    };
It working, fine for topSide when I click arrow up. But not working, properly when I click array down on bottom side.
Note: In the gif, First Half I click on arrow down, you could see that, it not working perfectly as when I click to arrow up, I need the same behavior as top side, In the bottom side, it need to show very bottom the highlighted part.
Here is my full component. Here I am creating a autocomplete components. I am stacking keyboard navigation when scrollIntoView.
const Autocomplete = ({ options }: Props) => {
    const [inputValue, setInputValue] = useState("");
    const [highlightedIndex, setHighlightedIndex] = useState(-1);
    const [open, setOpen] = useState<boolean>(false);
    const autocompleteRef = useRef<HTMLDivElement>(null);
    const listRef = useRef<HTMLUListElement>(null);
    const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
        setInputValue(event.target.value);
        setHighlightedIndex(-1);
    };
    const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
        if (event.key === "ArrowUp") {
            event.preventDefault();
            setHighlightedIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : prevIndex));
            scrollOptionIntoView(-1);
        } else if (event.key === "ArrowDown") {
            event.preventDefault();
            setHighlightedIndex((prevIndex) =>
                prevIndex < options.length - 1 ? prevIndex + 1 : prevIndex
            );
            scrollOptionIntoView(1);
        } else if (
            event.key === "Enter" &&
            highlightedIndex >= 0 &&
            highlightedIndex < options.length
        ) {
            event.preventDefault();
            setInputValue(options[highlightedIndex]);
            setHighlightedIndex(-1);
        }
    };
    const scrollOptionIntoView = (direction: number) => {
        if (listRef.current && highlightedIndex >= 0) {
            const optionElement = listRef.current.children[highlightedIndex] as HTMLElement;
            if (optionElement) {
                const { offsetTop, offsetHeight } = optionElement;
                const { scrollTop, clientHeight } = listRef.current;
                const optionTop = offsetTop - offsetHeight;
                const optionBottom = offsetTop + offsetHeight + scrollTop;
                if (optionTop < scrollTop) {
                    listRef.current.scrollTop = optionTop;
                } else if (optionBottom > scrollTop + clientHeight) {
                    listRef.current.scrollTop = optionBottom - clientHeight;
                }
            }
        }
    };
    useOutsideClick(autocompleteRef, handleBlur);
    return (
        <div className="relative" ref={autocompleteRef}>
            <Input
                label="Movie Name"
                color="indigo"
                size="lg"
                onChange={handleChange}
                onKeyDown={handleKeyDown}
                value={inputValue}
                onFocus={() => setOpen(true)}
            />
            {open && (
                <ul
                    className="absolute bg-white shadow-lg rounded-md h-[300px] px-5 overflow-auto left-0 top-full z-10 w-full"
                    ref={listRef}
                >
                    {options.map((option, index) => (
                        <li
                            key={option}
                            className={highlightedIndex === index ? "bg-yellow-600" : ""}
                            onClick={() => setInputValue(option)}
                        >
                            {option}
                        </li>
                    ))}
                </ul>
            )}
        </div>
    );
};
export default Autocomplete;
RSA-OAEP Encrypt: OperationError on File upload but not strings using SubtleCrypto
I am trying to allow the client to upload a file, have the file be encrypted with RSA-OAEP using a public key provided by the server, then have the file be uploaded and completely readable by the server.
However, my current code gives me OperationError: The operation failed for an operation-specific reason (on Safari and Firefox). Here is my code:
document.getElementById("input").addEventListener('change', async event => {
    if (event.target.files[0]) {
        const reader = new FileReader();
        reader.addEventListener('load', async (event2) => {
            const res = await fetch("/key");
            const exported = await res.text();
            const key = await importRSAPublicKey(exported);
            const arrayBuffer = event2.target.result;
            console.log(arrayBuffer);
            const encrypted = await encryptRSA(key, arrayBuffer); // Fails here at the call to window.crypto.subtle.encrypt()
            console.log(encrypted);
            await fetch(`/upload`, {method: "POST", body: encrypted});
        });
        reader.addEventListener('error', () => {
            reject(new Error("There was an error reading the inserted file as text."));
        })
        /**
         * @type {File}
         */
        const file = event.target.files[0];
        reader.readAsArrayBuffer(file);
    }
});
async function importRSAPublicKey(key) {
    return new Promise(async (resolve, reject) => {
        try {
            const imported = await window.crypto.subtle.importKey(
                "jwk",
                JSON.parse(atob(key)),
                {
                    name: "RSA-OAEP",
                    modulusLength: 4096,
                    publicExponent: new Uint8Array([1, 0, 1]),
                    hash: "SHA-256",
                },
                true,
                ["encrypt"]
            );
            return resolve(imported);
        } catch (error) {
            reject(error);
        }
    })
}
async function encryptRSA(key, data) {
    return new Promise(async (resolve, reject) => {
        try {       
            const encryptedData = await window.crypto.subtle.encrypt(
                { name: "RSA-OAEP" },
                key,
                data
            )
    
            const uintArray = new Uint8Array(encryptedData);
    
            const string = String.fromCharCode.apply(null, uintArray);
    
            const base64Data = btoa(string);
    
            return resolve(base64Data);
        } catch (error) {
            return reject(error);
        }
    });
}
Interestingly, the same operation, when preformed either on text or via similar code for AES-GCM on the same file, works perfectly. Here is my (working) code for the plaintext application:
document.getElementById("input").addEventListener('change', async event => {
    const res = await fetch("/key");
    const exported = await res.text();
    const key = await importRSAPublicKey(exported);
    const encrypted = await encryptRSA(key, new TextEncoder().encode("Test"));
    console.log(encrypted);
    await fetch(`/upload`, {method: "POST", body: encrypted});
});
// ... Helper functions from the previous codeblock unchanged
Why, since both times an ArrayBuffer is being passed into the function, does one work and the other not?
I would love it if someone could tell me a way I can encrypt these without using btoa() on the cleartext (which is a pain to convert back into actual binary from there).
The “from” argument must be of type string. Received type undefined
I am using “jest”: “^20.0.4” & “babel-jest”: “^23.6.0” packages for running unti test cases for in my Vue 2 project. Node 10.2.0v.
While running npm run test coverage is zero. It’s failed to collect coverage from file.
my Package dependencies
"dependencies": {
    "@vue/test-utils": "^1.0.0-beta.29",
    "animejs": "^3.2.0",
    "axios": "^0.16.2",
    "bootstrap-sass": "3.3.7",
    "envify": "^4.1.0",
    "es6-promise": "^4.1.1",
    "hammerjs": "^2.0.8",
    "javascript-time-ago": "^2.0.6",
    "jest-junit": "^6.0.1",
    "jest-localstorage-mock": "^2.4.0",
    "jest-serializer-vue": "^2.0.2",
    "jquery": "^3.1.1",
    "jquery-validation": "^1.16.0",
    "jquery-validation-unobtrusive": "^3.2.6",
    "key-sitecore-vue-plugin": "^1.0.2",
    "lazysizes": "^3.0.0-rc3",
    "lodash": "^4.17.4",
    "natives": "^1.1.6",
    "node-sass": "^4.11.0",
    "owl.carousel": "^2.2.0",
    "require-dir": "^1.2.0",
    "swiper": "^5.0.1",
    "vue": "^2.5.16",
    "vue-check-view": "^0.3.0",
    "vue-computed-helpers": "^1.3.0",
    "vue-cookie": "^1.1.4",
    "vue-cookies": "^1.5.6",
    "vue-flatpickr-component": "^8.1.0",
    "vue-good-table": "^2.3.0",
    "vue-highlight-text": "^1.6.2",
    "vue-jest": "^3.0.1",
    "vue-js-modal": "^1.3.12",
    "vue-js-toggle-button": "^1.2.2",
    "vue-modal": "^1.0.2",
    "vue-modal-dialogs": "^2.0.0",
    "vue-modals": "^0.5.0",
    "vue-modaltor": "^1.2.4",
    "vue-moment": "^3.2.0",
    "vue-paginate": "^3.6.0",
    "vue-popup": "^0.2.14",
    "vue-range-slider": "^0.6.0",
    "vue-resource": "^1.5.1",
    "vue-scrollto": "^2.13.0",
    "vue-server-renderer": "^2.4.2",
    "vue-shave": "^1.0.3",
    "vue-slider-component": "^2.6.1",
    "vue-star-rating": "^1.5.1",
    "vue-swal": "^0.1.0",
    "vue-switches": "^2.0.1",
    "vue-test-utils": "^1.0.0-beta.11",
    "vue-update": "^1.0.6",
    "vue-words-highlight": "^1.1.2",
    "vue-ya-semantic-elements": "0.0.4",
    "vue-ya-semantic-modal": "0.0.3",
    "vue-youtube": "^1.4.0",
    "vuejs-datepicker": "^1.5.4",
    "vuejs-paginator": "^2.0.2",
    "vuetable": "^1.5.12",
    "vuex": "^2.4.0",
    "whatwg-fetch": "^2.0.3"
  },
  "devDependencies": {
    "@frctl/fractal": "^1.0.11",
    "autoprefixer": "^6.5.4",
    "babel-core": "^6.26.3",
    "babel-jest": "^23.6.0",
    "babel-loader": "^8.1.0",
    "babel-plugin-transform-object-assign": "^6.22.0",
    "babel-polyfill": "^6.20.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-es2015": "^6.18.0",
    "babelify": "^7.3.0",
    "browserify": "^13.1.1",
    "browserify-shim": "^3.8.12",
    "eslint": "^3.12.1",
    "eslint-config-airbnb": "^13.0.0",
    "eslint-plugin-import": "^2.2.0",
    "eslint-plugin-jsx-a11y": "2.2.3",
    "eslint-plugin-react": "^6.8.0",
    "eslint-plugin-vue": "^4.7.1",
    "event-stream": "^3.3.4",
    "exorcist": "^0.4.0",
    "fs": "0.0.1-security",
    "glob": "^7.1.1",
    "globby": "^6.1.0",
    "gulp": "^3.9.1",
    "gulp-clean-css": "^2.3.2",
    "gulp-concat": "^2.6.1",
    "gulp-cached": "^1.1.1",
    "gulp-copy": "^1.0.0",
    "gulp-environments": "^0.1.1",
    "gulp-exec": "^2.1.3",
    "gulp-eslint": "^6.0.0",
    "gulp-filter": "^5.0.0",
    "gulp-imagemin": "7.1.0",
    "gulp-load-plugins": "^1.4.0",
    "gulp-modify-css-urls": "^0.2.2",
    "gulp-nuget-restore": "^0.4.0",
    "gulp-postcss": "^6.2.0",
    "gulp-replace": "^0.5.4",
    "gulp-sass": "^3.0.0",
    "gulp-sourcemaps": "^1.9.1",
    "gulp-svg-sprite": "^1.3.6",
    "gulp-uglify": "^2.0.0",
    "gulp-uglify-es": "^3.0.0",
    "gulp-watch": "^5.0.1",
    "inchjs": "^0.4.1",
    "jasmine": "^2.5.2",
    "jasmine-core": "^2.5.2",
    "jasmine-reporters": "^2.3.2",
    "jest": "^20.0.4",
    "jest-serializer-html": "^4.0.1",
    "jest-vue-preprocessor": "^1.4.0",
    "jquery-match-height": "^0.7.0",
    "jsdoc": "^3.4.3",
    "jsdoc-vue": "^1.0.0",
    "mocha": "^3.2.0",
    "run-sequence": "^1.2.2",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0",
    "vinyl-transform": "^1.0.0",
    "vueify": "^9.4.0",
    "watchify": "^3.8.0"
  },
.babelrc
{
  "presets": ["es2015"],
  "plugins": ["transform-object-assign"],
  "presets": ["env"]
}
jest.config.json
{
  "testMatch": [ "**/**/*.spec.js" ],
  "collectCoverageFrom": [
    "src/**/*.js",
    "src/**/*.vue",
    "!src/**/plugins/**/*.js",
    "!src/**/plugins/**/*.vue",
    "!src/**/Plugins/**/*.js",
    "!src/**/Plugins/**/*.vue",
    "!<rootDir>/node_modules/",
      "!<rootDir>/packages/"
  ],
  "moduleFileExtensions": [
    "js",
    "vue"
  ],
  "moduleNameMapper": {
    "^vue$": "vue/dist/vue.common.js"
  },
  "moduleDirectories": ["node_modules", "./src/Foundation/"],
  "setupFiles": [
    "<rootDir>/tasks/jest/polyfill.request-animation-frame.js",
    "<rootDir>/tasks/jest/polyfill.matchMedia.js",
    "<rootDir>/tasks/jest/setup.eventBus.js",
    "<rootDir>/tasks/jest/setup.stub.js",
    "<rootDir>/tasks/jest/setup.geolocation.js",
    "jest-localstorage-mock"
  ],
  "verbose": true,
  "setupTestFrameworkScriptFile": "./setup-jasmine-env.js",
  "snapshotSerializers": [
    "jest-serializer-vue"
  ],
  "unmockedModulePathPatterns": [
    "./node_modules/jasmine-reporters"
  ],
  "coverageThreshold": {
    "global": {
      "branches": 0,
      "functions": 0,
      "lines": 0,
      "statements": 0
    }
  },
  "transform": {
    "^.+\.js$": "<rootDir>/node_modules/babel-jest",
    ".*\.(vue)$": "<rootDir>/node_modules/vue-jest"
  },
  "reporters": ["default", ["jest-junit", { "output": "coverage/junit.xml" }]],
  "coverageReporters": ["text", "lcov", "cobertura"]
}
Test suite failed to run
TypeError [ERR_INVALID_ARG_TYPE]: The “from” argument must be of type string. Received type undefined
getting this Error:
ERROR: TypeError [ERR_INVALID_ARG_TYPE]: The “from” argument must be of type string. Received type undefined
STACK: TypeError [ERR_INVALID_ARG_TYPE]: The “from” argument must be of type string. Received type undefined
Any idea about this error.
I have updated jest latest version for this. It was not supporting my node version.
how can i hide or show select list depends on its value using for loop in vue?
this code:
<b-col md="6">
 <b-form-group label="Sub Matter" label-for="sub_matter">
   <div class="d-flex align-items-center">
     <div class="w-100">
       <b-form-select v-model="matter.sub_matter" :options="subMatterOptions"
         disabled></b-form-select>
     </div>
    <div>
       <b-button variant="primary" class="ml-2" @click="addSubMatter"
         v-if="subMatters.length < 9">
         +
       </b-button>
    </div>
   </div>
  </b-form-group>
 </b-col>
will show select list (disabled) and will show the value of matter.sub_matter and if i click “+” button it will add new select list with v-model=”sub_matter_2″ and if i click “+” button it will add another select list with v-model=”sub_matter_3″ and so on until sub_matter_10
this code:
<b-col md="6" v-for="(subMatterKey, index) in subMatters" :key="index">
  <b-form-group :label="`Sub Matter ${index + 2}`" :label-for="`sub_matter_${index + 2}`"
    v-if="shouldDisplaySubMatter(subMatterKey)">
    <div class="d-flex align-items-center">
     <div class="w-100">
     <b-form-select v-model="matter[subMatterKey]"
     :options="subMatterOptions"></b-form-select>
     </div>
    <div>
    <b-button variant="danger" class="ml-2" @click="removeSubMatter(index)">
      -
     </b-button>
     </div>
    </div>
   </b-form-group>
  </b-col>
will be showing when i press “+” button from the first button
this is the script:
data() {
    return {
        subMatterOptions: [
            { value: 'SubSale (SS)', text: 'SubSale (SS)' },
            { value: 'Direct Developer (DD)', text: 'Direct Developer (DD)' },
            { value: 'Auction (A)', text: 'Auction (A)' },
            { value: 'Love and Affection (Gift)', text: 'Love and Affection (Gift)' },
            { value: 'Perfection of Transfer (POT)', text: 'Perfection of Transfer (POT)' },
            { value: 'Perfection of Charge (POC)', text: 'Perfection of Charge (POC)' },
            { value: 'Discharge of Charge (DC)', text: 'Discharge of Charge (DC)' },
            { value: 'Deed of Receipt and Reassignment (DRR)', text: 'Deed of Receipt and Reassignment (DRR)' },
            { value: 'LOAN', text: 'LOAN' },
            { value: 'Others', text: 'Others' },
        ],
        subMatters: ['sub_matter_2', 'sub_matter_3', 'sub_matter_4', 'sub_matter_5', 'sub_matter_6', 'sub_matter_7', 'sub_matter_8', 'sub_matter_9', 'sub_matter_10'],
        matter: {
            sub_matter: "",
            sub_matter_2: "",
            sub_matter_3: "",
            sub_matter_4: "",
            sub_matter_5: "",
            sub_matter_6: "",
            sub_matter_7: "",
            sub_matter_8: "",
            sub_matter_9: "",
            sub_matter_10: "",
        }
    };
},
computed: {
    filteredSubMatters() {
        return this.subMatters.filter(
            (subMatterKey) =>
                this.matter[subMatterKey] !== null && this.matter[subMatterKey] !== "",
            console.log(subMatterKey)
        );
    },
},
methods: {
    shouldDisplaySubMatter(subMatterKey) {
        console.log("subMatters",this.subMatters)
        console.log("sub_matter_2",this.matter.sub_matter_2)
        console.log("sub_matter_3",this.matter.sub_matter_3)
        console.log("sub_matter_4",this.matter.sub_matter_4)
        console.log("sub_matter_5",this.matter.sub_matter_5)
        console.log("sub_matter_6",this.matter.sub_matter_6)
        console.log("sub_matter_7",this.matter.sub_matter_7)
        console.log("sub_matter_8",this.matter.sub_matter_8)
        console.log("sub_matter_9",this.matter.sub_matter_9)
        console.log("sub_matter_10",this.matter.sub_matter_10)
        if (this.subMatters.indexOf(subMatterKey) === 0) {
            return true;
        }
        const precedingSubMatters = this.subMatters.slice(0, this.subMatters.indexOf(subMatterKey));
        for (const key of precedingSubMatters) {
            if (this.matter[key] !== '') {
                return true;
            }
        }
        return this.matter[subMatterKey] !== null;
    },
    addSubMatter() {
        if (this.subMatters.length < 9) {
            const newSubMatterKey = `sub_matter_${this.subMatters.length + 2}`;
            this.subMatters.push(newSubMatterKey);
        }
    },
    removeSubMatter(index) {
        const subMatterKey = this.subMatters[index];
        this.matter[subMatterKey] = "";
        this.subMatters.splice(index, 1);
    }, 
}
what i’m trying to do is if any of matter.sub_matter_2 until matter.sub_matter_10 has value i want to display its select list otherwise if its empty i don’t want its select list to be displayed (i can add it from “+” button)
currently all select lists are showing, i’m trying to show only select list that has value
in this function:
shouldDisplaySubMatter(subMatterKey) {
        console.log("subMatters",this.subMatters)
        console.log("sub_matter_2",this.matter.sub_matter_2)
        console.log("sub_matter_3",this.matter.sub_matter_3)
        console.log("sub_matter_4",this.matter.sub_matter_4)
        console.log("sub_matter_5",this.matter.sub_matter_5)
        console.log("sub_matter_6",this.matter.sub_matter_6)
        console.log("sub_matter_7",this.matter.sub_matter_7)
        console.log("sub_matter_8",this.matter.sub_matter_8)
        console.log("sub_matter_9",this.matter.sub_matter_9)
        console.log("sub_matter_10",this.matter.sub_matter_10)
        if (this.subMatters.indexOf(subMatterKey) === 0) {
            return true;
        }
        const precedingSubMatters = this.subMatters.slice(0, this.subMatters.indexOf(subMatterKey));
        for (const key of precedingSubMatters) {
            if (this.matter[key] !== '') {
                return true;
            }
        }
        return this.matter[subMatterKey] !== null;
    },
what am i doing wrong?
note: the above code is update form so sub_matter, sub_matter_2, sub_matter_3 and sub_matter_4 has value, these are the outputs of the console log:
console.log("subMatters",this.subMatters) value is:
subMatters 
Array(9) [ "sub_matter_2", "sub_matter_3", "sub_matter_4", "sub_matter_5", "sub_matter_6", "sub_matter_7", "sub_matter_8", "sub_matter_9", "sub_matter_10" ]
console.log("sub_matter_2",this.matter.sub_matter_2) value is: sub_matter_2 Direct Developer (DD)
console.log("sub_matter_3",this.matter.sub_matter_3) value is: sub_matter_3 Auction (A)
console.log("sub_matter_4",this.matter.sub_matter_4) value is: sub_matter_4 Love and Affection (Gift)
console.log("sub_matter_5",this.matter.sub_matter_5) value is: sub_matter_5 null
console.log("sub_matter_6",this.matter.sub_matter_6) value is: sub_matter_6 null
console.log("sub_matter_7",this.matter.sub_matter_7) value is: sub_matter_7 null
console.log("sub_matter_8",this.matter.sub_matter_8) value is: sub_matter_8 null
console.log("sub_matter_9",this.matter.sub_matter_9) value is: sub_matter_9 null
console.log("sub_matter_10",this.matter.sub_matter_10) value is: sub_matter_10 null
Javascript – Handling camera permission when blocked mid stream
I want to handle a exception where the user allows the camera permission for video call but mid streaming to everyone, user decides to block permission through browser permissions.
function handleCameraPermission() {
  if (navigator.mediaDevices.getUserMedia) {
    // The browser supports `getUserMedia()`.
    navigator.mediaDevices.getUserMedia({
      video: true
    }).then(stream => {
      // The user has granted permission to access the camera.
      // Do something with the `stream` object.
      document.getElementById("video").srcObject = stream;
    }).catch(error => {
      // The user has denied permission to access the camera.
      // Display a message to the user explaining why they need to grant permission.
      alert("Please grant permission to access the camera in order to use this feature.");
    });
  } else {
    // The browser does not support `getUserMedia()`.
    // Display a message to the user explaining that their browser does not support this feature.
    alert("Your browser does not support the `getUserMedia()` method.");
  }
}
I have tried this code but this only works the first time when the user is asked for permission. I want to handle this exception at anytime. If there is any event which is triggered when the browser permission is blocked or any other way of handling this.
Javascript to auto-click “Load more”-Button
I’m running the site onlineyoga.ch which uses a third party software.
My issue is on the player page:
https://onlineyoga.ch/programs/entspannungsinseln-im-alltag
Since I can’t change the HTML Code, I would like to run a Javascript that auto-clicks the show more button called “Mehr anzeigen”, which I can add to the custom scripts section.
I tried several approaches, but didn’t find a working code:
For example:
// Wait until the DOM is fully loaded
document.addEventListener('DOMContentLoaded', function() {
  // Find the button using the class 'button left'
  var button = document.querySelector('.button.left ds-button');
  // Check if the element was found
  if (button) {
    // Simulate a click on the button
    button.click();
    // Display a notification
    window.alert("Button has been clicked!");
  }
});
The problem is, if I test my scripts in the chrome console, I always get a “undefined” back and the click does not happen. So I can’t go further with this..
See Screenshot of Chorme Script testing with Console
Do you know how I can reach my goal and make this clickable with a Javascript and can sucessfully test it on https://onlineyoga.ch/programs/entspannungsinseln-im-alltag ?
How to validate HTML form and call JS function through the same button? If not, how to set it up properly?
I am trying to use required and patterns in my HTML form. The submit button for the form has a function attached to it on document ready that hides the new-guest div and shows the qr-generated div. This function is attached to all page-show buttons. There is also a function that is attached to the form on submit that processes the info in the form. Currently, when I click the submit button, it hides the new-guest div, despite the inputs not being filled out or valid. I feel like there’s a minimal change I can make before I write more specific functions for this form. Any advice on how I can proceed?
<div class="container p-4 view" id="new-guest">
    <!-- when making a form, always start with form class, form-floating is a bootstrap class -->
    <form class="form-floating" method="post" id="infoform">
      <!-- each form-floating div holds a label and the input you want to take in -->
      <div class="form-floating">
        <!-- type is self explanatory, form-control is bootstrap class, placeholder is for the animation to work, required is self explanatory -->
        <input type="text" class="form-control" id="firstName" name="firstName" placeholder="lionel" required><br><br>
        <label for="firstName">First Name</label>
      </div>
      <div class="form-floating">
        <input type="text" class="form-control" id="lastName" name="lastName" placeholder="messi" required><br><br>
        <label for="lastName">Last Name</label>
      </div>
      <div class="form-floating">
        <input type="tel" class="form-control" id="phoneNumber" name="phoneNumber" pattern="[0-9]{10}" placeholder="idk"
          required>
        <label for="phoneNumber">Phone Number</label>
        <small>Format: 1234567890</small><br><br>
      </div>
      <button type="submit" page-show="qr-generated" class="btn btn-primary" value="Submit">Submit</button>
    </form>
  </div>
//function attached to buttons to change div currently viewable
    <script>
      $(document).ready(function (e) {
        showView("home");
        function showView(viewName) {
          $('.view').hide();
          $('#' + viewName).show();
        }
        $('[page-show]').click(function (e) {
          var viewName = $(this).attr('page-show');
          showView(viewName);
        });
      });
    </script>
async function submitForm(e) {
        // Get form values
        e.preventDefault();
        var firstName = document.getElementById("firstName").value;
        var lastName = document.getElementById("lastName").value;
        var phoneNumber = document.getElementById("phoneNumber").value;
....
}
var form = document.getElementById("infoform");
form.addEventListener("submit", submitForm);
Unable to import JavaScript module due to net::ERR_ABORTED 404 (Not Found) – How to fix?
I’ve searched this error on different platform and tried the answers but none worked here is my code
javascript:
import { Octokit } from "./octokit.js";
const TOKEN = "mytoken";
const octokit = new Octokit({
    auth: TOKEN
});
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>gitmail</title>
</head>
<body>
    
</body>
<script type='module' src="test.js" ></script>
</html>
I tried with and without “.js” . tried with “../” and “./” I even wrote the full path to the module but that didn’t help as well.
I am using VS code as editor and the live server. Not only this module but other modules do not work as well
How do I extend the duration of each photo in a fading slideshow carousel on a webpage?
I’ve managed to manipulate a slideshow carousel from w3schools for a carousel slideshow with fading, however it is unclear to me how to make each photo stay on for longer – to pause longer before fading to the next iamge (ie 30 seconds to several minutes).
How do I extend and hold each photo longer on the screen?
(Intent is to only use this on Chrome as a photo display for my monitor/tv)
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
    <div style="overflow: hidden; background-color: black; height: 100vh;">
        <div class="w3-content w3-section" style="object-fit: contain; max-width: 100%; position: center center;">
  <img class="mySlides w3-animate-fading" src="img_rr_01.jpg" style="width:100%">
  <img class="mySlides w3-animate-fading" src="img_rr_02.jpg" style="width:100%">
  <img class="mySlides w3-animate-fading" src="img_rr_03.jpg" style="width:100%">
  <img class="mySlides w3-animate-fading" src="img_rr_04.jpg" style="width:100%">
        </div>
    </div>
    <script>
        var myIndex = 0;
        carousel();
        function carousel() {
            var i;
            var x = document.getElementsByClassName("mySlides");
            for (i = 0; i < x.length; i++) {
                x[i].style.display = "none";
            }
            myIndex++;
            if (myIndex > x.length) { myIndex = 1 }
            x[myIndex - 1].style.display = "block";
            setTimeout(carousel, 9000);
        }
    </script>
</body>
</html>
I noticed I can’t just set the timeout longer as that causes some photos to just repeat or weird clipping. I also tried to adjust the css to make it longer than 10seconds, but that also causes other weird artifacts/clipping.
React 2 Object of Same Class Having Same Values After Updating One of Them
I am new to react redux and facing a strange problem while working on my project. I have a class named ApiUtils.js which has some set of functions to handle API realted calls.
import axios from 'axios';    
const ErrorResponse = {
  data: {
    message: 'Something went wrong, please try again'
  }
};
class ApiUtils {
  request = null;
  baseUrl = null;
  defaultTimeout = 0;
  constructor(baseUrl, defaultTimeout) {
    this.baseUrl = baseUrl;
    this.defaultTimeout = defaultTimeout;
  }
setAxiosConfig = (isLogin = false, token = '') => {
    // Create a Unauthorised axios Instance
    let headerDetails = {
      'Content-Type': 'application/json'
    };
    if (isLogin) {
      headerDetails = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest'
      };
    }
    if (token) {
      headerDetails = {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`
      };
    }
    this.request = axios.create({
      baseURL: this.baseUrl,
      headers: headerDetails
    });
  };
post = async (url, body, requestTimeout = this.defaultTimeout) => {
    let response = null;
    try {
      response = await this.request.post(url, body, {
        timeout: requestTimeout
      });
      return response;
    } catch (ex) {
      if (ex.response && ex.response.data && ex.response.data.message) {
        throw ex.response;
      } else if (
        ex.response.status === 409 &&
        ex.response.data.error === 'Email Id already exist'
      ) {
        throw ex.response.data;
      } else if (
        ex.response.data.status === 401 &&
        ex.response.data.error === 'Exceeded Reset Passwords Attempts'
      ) {
        throw ex.response.data;
      } else if (
        ex.response.data.status === 401 &&
        ex.response.data.error === 'User type does not match'
      ) {
        throw ex.response.data;
      } else {
        if (
          ex.response &&
          ex.response?.data &&
          ex.response?.data?.data?.message &&
          ex.response?.status === 408
        ) {
          throw ex.response;
        } else {
          // if error response not defined
          // ErrorResponse.data.statusCode = ex.response.status
          throw ErrorResponse;
        }
      }
    }
  };
    export const AuthExternalApiUtils = new ApiUtils(
      process.env.REACT_APP_EXT_BASE_URL,
      process.env.REACT_APP_API_TIMEOUT
    );
    
    export const WsApiUtils = new ApiUtils(
      process.env.REACT_APP_WS_API_ROOT,
      process.env.REACT_APP_WS_API_TIMEOUT
    );
    
    export default new ApiUtils(process.env.REACT_APP_API_ROOT, process.env.REACT_APP_API_TIMEOUT);
I have a 2 objects of this ApiUtils class
export const AuthExternalApiUtils = new ApiUtils(
  process.env.REACT_APP_EXT_BASE_URL,
  process.env.REACT_APP_API_TIMEOUT
);
export const WsApiUtils = new ApiUtils(
  process.env.REACT_APP_WS_API_ROOT,
  process.env.REACT_APP_WS_API_TIMEOUT
);
export default new ApiUtils(process.env.REACT_APP_API_ROOT, process.env.REACT_APP_API_TIMEOUT);
Now if I update the variables of any one of the above the other one has the same value. For example: if I update the baseUrl of WsApiUtils with https://xyzbaseurl.com/ and do console.log(AuthExternalApiUtils.baseUrl) it also has the same value.
Why this is happening? is this an expected behavior or I am doing something wrong here.
Cypress and file upload using drag n drop
I’m attempting to test, using cypress, the functionality of a file upload widget.
The cypress tests which I’ve tried are:
const filePath = './cypress/fixtures/example.jpg'
    cy.get('.dropzone')
    .selectFile(filePath, 
    { action: 'drag-drop',
      force: true, }).trigger('drop', {force: true})
and
    cy.get('.dropzone > input[type="file"]').should('exist').invoke('show')
    .selectFile(filePath, {
      action: 'drag-drop',
      force: true,
      log: true,
    })
    .trigger('drop', {force: true})
The html that the tests are executing against is:
<div tabindex="0" role="button" class="dropzone  svelte-817dg2" style="">
<input accept="image/*" type="file" name="avatar" autocomplete="off" tabindex="-1" style="display: none;"> 
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
In both cases, and every variation on these, the tests never actually upload a file.
However, in the cypress chrome browser, I’m able to manually perform the drag n drop action successfully.
Missing script : “start” while running npm start even though package.json is at the right place with all the scripts in it
Missing script : “Start” while running npm start even though package.json file is in the directory with scripts in it
{
  "name": "typee",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.34",
    "@types/react": "^18.2.7",
    "@types/react-dom": "^18.2.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
This is my package.json file after running
npx create-react-app typee –template typescript
when I try to run npm start
I get this
Missing script : “start”
Loop through Object and push into Array
I am looking to loop the object and want to add those object in array in Javascript.
 My Object:
        var raw_data = {
            "name":"Mike",
            "age":"27"
        }
     var array_data = []
 
Then I loop through the object: 
  for (let [key, name] of Object.entries(raw_data)) {
    if (name !== "") {
      array_data.push({
        email: `${raw_data.name}`,
        password: `${raw_data.age}`,
      });
    }
  }
  console.log(array_data);
My out put is :
[
  { email: '[email protected]', password: '1234567' },
  { email: '[email protected]', password: '1234567' }
]
I would like expect to get only one insert:
[
  { email: '[email protected]', 
  password: '1234567' }
]
Could you please help me how to get that?
Two Calls to Function, One Failing – Javascript – Chrome Extension
Hi I am working on my first chrome extension and am running into a problem when calling a function. I have a function that sends a prompt to the ChatGPT API and returns a value. When I call it this way:
// Execute if "Context Menu" from background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (
      message.type === "CM_SpellingGrammar" ||
      message.type === "CM_Task" ||
      message.type === "CM_Answer" ||
      message.type === "CM_WordCount" ||
      message.type === "CM_Rewrite" ||
      message.type === "CM_Clarity" ||
      message.type === "CM_Scholar" ||
      message.type === "CM_Tone" ||
      message.type === "CM_StructureOrganization"
     ) {
    CM_result = message.type;
    sendRetrieve();
  }
});
This is a call in my contentScript.js file using inputs from the Context Menu read from my background.js file.
However when I try to call the same function like this:
function TESTCLICKED(event) {
  CM_result = "CM_SpellingGrammar";
   sendRetrieve();
}
The request seems to be send to ChatGPT API but the console just returns “null”
Why is this happening? The function calls seem to be the same with the same inputs.
Here is my function to send a prompt to ChatGPT API:
function sendRetrieve() {
// If there's an active text input
if (
  document.activeElement &&
  (document.activeElement.isContentEditable ||
    document.activeElement.nodeName.toUpperCase() === "TEXTAREA" ||
    document.activeElement.nodeName.toUpperCase() === "INPUT")
) {
  // Set as original for later
  originalActiveElement = document.activeElement;
  // Use selected text or all text in the input
  textOriginal = 
    document.getSelection().toString().trim() ||
    document.activeElement.textContent.trim();
  text =
    document.getSelection().toString().trim() ||
    document.activeElement.textContent.trim();
} else {
  // If no active text input use any selected text on page
  textOriginal = document.getSelection().toString().trim();
  text = document.getSelection().toString().trim();
}
if (!text) {
  alert(
    "No text found. Select this option after right-clicking on a textarea that contains text or on a selected portion of text."
  );
  return;
}
console.log(originalActiveElement);
// SPECIAL CASES PROMPT
// Alter the message based on task from user for prompt
if (CM_result === "CM_SpellingGrammar") {
  text = "Revise the following for grammar and spelling:nn[" + text + "]nn If the provided text cannot be revised for spelling or grammar return 'NoneNullNoneNullNone'";
}  else if (CM_result === "CM_Task") {
    text = text;
} else if (CM_result === "CM_Answer") {
  text = "If the following is a question, answer it. Else return 'NoneNullNoneNullNone': [" + text + "]";
} else if (CM_result === "CM_WordCount") {
    var wordcountInput = prompt("Please provide a description of the word count adjustment you would like made:nnHint: It often helps to provide an upper and lower limit.");
    if (wordcountInput) {
      text = "Adjust the word count of the following based on 'Word count adjustment':nn[" + text + "]nnWord count adjustment: [" + wordcountInput + "]nn If you cannot complete this task return 'NoneNullNoneNullNone'";
    } else {
      return
    }
} else if (CM_result === "CM_Rewrite") {
  text = "Rewrite the following to convey the same meaning in different structure, words, and organization: [" + text + "]";
} else if (CM_result === "CM_Clarity") {
    text = "Revise the following for clarity:nn[" + text + "]";
} else if (CM_result === "CM_Scholar") {
  text = "Revise the following to meet the standards of an extremely scholarly written paragraph, up to the highest academic quality:nn[" + text + "]";
} else if (CM_result === "CM_Tone") {
  var toneInput = prompt("Please provide a tone description to complete the revisions:");
  if (toneInput) {
    text = "Adjust the tone of the following based on 'Desired tone':nn[" + text + "]nnDesired tone: [" + toneInput + "]nn If you cannot complete this task return 'NoneNullNoneNullNone'";
  } else {
    return
  }
} else if (CM_result === "CM_StructureOrganization") {
  text = "Revise the following for structure and organization:nn[" + text + "]";
}
// Define the prompt to send to the API
let userPrompt = {
  model: "gpt-3.5-turbo",
  messages: [{ role: "user", content: text }],
  temperature: 1,
};
document.body.style.cursor = "wait";
// Send a POST request to the endpoint with the prompt and headers
fetch(endpointUrl, {
  method: "POST",
  headers,
  body: JSON.stringify(userPrompt),
})
  .then((response) => response.json())
  .then((data) => {
    // Use original text element and fallback to current active text element
    const activeElement =
      originalActiveElement ||
      (document.activeElement.isContentEditable && document.activeElement);
    if (activeElement) {
      if (
        activeElement.nodeName.toUpperCase() === "TEXTAREA" ||
        activeElement.nodeName.toUpperCase() === "INPUT"
      ) {
        responseMessage = data.choices[0].message.content;
        console.log(responseMessage);
        // SPECIAL CASES RESPONSE
        // Dont add a period if the original prompt didn't end in one
        if ((
            CM_result === "CM_SpellingGrammar" || 
            CM_result === "CM_Rewrite") && 
            textOriginal.charAt(textOriginal.length - 1) !== "." && 
            responseMessage.charAt(responseMessage.length - 1) === "."
          ) {
          responseMessage = responseMessage.slice(0, -1);
        } 
        // Check for quotation marks and remove them
        if (
            responseMessage.charAt(0) === '"' &&
            responseMessage.charAt(responseMessage.length - 1) === '"'
          ) {
          responseMessage = responseMessage.slice(1, -1);
        }
        // Alert if CM_Answer prompt was not a question
        if (CM_result === "CM_Answer" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            "It appears the prompt provided was not a question. Try submitting a question."
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Alert if CM_Tone prompt was not a valid tone
        if (CM_result === "CM_Tone" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            `It appears the provided tone could not be applied to the text or the prompt provided was not a valid tone. Try submitting a valid tone including but not limited to:nn${toneExamples}`
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Alert if CM_WordCount prompt was not a valid tone
        if (CM_result === "CM_WordCount" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            "It appears the provided word count adjustment was invalid. Try submitting a valid word count adjustment description."
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Alert if CM_GrammarSpelling prompt was not able to be corrected
        if (CM_result === "CM_SpellingGrammar" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            "It appears the prompt you provided was not able to be corrected for grammar or spelling. Please try a different prompt"
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Insert Response
        if (CM_result === "CM_Answer") {
          activeElement.value = activeElement.value + "n" + responseMessage;
        } else {
          activeElement.value = responseMessage;
        }
      }
    } else {
      // Alert reply since no active text area
      alert(`ChatGPT says: ${data.reply}`);
    }
    document.body.style.cursor = "default";
  })
  .catch((error) => {
    console.error(error);
    document.body.style.cursor = "default";
  });
}
