Serve Different Angular Apps on Different Express Routes

I want to serve two defferent angular apps on two different routes: domain.com/admin for admin app and domain.com/customer for customer app.

app.use("/admin", express.static(path.join(process.cwd(), "web/dist/admin")));
app.use("/customer", express.static(path.join(process.cwd(), "web/dist/customer")));

app.get("/admin/**", (req, res) => {
    res.sendFile(path.join(process.cwd(), "web/dist/admin/index.html"));
});
app.get("/customer/**", (req, res) => {
    res.sendFile(path.join(process.cwd(), "web/dist/customer/index.html"));
});

This works, apps are on the routes where they have to be. But I’m getting these error from angular:
enter image description here

Seems like angular can’t get files from the server. Is there something like baseUrl, a path for angular to get the files from?

In a JavaScript program execution of a unexpected if statement

I have created a html page containing three buttons with js code. when i click the first button it shows the value is 0 in the console, and next after set the value ,when i click the next button it shows the value changed to 1. But see the js codes, there how the if statement can execute whereas we have already set the value to 1

I expected that it will not be execute, but it became the opposite… Please answer for this, I didn’t think I would face such a problem

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button onclick="btnf()">Get value</button>
<button onclick="btns()">Set value</button>
<button onclick="btnt()">Get value</button>
<script>
    let value = 0;

    function btnf(){
        console.log(value)
    }
    function btns(){
        value = 1;
    }

    if(value == 0){
        function btnt(){
             console.log(value)
        }
    }
</script>
</body>
</html>

abort() not working in dependent UseEffect

I am trying to optimise my react code by fixing any memory leaks. I am using “createAsyncThunk canceling-while-running” to cancel requests, if my component unmounts. Refer this redux toolkit docs.

I have three reducers inside two useEffects. One dispatches when the component mounts and the other two dispatches when the response from the first dispatched reducer arrives. Below is my code

// this triggers when my component mounts
useEffect(() => {
        const promise = dispatch(bookDetails(bookId))
        return () => promise.abort()
    }, [])

// this is triggered when the response from the dispatched "bookDetails" reducer arrives
// and get stored in the "book" variable as shown in dependency array
useEffect(() => {
    let promise1, promise2
    if (book._id !== undefined) {
         promise1 = dispatch(getComments(book._id))
         promise2 = dispatch(relatedBooks({ genre: book.genre }))
        }
    return () => {
            promise1.abort()  //BookDetails.jsx:58:1
            promise2.abort()
        }
    }, [book])

when the component mounts the second useEffect gives me an error, given below

BookDetails.jsx:58 Uncaught TypeError: Cannot read properties of undefined (reading 'abort')
    at BookDetails.jsx:58:1
    at safelyCallDestroy (react-dom.development.js:22932:1)
    at commitHookEffectListUnmount (react-dom.development.js:23100:1)
    at invokePassiveEffectUnmountInDEV (react-dom.development.js:25207:1)
    at invokeEffectsInDev (react-dom.development.js:27351:1)
    at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27324:1)
    at flushPassiveEffectsImpl (react-dom.development.js:27056:1)
    at flushPassiveEffects (react-dom.development.js:26984:1)
    at performSyncWorkOnRoot (react-dom.development.js:26076:1)
    at flushSyncCallbacks (react-dom.development.js:12042:1)

I tried few things but it didn’t workout for me. Please help. Thanks in advance.

Using Firebase Admin within Deno throwing HTTP 500 for https://esm.sh/v103/@firebase/[email protected]/deno/standalone.js

When attempting to build/deploy this Deno function,

import { serve } from "https://deno.land/[email protected]/http/server.ts";
import "https://deno.land/x/[email protected]/mod.ts";
import { installGlobals } from "https://deno.land/x/[email protected]/mod.ts";
import admin from 'https://esm.sh/[email protected]';
installGlobals();
const serviceAccount = Deno.env.get('service_account');

if (!serviceAccount) {
  throw new Error('service account details not available');
}

admin.initializeApp(JSON.parse(serviceAccount));

serve((_req) => {
  admin.database().ref('/test').set('Hi there');

  return new Response("Maybe done?", {
    headers: { "content-type": "text/plain" },
  });
});

I get the following error

Import ‘https://esm.sh/v103/@firebase/[email protected]/deno/standalone.js’ failed: 500 Internal Server Error
at https://esm.sh/v103/[email protected]/deno/database.js:2:901

Is there anything I can do to fix? Or do I have to find and use a different version of firebase-admin in the function?

Error: Request failed with status code 400 (Axios, Graphql, Mongoose)

I made a server that handles webhook events from a service called Persona that verifies and collects identity information. Everytime I get a webhook call from Persona, I want to do 2 things: I want to take store some of the data from the webhook payload in my Mongoose database AND I want a notification to pop up in discord. If the information taken from the payload already exists in the mongoose db, then I want a notification on discord saying “user already exists”. Otherwise, “new user”.

My problem is that my axios request seems to be failing after getting the webhook call from Persona. This is my code:

require("dotenv").config();
const express = require("express");
const bodyParser = require('body-parser');
const axios = require("axios").default;
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
const mongoose = require('mongoose');

const Event = require('./models/event');


const app = express();
const port = 3000;


app.use(bodyParser.json());

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  next();
});

