0

I have a string like this inside a textarea with id #map_coords.

[id:1,x:288.43,y:260.15,url:#]-[id:2,x:396.43,y:310.15,url:#]-[id:3,x:503.43,y:299.15,url:#]-[id:4,x:642.43,y:191.15,url:#]

I assign the string to a variable: var getVals = jQuery('#map_coords').val();

I am converting the string to array: getVals = getVals.split("-");

So now the above string looks like this:

Array
0: [id:1,x:288.43,y:260.15,url:#]
1: [id:2,x:396.43,y:310.15,url:#]
2: [id:3,x:503.43,y:299.15,url:#]
3: [id:4,x:642.43,y:191.15,url:#]

Then, with a click of a button, I want to delete a value inside the array, let's say the 2nd one (1:). I do that with this:

getVals.splice((getMap - 1),1);

The getMap variable is always the same value as the id: inside the array. So if I need to delete the id:2 I will splice the 1 value (that's why I do getMap - 1 ).

After the deletion, the array looks like this:

Array
0: [id:1,x:288.43,y:260.15,url:#]
1: [id:3,x:503.43,y:299.15,url:#]
2: [id:4,x:642.43,y:191.15,url:#]

Which is good, but the problem is that now the 1: key, has an id:3 which is wrong. I want to change that to id:2. Same goes for the id:4 that needs to change to id:3 and so on for every key inside the array AFTER the id:2. And this id:2 is not static but dynamically changes depending on the getMap variable. To do this, I convert once again the key into another array. Like this:

var arrLength = getVals.length;
for (var i = (getMap - 1); i < arrLength; i++) {
  var newVals = getVals[i].split(",");
}

The magic happens inside the for arguements, where I set the var i = (getMap - 1). This helps me do changes to the values that proceed the key I changed.

Now we get to split each key and the results for the are these:

0: [id:3
1: x:503.43
2: y:299.15
3: url:#]

and this:

0: [id:4
1: x:642.43
2: y:191.15
3: url:#]

Great! Now I can simply change only the [0] key and substract 1 from their values, making 3 into 2 and 4 into 3 and so on until the array ends. I do it like this:

var arrLength = getVals.length;
for (var i = (getMap - 1); i < arrLength; i++) {
  var newVals = getVals[i].split(",");
  for (var x = 0; x < 1; x++) {
    newVals = newVals[0].replace((i+2),(i+1));
  }
}

If I do console.log(newVals) I get the correct changed values:

[id:2
[id:3

Yes! It worked but... now, how do I put these new values back to the original getVals array? The final form that I need to get is this:

[id:1,x:288.43,y:260.15,url:#]-[id:2,x:503.43,y:299.15,url:#]-[id:3,x:642.43,y:191.15,url:#]

It's the same string you saw at the start of this post only that the id:2 key is now deleted and all the following keys have their id:'s substracted by 1.

Finally I will do: getVals.toString().replace( /],/g,']-'); which helps me add the - symbol in-between the arrays and convert the whole thing into a string again and pass it as a value inside the textarea where it came from!

So my only problem is how can I update the results of newVals inside my getVals array?

Thanks so much if you read all of this!

3
  • 3
    Why aren't you using JSON in the text area to begin with? Commented Nov 4, 2021 at 15:17
  • what is url:# ? in JS # is supposed to be an object of your own... Commented Nov 4, 2021 at 15:25
  • Telling us what you're doing is good. Telling us what you want to achieve is even better! Commented Nov 4, 2021 at 15:37

2 Answers 2

1

I strongy suggest you paste JSON into the textarea

Here I do simple replacing to get a proper object - this is all unnecessary if you have a proper JSON string to begin with

let  str = document.querySelector("#t1").value;
// replace to make a proper JSON 
str = "["+str
  .replaceAll("#",'"#"}')
  .replaceAll("-",",")
  .replaceAll("x",'"x"')
  .replaceAll("y",'"y"')
  .replaceAll("id",'{"id"')
  .replaceAll("url",'"url"')
  +"]"
let getVals = JSON.parse(str).flat()
document.querySelector("#t2").value = JSON.stringify(getVals)
const getMap = 3;
getVals.splice((getMap - 1),1);
getVals.forEach((item,i) => item.id=i+1)
document.querySelector("#t3").value = JSON.stringify(getVals)
This is what I read<br/>
<textarea id="t1" rows=5 cols=50>
[id:1,x:288.43,y:260.15,url:#]-[id:2,x:396.43,y:310.15,url:#]-[id:3,x:503.43,y:299.15,url:#]-[id:4,x:642.43,y:191.15,url:#]
</textarea>
<hr>
This is what I generate <br/>
<textarea id="t2" rows=5 cols=50>
</textarea>
<hr>
After deleting and renumbering<br/>
<textarea id="t3" rows=5 cols=50>
</textarea>

Sign up to request clarification or add additional context in comments.

1 Comment

I will try it and let you know, but as I look at it, it should work for me! Thank you so much! And I will also try to generate JSON code instead of a JSON-like string.
0

What if you disregard the id completely from the object/item and populate when needed just using the index of that item in the array.

I will give you an example code here and in https://codesandbox.io/s/great-hopper-3eb4y

Sorry for using ES6, you can easily transform it to not use class, and import.

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <textarea id="txt-area" rows="10" cols="50"></textarea>
      <br /><br />
      <input id="add-input" placeholder="use this format: x,y,url" />
      <button id="add-button">Add</button>
      <br /><br />
      <input
        type="number"
        id="remove-input"
        placeholder="use numbers: 0,1,2,3"
      />
      <button id="remove-button">Remove</button>
    </div>

    <script src="src/index.js"></script>
  </body>
</html>

MyMemory.js

class MyMemory {
  constructor() {
    this.value = [];
  }

  setInitialState(str) {
    this.value = str.split("-").map((x, i) => {
      const groups = /\[id:(\d*),x:(\d*.\d*),y:(\d*.\d*),url:(.*)\]/.exec(x);
      return {
        x: groups[2],
        y: groups[3],
        url: groups[4]
      };
    });
  }

  add(inputArray) {
    this.value.push({
      x: inputArray[0] || "#",
      y: inputArray[1] || "#",
      url: inputArray[2] || "#"
    });
  }

  getText() {
    return this.value.map((v, i) => MyMemory.objToString(v, i)).join("-");
  }

  remove(id) {
    id = Number.parseInt(id);

    if (id >= 1 && id <= this.value.length) {
      this.value.splice(id - 1, 1);
    } else {
      console.error("Remove id is not valid. Use a number, please!");
    }
  }

  static objToString(obj, idx) {
    const { x, y, url } = obj;
    return `[id:${idx + 1}, x:${x}, y:${y}, url:${url}]`;
  }
}

export default MyMemory;

index.js

import $ from "jquery";
import MyMemory from "./MyMemory";
import "./styles.css";
// window.$ = $;

const memory = new MyMemory();

const initialState =
  "[id:1,x:288.43,y:260.15,url:#]-[id:2,x:396.43,y:310.15,url:#]-[id:3,x:503.43,y:299.15,url:#]-[id:4,x:642.43,y:191.15,url:#]";

const bindEvents = () => {
  const $txtArea = $("#txt-area"),
    $add = $("#add-button"),
    $remove = $("#remove-button"),
    $add_input = $("#add-input"),
    $remove_input = $("#remove-input");

  memory.setInitialState(initialState);
  $txtArea.val(memory.getText());

  $add.on("click", (e) => {
    const newVal = $add_input.val();
    const ar = newVal && newVal.split(",");
    memory.add(ar);
    $txtArea.val(memory.getText());
  });

  $remove.on("click", (e) => {
    const id = $remove_input.val();
    memory.remove(id);
    $txtArea.val(memory.getText());
  });
};

$(document).ready(bindEvents);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.