app.use('/graphql', graphqlHTTP({
  schema: buildSchema(`
  type Event {
    _id: ID!
    lastName: String!
    firstName: String!  
    birthdate: String!
    address: String!
  }

  input EventInput {
    lastName: String!
    firstName: String!  
    birthdate: String!
    address: String!
  }

  type RootQuery {
    events: [Event!]!

  }

  type RootMutation {
    createEvent(eventInput: EventInput): Event
  }


  schema {
    query: RootQuery
    mutation: RootMutation
  }
  `),
  rootValue: {
    events: () => {
      return Event.find()
        .then(events => {
          return events.map(event => {
            return { ...event._doc, _id: event.id };
          });
        })
        .catch(err => {
          throw err;
        });
    },
    createEvent: (args) => {
      return Event.find({lastName: args.eventInput.lastName, firstName: args.eventInput.firstName, birthdate: args.eventInput.birthdate})
      .then( event => {
        if (event) {
          const content = `User already exists: ${args.eventInput.firstName},${args.eventInput.firstName}. Birthdate: 
          ${args.eventInput.birthdate}. address: ${args.eventInput.address}`;

          axios
          .post(process.env.DISCORD_WEBHOOK_URL, {
            content: content,
  
          })
          .then((discordResponse) => {
            console.log("Success!");
          })
        }
        const content = `New User. address: ${args.eventInput.address}`;

        axios
        .post(process.env.DISCORD_WEBHOOK_URL, {
          content: content,

        })
        .then((discordResponse) => {
          console.log("Success!");
        })

        return event
        .save()
        .then(result => {
          console.log(result);
          return { ...result._doc, _id: result._doc._id.toString() };
        })
        .catch(err => {
          console.log(err);
          throw err;
        }); 
      })

  }
},
graphiql: true
})
);

app.post("/", (req, res) => {

    const nameOfEvent = req.body.data.attributes.name;
    const firstName = req.body.data.attributes.payload.data.attributes.nameFirst;
    const lastName = req.body.data.attributes.payload.data.attributes.nameLast;
    const birthdate = req.body.data.attributes.payload.data.attributes.birthdate;
    const address = req.body.data.attributes.payload.data.attributes.fields.address.value;
    if (nameOfEvent == "inquiry.completed") {

axios({
  url: 'http://localhost:3000/graphql',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  data: {
    query: `
      mutation {
        createEvent(eventInput: {lastName: "${lastName}", firstName: "${firstName}", birthdate: "${birthdate}", address: "${address}}) {
          lastName
          firstName
        }
      }
    `
  }
})
  .then(res => {
    if (res.status !== 200 && res.status !== 201) {
      throw new Error('Failed!');
    }
    return res.json();
  })
  .then(resData => {
    console.log(resData);
  })
  .catch(err => {
    console.log(err);
  });
}})
;

app.use((error, req, res, next) => {
  res.status(500)
  res.send({ error: error })
  console.error(error.stack)
  next(error)
})


mongoose
  .connect(
    `mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@cluster0.nrtrssh.mongodb.net/${process.env.MONGO_DB}?retryWrites=true&w=majority`
  )
  .then(() => {
    app.listen(port, () =>
  console.log(`Example app listening at http://localhost:${port}`)
);
  })
  .catch(err => {
    console.log(err);
  });

This is my event schema:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const eventSchema = new Schema({
  lastName: {
    type: String,
    required: true
  },
  firstName: {
    type: String,
    required: true
  },
  birthdate: {
    type: String,
    required: true
  },
  address: {
    type: String,
    required: true
  }
});

module.exports = mongoose.model('Event', eventSchema);

This was I got in my terminal:

  config: {
    url: 'http://localhost:3000/graphql',
    method: 'post',
    data: '{"query":"\n      mutation {\n        createEvent(eventInput: {lastName: \"SAMPLE\", firstName: \"ALEXANDER J\", birthdate: \"1977-07-17\", address: \"0x98433A5F2127b48Ae71f638e81f99b211e1F8ab6}) {\n          lastName\n          firstName\n        }\n      }\n    "}',
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      'User-Agent': 'axios/0.21.1',
      'Content-Length': 266
    },
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    adapter: [Function: httpAdapter],
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus]
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: false,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: null,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'localhost',
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      parser: null,
      _httpMessage: [Circular *1],
      [Symbol(async_id_symbol)]: 262,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    _header: 'POST /graphql HTTP/1.1rn' +
      'Accept: application/json, text/plain, */*rn' +
      'Content-Type: application/jsonrn' +
      'User-Agent: axios/0.21.1rn' +
      'Content-Length: 266rn' +
      'Host: localhost:3000rn' +
      'Connection: closern' +
      'rn',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    path: '/graphql',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [Socket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 400,
      statusMessage: 'Bad Request',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'http://localhost:3000/graphql',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(RequestTimeout)]: undefined
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'localhost',
    protocol: 'http:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 266,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'http://localhost:3000/graphql',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'user-agent': [Array],
      'content-length': [Array],
      host: [Array]
    }
  },
  response: {
    status: 400,
    statusText: 'Bad Request',
    headers: {
      'x-powered-by': 'Express',
      'access-control-allow-origin': '*',
      'access-control-allow-methods': 'POST,GET,OPTIONS',
      'access-control-allow-headers': 'Content-Type, Authorization',
      'content-type': 'application/json; charset=utf-8',
      'content-length': '99',
      etag: 'W/"63-STfhlTxeoEFxDo5wbBoiR3lYMrg"',
      date: 'Sat, 21 Jan 2023 03:44:04 GMT',
      connection: 'close'
    },
    config: {
      url: 'http://localhost:3000/graphql',
      method: 'post',
      data: '{"query":"\n      mutation {\n        createEvent(eventInput: {lastName: \"SAMPLE\", firstName: \"ALEXANDER J\", birthdate: \"1977-07-17\", address: \"0x98433A5F2127b48Ae71f638e81f99b211e1F8ab6}) {\n          lastName\n          firstName\n        }\n      }\n    "}',
      headers: [Object],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      adapter: [Function: httpAdapter],
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      validateStatus: [Function: validateStatus]
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: [Socket],
      _header: 'POST /graphql HTTP/1.1rn' +
        'Accept: application/json, text/plain, */*rn' +
        'Content-Type: application/jsonrn' +
        'User-Agent: axios/0.21.1rn' +
        'Content-Length: 266rn' +
        'Host: localhost:3000rn' +
        'Connection: closern' +
        'rn',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: noopPendingOutput],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      path: '/graphql',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'localhost',
      protocol: 'http:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    data: { errors: [Array] }
  },
  isAxiosError: true,
  toJSON: [Function: toJSON]
}

Im trying to find the index of some elements in an array, but I redefined the array to get said elements and if I make a copy it gets redefined aswell

I’m solving the leetcode TwoSum problem in javascript. I made a search algorithm that alters the nums array until the first and last indexes are the correct numbers to add to the sum. Then I try to search through an original of the nums array before I altered it to find the indexes of the correct numbers in the original array, but the problem is the saved copy array gets redefined as I alter the first array. Then I can’t check against it and find the correct indexes. I tried defining original as a function or even a class, but neither worked; how do I keep it from changing?

const searchAlgorithm = (nums, target) => {
    nums = nums.sort((a, b)=>a-b);
    while(true){
        total = nums[0]+nums[nums.length-1];
            if(total>target){
                nums.splice(nums.length-1, 1);
            }
            else{
                if(total==target){
                    answers = [nums[0], nums[nums.length-1]];
                    return answers;
                }
                else{
                    nums.splice(0, 1);
                }
            }
    }
}


const twoSum = (nums, target)=>{
    original = nums;
    [num1, num2] = searchAlgorithm(nums, target);
    answers = [original.indexOf(num1, 0), original.indexOf(num2, 0)];
    return (answers);
}

console.log(twoSum([3,6,8,2,11], 5));

Async/await & promise to wait for a post request to complete and get what was added does not work

So, when I create a new user, it is added to the database, and after that I want to receive the list of updated users. But even waiting for the finalization of the post method to happen, the new user that has just been created is never returned, only after the creation of a new user does the fetch return the one that was previously created.

I tried this:

createUser()
    async function createUser(){
        const response = await fetch("http://localhost:3334/user", {
            method: "POST",
            body: JSON.stringify({
              name: name,
              password: password,
              email: email,
            }),
            headers: {
              "Content-type": "application/json; charset=UTF-8",
            },
          })
          const data = await response.json()
          console.log(data)

          const fetchResponse = await fetch("http://localhost:3334/users")
          const fetchData = await fetchResponse.json()
          
          console.log(fetchData)
          
    }

And this:

    fetch("http://localhost:3334/user", {
      method: "POST",
      body: JSON.stringify({
        name: name,
        password: password,
        email: email,
      }),
      headers: {
        "Content-type": "application/json; charset=UTF-8",
      },
    }).then((response) => {
      if (response.status === 200) {
        return fetch("http://localhost:3334/users")
          .then((response) => response.json())
          .then((data) => console.log(data));
      }
    });

I expect that the user that I just created, appear in the GET method.

This is /user endpoint using express:

router.post('/user', (req, res) => {
    res.json({requestBody: req.body})
    bcrypt.hash(req.body.password, saltRounds, function(err, hash) {
        db.query("INSERT INTO users (email, name, password) VALUES (?,?,?)", [req.body.email, req.body.name, hash], function(err, result) {
        if (err) throw err;
        console.log("Result: " + JSON.stringify(result));
      })
    
    });
})

How to make this div scrollTop value match that of the textarea?

I’m using a div to format and display the text from a textarea of equal dimensions and I need them to be permanently in sync. However, I haven’t been able to synchronize their respective scrollTops after the input text goes past the bottom of the textarea.

My process has been similar to the one described here, however I can’t get his solution to work on my project.

Here’s a demo and snippets of the minimum relevant code:

<section>
  <div class="input-text__container">
    <div id="input-text--mirror" class="input-text"></div>
      <textarea
        id="input-text--original"
        cols="30"
        rows="6"
        autofocus
        class="input-text"
        placeholder="Enter your text here"
        autocomplete="off"
        autocorrect="off"
        spellcheck="false"
      ></textarea>
  </div>
<section>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap');

html {
  font-size: 62.5%;
  box-sizing: border-box;
  scroll-behavior: smooth;
}

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  border: 0;
  box-sizing: inherit;
  vertical-align: baseline;
}

body {
  height: 100vh;
}

section {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  padding: 1rem;
}

.input-text__container {
  width: 100%;
  position: relative;
  flex: 1;
}

.input-text {
  width: 100%;
  height: 100%;
  position: absolute;
  font-size: 3.2rem;
  overflow-wrap: break-word;
  font-family: "Inter";
}

#input-text--mirror {
  background-color: #e9ecf8;
  color: #0a3871;
  overflow: hidden;
}

#input-text--original {
  background-color: transparent;
  -webkit-text-fill-color: transparent;
  resize: none;
  outline: none;
  -ms-overflow-style: none; /* IE and Edge */
  scrollbar-width: none; /* Firefox */
}

#input-text--original::placeholder {
  color: #e9ecf8;
  -webkit-text-fill-color: #052051;
}

#input-text--original::selection {
  -webkit-text-fill-color: #ffffff;
}

.invalid {
  font-weight: 400;
  color: #ff0000;
}

#input-text--original::-webkit-scrollbar {
  display: none;
}
let invalidInput = false;
const patterns = {
  valid: "a-z ",
  invalid: "[^a-z ]",
  linebreaks: "r|rn|n",
};
const textIn = document.querySelector("#input-text--original");
const mirror = document.querySelector("#input-text--mirror");

function validateInput(string, className) {
  let anyInvalidChar = false;

  // Generate regular expressions for validation
  const regExpInvalids = new RegExp(patterns.invalid, "g");
  const regExpLinebreaks = new RegExp(patterns.linebreaks);

  // Generate innerHTML for mirror
  const mirrorContent = string.replace(regExpInvalids, (match) => {
    if (regExpLinebreaks.test(match)) {
      return "<br/>";
    } else {
      anyInvalidChar = true;
      return `<span class=${className}>${match}</span>`;
    }
  });
  // Update mirror
  mirror.innerHTML = mirrorContent;

  return anyInvalidChar;
}

textIn.addEventListener("input", (e) => {
  const plain = textIn.value;
  const newInputValidity = validateInput(plain, "invalid");
  mirror.scrollTop = textIn.scrollTop;
});

textIn.addEventListener(
  "scroll",
  () => {
    mirror.scrollTop = textIn.scrollTop;
  },
  { passive: true }
);

On a desktop screen typing the first 8 natural numbers in a column should be enough to reproduce the issue.

The last thing I checked, but perhaps the most relevant so far was this. It seems to deal with the exact same issue on React, but I’m afraid I don’t know how to adapt that solution to Vanilla JavaScript, since I’m just starting to learn React. Please, notice, I’m trying to find a solution that doesn’t depend on libraries like jQuery or React.

Besides that, I tried the solution described in the aforementioned blog, by replacing return "<br/>"; with return "<br/>&nbsp;"; in my validateInput function but that didn’t work. I also added a conditional to append a space to plain in const plain = textIn.value; in case the last char was a linebreak, but I had no luck.

I also included console.log commands before and after mirror.scrollTop = textIn.scrollTop; in the textIn scroll handler to track the values of each scrollTop and even when they were different, the mirror scrollTop wasn’t updated. I read it might be because divs weren’t scrollable by default, but adding “overflow: scroll” to its styles didn’t fix the problem either.

I read about other properties related to scrollTop, like offsetTop and pageYOffset, but they’re either read-only or not defined for divs.

I’ve reviewed the following posts/sites, too, but I’ve still haven’t been able to fix this problem.

I no longer remember what else I’ve reviewed, but nothing has worked and I no longer know what else to do. Thank you for your attention and help.

Why is the “myText1” and “myText3” id and function interfering with one another?

Im making this website as a school project and I need it done real quick. When I use the save function for a contenteditable data table, one cell saves how it should but it also changes the value of another cell. I want to split these two cells into unique cells that are both editable and saveable and are distinct from one another. Here is my code.

<html>
<meta name="viewport" content="width=device-width, initial-scale=1">

</body>

</html>
<html>
<style>
    table.GeneratedTable {
        width: 100%;
        background-color: #ffffff;
        border-collapse:
            collapse;
        border-width: 2px;
        border-color: #000000;
        border-style: solid;
        color: #000000;
    }

    table.GeneratedTable td,
    table.GeneratedTable th {
        border-width:
            2px;
        border-color: #000000;
        border-style: solid;
        padding: 3px;
    }

    table.GeneratedTable thead {
        background-color: #ffa500;
    }
</style>
<table class="GeneratedTable">
    <thead>
        <tr>
            <th> Book Name </th>
            <th> Author </th>
            <th> Teacher Name </th>
            <th> Number of Books </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <div>  <style>
                        p {
                            margin: 1em;
                            color: #777;
                        }

                        p.changed {
                            color: black;
                        }

                        button {
                            margin:
                                0 1em;
                        }

                        .btn {
                            display: inline-block;
                            *display: inline;
                            padding: 4px 10px 4px;
                            margin-bottom: 0;
                            *margin-left: .3em;
                            font-size: 13px;
                            line-height:
                                18px;
                            *line-height: 20px;
                            color: #333333;
                            text-align: center;
                            text-shadow:
                                0 1px 1px rgba(255, 255, 255, 0.75);
                            vertical-align: middle;
                            cursor: pointer;
                            background-color: #f5f5f5;
                            *background-color: #e6e6e6;
                            background-image:
                                -ms-linear-gradient(top, #ffffff, #e6e6e6);
                            background-image: -webkit-gradient(linear,
                                    0 0, 0 100%, from(#ffffff), to(#e6e6e6));
                            background-image: -webkit-linear-gradient(top,
                                    #ffffff, #e6e6e6);
                            background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
                            background-image: linear-gradient(top, #ffffff, #e6e6e6);
                            background-image:
                                -moz-linear-gradient(top, #ffffff, #e6e6e6);
                            background-repeat: repeat-x;
                            border: 1px solid #cccccc;
                            *border: 0;
                            border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
                            border-color: #e6e6e6 #e6e6e6 #bfbfbf;
                            border-bottom-color: #b3b3b3;
                            -webkit-border-radius: 4px;
                            -moz-border-radius:
                                4px;
                            border-radius: 4px;
                            filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff',
                                    endColorstr='#e6e6e6', GradientType=0);
                            filter: progid:dximagetransform.microsoft.gradient(enabled=false);
                            *zoom: 1;
                            -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
                            -moz-box-shadow: inset 0 1px 0 rgba(255, 255,
                                    255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
                            box-shadow: inset 0 1px 0 rgba(255,
                                    255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
                        }

                        .btn:hover,
                        .btn:active,
                        .btn.active,
                        .btn.disabled,
                        .btn[disabled] {
                            background-color: #e6e6e6;
                            *background-color: #d9d9d9;
                        }

                        .btn:active,
                        .btn.active {
                            background-color:
                                #cccccc 9;
                        }

                        .btn:first-child {
                            *margin-left: 0;
                        }

                        .btn:hover {
                            color:
                                #333333;
                            text-decoration: none;
                            background-color: #e6e6e6;
                            *background-color:
                                #d9d9d9;
                            /* Buttons in IE7 don't get borders, so darken on hover */
                            background-position:
                                0 -15px;
                            -webkit-transition: background-position 0.1s linear;
                            -moz-transition:
                                background-position 0.1s linear;
                            -ms-transition: background-position 0.1s linear;
                            -o-transition: background-position 0.1s linear;
                            transition: background-position 0.1s linear;
                        }

                        .btn:focus {
                            outline: thin dotted #333;
                            outline: 5px auto -webkit-focus-ring-color;
                            outline-offset: -2px;
                        }

                        .btn.active,
                        .btn:active {
                            background-color: #e6e6e6;
                            background-color: #d9d9d9 9;
                            background-image:
                                none;
                            outline: 0;
                            -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),
                                0 1px 2px rgba(0, 0, 0, 0.05);
                            -moz-box-shadow: inset 0 2px 4px rgba(0,
                                    0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
                            box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
                        }

                        .btn-primary {
                            background-color:
                                #0074cc;
                            *background-color: #0055cc;
                            background-image: -ms-linear-gradient(top,
                                    #0088cc, #0055cc);
                            background-image: -webkit-gradient(linear, 0 0, 0 100%,
                                    from(#0088cc), to(#0055cc));
                            background-image: -webkit-linear-gradient(top,
                                    #0088cc, #0055cc);
                            background-image: -o-linear-gradient(top, #0088cc, #0055cc);
                            background-image: -moz-linear-gradient(top, #0088cc, #0055cc);
                            background-image:
                                linear-gradient(top, #0088cc, #0055cc);
                            background-repeat: repeat-x;
                            border-color:
                                #0055cc #0055cc #003580;
                            border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0,
                                    0.1) rgba(0, 0, 0, 0.25);
                            filter: progid:dximagetransform.microsoft.gradient(startColorstr='#0088cc',
                                    endColorstr='#0055cc', GradientType=0);
                            filter: progid:dximagetransform.microsoft.gradient(enabled=false);
                        }

                        .btn-primary:hover,
                        .btn-primary:active,
                        .btn-primary.active,
                        .btn-primary.disabled,
                        .btn-primary[disabled] {
                            background-color: #0055cc;
                            *background-color:
                                #004ab3;
                        }

                        .btn-primary:active,
                        .btn-primary.active {
                            background-color:
                                #004099 9;
                        }

                        .btn-warning {
                            background-color: #faa732;
                            *background-color:
                                #f89406;
                            background-image: -ms-linear-gradient(top, #fbb450, #f89406);
                            background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450),
                                    to(#f89406));
                            background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
                            background-image: -o-linear-gradient(top, #fbb450, #f89406);
                            background-image:
                                -moz-linear-gradient(top, #fbb450, #f89406);
                            background-image: linear-gradient(top,
                                    #fbb450, #f89406);
                            background-repeat: repeat-x;
                            border-color: #f89406 #f89406 #ad6704;
                            border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0,
                                    0, 0.25);
                            filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450',
                                    endColorstr='#f89406', GradientType=0);
                            filter: progid:dximagetransform.microsoft.gradient(enabled=false);
                        }

                        .btn-warning:hover,
                        .btn-warning:active,
                        .btn-warning.active,
                        .btn-warning.disabled,
                        .btn-warning[disabled] {
                            background-color: #f89406;
                            *background-color:
                                #df8505;
                        }

                        .btn-warning:active,
                        .btn-warning.active {
                            background-color:
                                #c67605 9;
                        }

                        .btn-primary,
                        .btn-primary:hover,
                        .btn-warning,
                        .btn-warning:hover,
                        .btn-danger,
                        .btn-danger:hover,
                        .btn-success,
                        .btn-success:hover,
                        .btn-info,
                        .btn-info:hover,
                        .btn-inverse,
                        .btn-inverse:hover {
                            color: #ffffff;
                            text-shadow:
                                0 -1px 0 rgba(0, 0, 0, 0.25);
                        }

                        .btn-primary.active,
                        .btn-warning.active,
                        .btn-danger.active,
                        .btn-success.active,
                        .btn-info.active,
                        .btn-inverse.active {
                            color: rgba(255, 255, 255, 0.75);
                        }
                    </style>
                    <p id="myText" contenteditable> fafa </p>
                    <button class="btn btn-primary" onclick="saveChanges()"> Save </button>
                    <script>
                        var text = document.Document.getElementsById('myText');
                        var myData;
                        var postData = window.localStorage.getItem("save");
                        var reset = text.innerHTML;
                        // if no data
                        if (postData == null || postData == '') {
                            myData = text.innerHTML;
                            // store default value
                            window.localStorage.setItem("save", myData);
                            // make it placeholder style
                            text.classList.remove('changed');
                        } else {
                            // if there is a value post it
                            text.innerHTML = postData;
                            // make dark text
                            text.classList.add('changed');
                        }

                        function saveChanges() {
                            // store the current value
                            myData = text.innerHTML;
                            // local store the value
                            window.localStorage.setItem("save", myData);
                            text.classList.add('changed');
                        }

                        function clearStorage() {
                            text.classList.remove('changed');
                            // clear storage
                            window.localStorage.clear("save");
                            // return to default text
                            text.innerHTML = reset;
                        }
                    </script>
            </td>
            <td>
                <div>  <style>
                        p {
                            margin: 1em;
                            color: #777;
                        }

                        p.changed {
                            color: black;
                        }

                        button {
                            margin:
                                0 1em;
                        }

                        .btn {
                            display: inline-block;
                            *display: inline;
                            padding: 4px 10px 4px;
                            margin-bottom: 0;
                            *margin-left: .3em;
                            font-size: 13px;
                            line-height:
                                18px;
                            *line-height: 20px;
                            color: #333333;
                            text-align: center;
                            text-shadow:
                                0 1px 1px rgba(255, 255, 255, 0.75);
                            vertical-align: middle;
                            cursor: pointer;
                            background-color: #f5f5f5;
                            *background-color: #e6e6e6;
                            background-image:
                                -ms-linear-gradient(top, #ffffff, #e6e6e6);
                            background-image: -webkit-gradient(linear,
                                    0 0, 0 100%, from(#ffffff), to(#e6e6e6));
                            background-image: -webkit-linear-gradient(top,
                                    #ffffff, #e6e6e6);
                            background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
                            background-image: linear-gradient(top, #ffffff, #e6e6e6);
                            background-image:
                                -moz-linear-gradient(top, #ffffff, #e6e6e6);
                            background-repeat: repeat-x;
                            border: 1px solid #cccccc;
                            *border: 0;
                            border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
                            border-color: #e6e6e6 #e6e6e6 #bfbfbf;
                            border-bottom-color: #b3b3b3;
                            -webkit-border-radius: 4px;
                            -moz-border-radius:
                                4px;
                            border-radius: 4px;
                            filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff',
                                    endColorstr='#e6e6e6', GradientType=0);
                            filter: progid:dximagetransform.microsoft.gradient(enabled=false);
                            *zoom: 1;
                            -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
                            -moz-box-shadow: inset 0 1px 0 rgba(255, 255,
                                    255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
                            box-shadow: inset 0 1px 0 rgba(255,
                                    255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
                        }

                        .btn:hover,
                        .btn:active,
                        .btn.active,
                        .btn.disabled,
                        .btn[disabled] {
                            background-color: #e6e6e6;
                            *background-color: #d9d9d9;
                        }

                        .btn:active,
                        .btn.active {
                            background-color:
                                #cccccc 9;
                        }

                        .btn:first-child {
                            *margin-left: 0;
                        }

                        .btn:hover {
                            color:
                                #333333;
                            text-decoration: none;
                            background-color: #e6e6e6;
                            *background-color:
                                #d9d9d9;
                            /* Buttons in IE7 don't get borders, so darken on hover */
                            background-position:
                                0 -15px;
                            -webkit-transition: background-position 0.1s linear;
                            -moz-transition:
                                background-position 0.1s linear;
                            -ms-transition: background-position 0.1s linear;
                            -o-transition: background-position 0.1s linear;
                            transition: background-position 0.1s linear;
                        }

                        .btn:focus {
                            outline: thin dotted #333;
                            outline: 5px auto -webkit-focus-ring-color;
                            outline-offset: -2px;
                        }

                        .btn.active,
                        .btn:active {
                            background-color: #e6e6e6;
                            background-color: #d9d9d9 9;
                            background-image:
                                none;
                            outline: 0;
                            -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),
                                0 1px 2px rgba(0, 0, 0, 0.05);
                            -moz-box-shadow: inset 0 2px 4px rgba(0,
                                    0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
                            box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
                        }

                        .btn-primary {
                            background-color:
                                #0074cc;
                            *background-color: #0055cc;
                            background-image: -ms-linear-gradient(top,
                                    #0088cc, #0055cc);
                            background-image: -webkit-gradient(linear, 0 0, 0 100%,
                                    from(#0088cc), to(#0055cc));
                            background-image: -webkit-linear-gradient(top,
                                    #0088cc, #0055cc);
                            background-image: -o-linear-gradient(top, #0088cc, #0055cc);
                            background-image: -moz-linear-gradient(top, #0088cc, #0055cc);
                            background-image:
                                linear-gradient(top, #0088cc, #0055cc);
                            background-repeat: repeat-x;
                            border-color:
                                #0055cc #0055cc #003580;
                            border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0,
                                    0.1) rgba(0, 0, 0, 0.25);
                            filter: progid:dximagetransform.microsoft.gradient(startColorstr='#0088cc',
                                    endColorstr='#0055cc', GradientType=0);
                            filter: progid:dximagetransform.microsoft.gradient(enabled=false);
                        }

                        .btn-primary:hover,
                        .btn-primary:active,
                        .btn-primary.active,
                        .btn-primary.disabled,
                        .btn-primary[disabled] {
                            background-color: #0055cc;
                            *background-color:
                                #004ab3;
                        }

                        .btn-primary:active,
                        .btn-primary.active {
                            background-color:
                                #004099 9;
                        }

                        .btn-warning {
                            background-color: #faa732;
                            *background-color:
                                #f89406;
                            background-image: -ms-linear-gradient(top, #fbb450, #f89406);
                            background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450),
                                    to(#f89406));
                            background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
                            background-image: -o-linear-gradient(top, #fbb450, #f89406);
                            background-image:
                                -moz-linear-gradient(top, #fbb450, #f89406);
                            background-image: linear-gradient(top,
                                    #fbb450, #f89406);
                            background-repeat: repeat-x;
                            border-color: #f89406 #f89406 #ad6704;
                            border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0,
                                    0, 0.25);
                            filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450',
                                    endColorstr='#f89406', GradientType=0);
                            filter: progid:dximagetransform.microsoft.gradient(enabled=false);
                        }

                        .btn-warning:hover,
                        .btn-warning:active,
                        .btn-warning.active,
                        .btn-warning.disabled,
                        .btn-warning[disabled] {
                            background-color: #f89406;
                            *background-color:
                                #df8505;
                        }

                        .btn-warning:active,
                        .btn-warning.active {
                            background-color:
                                #c67605 9;
                        }

                        .btn-primary,
                        .btn-primary:hover,
                        .btn-warning,
                        .btn-warning:hover,
                        .btn-danger,
                        .btn-danger:hover,
                        .btn-success,
                        .btn-success:hover,
                        .btn-info,
                        .btn-info:hover,
                        .btn-inverse,
                        .btn-inverse:hover {
                            color: #ffffff;
                            text-shadow:
                                0 -1px 0 rgba(0, 0, 0, 0.25);
                        }

                        .btn-primary.active,
                        .btn-warning.active,
                        .btn-danger.active,
                        .btn-success.active,
                        .btn-info.active,
                        .btn-inverse.active {
                            color: rgba(255, 255, 255, 0.75);
                        }
                    </style>
                    <p id="myText2" contenteditable> Book Name </p>
                    <button class="btn btn-primary" onclick="saveChanges()"> Save </button>
                    <script>
                        var text = document.getElementById('myText2');
                        var myData;
                        var postData = window.localStorage.getItem("save");
                        var reset = text.innerHTML;
                        // if no data
                        if (postData == null || postData == '') {
                            myData = text.innerHTML;
                            // store default value
                            window.localStorage.setItem("save", myData);
                            // make it placeholder style
                            text.classList.remove('changed');
                        } else {
                            // if there is a value post it
                            text.innerHTML = postData;
                            // make dark text
                            text.classList.add('changed');
                        }

                        function saveChanges() {
                            // store the current value
                            myData = text.innerHTML;
                            // local store the value
                            window.localStorage.setItem("save", myData);
                            text.classList.add('changed');
                        }

                        function clearStorage() {
                            text.classList.remove('changed');
                            // clear storage
                            window.localStorage.clear("save");
                            // return to default text
                            text.innerHTML = reset;
                        }
                    </script>
            
          
            
            <td>
                <div contenteditable> 
                <p id="myText3" contenteditable > Book Name </p>
                    <button class="btn btn-primary" onclick="saveChanges()"> Save </button>
                    <script>
                        var text = document.getElementById('myText3');
                        var myData;
                        var postData = window.localStorage.getItem("save");
                        var reset = text.innerHTML;
                        // if no data
                        if (postData == null || postData == '') {
                            myData = text.innerHTML;
                            // store default value
                            window.localStorage.setItem("save", myData);
                            // make it placeholder style
                            text.classList.remove('changed');
                        } else {
                            // if there is a value post it
                            text.innerHTML = postData;
                            // make dark text
                            text.classList.add('changed');
                        }

                        function saveChanges() {
                            // store the current value
                            myData = text.innerHTML;
                            // local store the value
                            window.localStorage.setItem("save", myData);
                            text.classList.add('changed');
                        }

                        function clearStorage() {
                            text.classList.remove('changed');
                            // clear storage
                            window.localStorage.clear("save");
                            // return to default text
                            text.innerHTML = reset;
                        }
                        
                        
                            
                    </script>
            </td>
            
        </tr>
</table>
</body>

</html>

So I tried to copy and paste the same code of the working saveable cell, into the new cell, but instead it made the two cells interlinked and by editing one and saving it, it changed itself and the other one.

How to change css html { } attribute for a single page

First time posting here. I was wondering how to change the css for the html { } attribute of a single page. I am trying to make the background color for 2 pages different. If there is a better way to do it please let me know. Thanks!

I have done this:

html {
  background-color: black;
}

for one page.

I want to do the same thing with a different color for another page (so that when you scroll out of bounds of the div it does not show a different color).

Multiple HTML audio players with play/pause toggle text buttons

I’m an absolute newbie when it comes to javascript, but I’m trying to implement multiple audio players with separate songs on a page where the buttons toggles between the text “Listen” and “Pause” when clicked.

With the following code the text toggle works, but it only plays and pauses the first song. I recognize that I’m not even close here, but would love if someone can show me how to achieve what I want to do.

<audio id="song1" src='audio/song1.mp3'></audio>
<button id="song1Button">Listen</button>

<audio id="song2" src='audio/song2.mp3'></audio>
<button id="song2Button">Listen</button>
document.getElementById('song1Button').onclick = player;

function player(event) {
  const clicked = event.target;
  clicked.classList.toggle('playing');
  const song = document.getElementById('song1');
  if (song.paused || song.ended) {
    song.play();
  } else {
    song.pause();
  }
}

document.getElementById("song1Button").addEventListener("click", function (e) {
  document.body.classList.toggle('listen');
  // element.classList.toggle("listen");
  if (e.target.textContent === "Listen") {
    e.target.textContent = "Pause";
  } else {
    e.target.textContent = "Listen";
  }
});

document.getElementById('song2Button').onclick = player;

function player(event) {
  const clicked = event.target;
  clicked.classList.toggle('playing');
  const song = document.getElementById('song2');
  if (song.paused || song.ended) {
    song.play();
  } else {
    song.pause();
  }
}

document.getElementById("song2Button").addEventListener("click", function (e) {
  document.body.classList.toggle('listen');
  // element.classList.toggle("listen");
  if (e.target.textContent === "Listen") {
    e.target.textContent = "Pause";
  } else {
    e.target.textContent = "Listen";
  }
});

How To Set Image In Foreach Side By Side

How make the images in this looping condition appear side by side

Below is my source code

                       @foreach ($dataLevelTiga as $keyTiga => $itemTiga)
                            @if ($itemTiga->opsi_jawaban != 'option')
                                @php
                                    $dataDetailJawabanText = AppModelsJawabanTextModel::select('jawaban_text.id', 'jawaban_text.id_pengajuan', 'jawaban_text.id_jawaban', 'jawaban_text.opsi_text', 'item.id as id_item', 'item.nama')
                                        ->join('item', 'jawaban_text.id_jawaban', 'item.id')
                                        ->where('jawaban_text.id_pengajuan', $dataUmum->id)
                                        ->where('jawaban_text.id_jawaban', $itemTiga->id)
                                        ->get();
                                @endphp
                                @foreach ($dataDetailJawabanText as $itemTextTiga)
                                    @if ($itemTextTiga->nama != 'Ratio Tenor Asuransi')                                               
                                            @if ($itemTiga->opsi_jawaban == 'file')
                                                    <div class="form-group col-md-6 mb-0">
                                                        <label for="">{{ $itemTextTiga->nama }}</label>
                                                    </div>
                                                    <div class="col-md-6 form-group">
                                                        <b>Jawaban: </b>
                                                        <div class="mt-2">
                                                            @php
                                                                $file_parts = pathinfo(asset('..') . '/upload/' . $dataUmum->id . '/' . $itemTiga->id . '/' . $itemTextTiga->opsi_text);
                                                            @endphp
                                                            @if ($file_parts['extension'] == 'pdf')
                                                                <iframe src="{{ asset('..') . '/upload/' . $dataUmum->id . '/' . $itemTiga->id . '/' . $itemTextTiga->opsi_text }}" width="100%" height="300px"></iframe>
                                                            @else
                                                                <img src="{{ asset('..') . '/upload/' . $dataUmum->id . '/' . $itemTiga->id . '/' . $itemTextTiga->opsi_text }}" alt="" width="300px">
                                                            @endif
                                                        </div>
                                                    </div>         
                                            @endif
                                    @endif
                                @endforeach
                            @endif
                        @endforeach

The source code above if it will be like this

There is my image

I want to change side by side, any solution ?

Horizontal Slider X axis

I have a container in which it is a horizontal scroll slider. I am just trying to figure how to show the element that is in the viewport at the time

<div class="slider hidden" id="slideshowContainer">
                <div class="innerSlider" id="innerSlider">
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1586023492125-27b2c045efd7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=958&q=80"
                            alt=""
                            draggable="false"
                        />
                    </div>
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1583847268964-b28dc8f51f92?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"
                            alt=""
                            draggable="false"
                        />
                    </div>
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1586105251261-72a756497a11?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=958&q=80"
                            alt=""
                            draggable="false"
                        />
                    </div>
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1618220048045-10a6dbdf83e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=880&q=80"
                            alt=""
                            draggable="false"
                        />
                    </div>
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1513694203232-719a280e022f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1169&q=80"
                            alt=""
                        />
                    </div>
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1513694203232-719a280e022f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1169&q=80"
                            alt=""
                            draggable="false"
                        />
                    </div>
                    <div class="slide">
                        <img
                            src="https://images.unsplash.com/photo-1513694203232-719a280e022f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1169&q=80"
                            alt=""
                            draggable="false"
                        />
                    </div>
                </div>
            </div>

This is just the scroll function I have

    const scroll = () => {
        const scrollContainer = document.querySelector('.slider');

        scrollContainer.addEventListener('wheel', (e) => {
            e.preventDefault();
            scrollContainer.scrollLeft += e.deltaY;
        });
    };
    //

I tried to look for left. I tried to put the slides in an array and look for the x axis but I am a little stumped

How do you de-hash when requested by the system?

I have a Javascript hasher that generates a hash. I need a system that would de-hash it when a button is clicked, etc.

Here is the code.

hashCode = function(s) {
  return s.split("").reduce(function(a, b) {
    a = ((a << 5) - a) + b.charCodeAt(0);
    return a & a;
  }, 0);
}
 
 // testing
 alert(hashCode("Hi."));