Home > Enterprise >  Trying to search and replace in textarea based on multiple selects
Trying to search and replace in textarea based on multiple selects

Time:01-29

I'm giving users multiple select options, and want to change parts of a textarea based on the selections. I can get each instance to work, but only for the current select. When I change another select, the previous one goes back to the original value.

How can I replace a string on select change, and have it stay that way if another select is changed?

    <script type="text/javascript">
        var textcode = document.getElementById("code").innerHTML; 
        var bckcolor = document.querySelector('#bckcolor');
        var txtinner = document.querySelector('#txtinner');
        var submitbtn = document.querySelector('#submitbtn');
        bckcolor.addEventListener('change', e => {
            document.getElementById("code").innerHTML = textcode.replace("backcolor = \"#242323\"", "backcolor = \""   bckcolor.value   "\"");
        })
        txtinner.addEventListener('change', e => {
            document.getElementById("code").innerHTML = textcode.replace("textinner = \"#c6c6c6\"", "textinner = \""   txtinner.value   "\"");
        })
        submitbtn.addEventListener('change', e => {
            document.getElementById("code").innerHTML = textcode.replace("subbtn = \"linear-gradient(225deg, #ee69ff 0%, #955af9 100%)\"", "subbtn = \""   submitbtn.value   "\"");
        })
    </script>


    <select name="bckcolor" id="bckcolor">
      <option value="#242323">#242323 (default)</option>
      <option value="blue">blue</option>
      <option value="red">red</option>
      <option value="yellow">yellow</option>
    </select>

    <br/>
    
    <select name="txtinner" id="txtinner">
      <option value="#c6c6c6">#c6c6c6 (default)</option>
      <option value="black">black</option>
      <option value="white">white</option>
      <option value="blue">blue</option>
    </select>

    <br/>
    
    <select name="submitbtn" id="submitbtn">
      <option value="linear-gradient(225deg, #ee69ff 0%, #955af9 100%)">linear-gradient(225deg, #ee69ff 0%, #955af9 100%) (default)</option>
      <option value="black">black</option>
      <option value="white">white</option>
      <option value="blue">blue</option>
    </select>

<textarea id="code" style="width:100%;height:300px;padding:10px;margin-bottom:10px;" disabled>
<script type="text/javascript">
var backcolor = "#242323";
var textinner = "#c6c6c6";
var subbtn = "linear-gradient(225deg, #ee69ff 0%, #955af9 100%)";
</script>
</textarea>

CodePudding user response:

The fixes and some improvements with your code:

  • You're referencing and storing the value of innerHTML inside the textcode variable. After one select updates the value, the variable isn't updated and still contains the old text
  • You're always replacing the base value as your search term and not accounting for the changed text. Use regex to select the whole line
  • Don't use var, but let.
  • No need to use escape the double quotes. You can use backtick (``) around your string and include any variables within ${}.

Here's a codepen that resolves your issues (and improves upon the code a bit):

https://codepen.io/prvashisht/pen/MWBBaVv

<script>
var textcodeNode = document.getElementById("code");
var bckcolor = document.querySelector("#bckcolor");
var txtinner = document.querySelector("#txtinner");
var submitbtn = document.querySelector("#submitbtn");
bckcolor.addEventListener("change", (e) => {
  textcodeNode.innerHTML = textcodeNode.innerHTML.replace(
    /backcolor.*/g,
    `backcolor = "${bckcolor.value}"`
  );
});
txtinner.addEventListener("change", (e) => {
  textcodeNode.innerHTML = textcodeNode.innerHTML.replace(
    /textinner.*/g,
    `textinner = "${txtinner.value}"`
  );
});
submitbtn.addEventListener("change", (e) => {
  textcodeNode.innerHTML = textcodeNode.innerHTML.replace(
    /subbtn.*/g,
    `subbtn = "${submitbtn.value}"`
  );
});
</script>
<select name="bckcolor" id="bckcolor">
  <option value="#242323">#242323 (default)</option>
  <option value="blue">blue</option>
  <option value="red">red</option>
  <option value="yellow">yellow</option>
</select>

<br />

<select name="txtinner" id="txtinner">
  <option value="#c6c6c6">#c6c6c6 (default)</option>
  <option value="black">black</option>
  <option value="white">white</option>
  <option value="blue">blue</option>
</select>

<br />

<select name="submitbtn" id="submitbtn">
  <option value="linear-gradient(225deg, #ee69ff 0%, #955af9 100%)">linear-gradient(225deg, #ee69ff 0%, #955af9 100%) (default)</option>
  <option value="black">black</option>
  <option value="white">white</option>
  <option value="blue">blue</option>
</select>

<textarea id="code" style="width:100%;height:300px;padding:10px;margin-bottom:10px;" disabled>
  <script type="text/javascript">
    var backcolor = "#242323";
    var textinner = "#c6c6c6";
    var subbtn = "linear-gradient(225deg, #ee69ff 0%, #955af9 100%)";
  </script>
</textarea>

CodePudding user response:

Your code doesn't exactly do anything, probably you are omitted some parts of it. So can't tell what is going on. Maybe you gotta rephrase your question or add missing parts to your code.

Another thing is you don't consider when there is a change your replace literals are still based on the previous values.

That's being said, I am guessing: if you are "posting" this as a form, then that's a normal behavior because you are re-navigating to the page, so default values are back, either you gotta handle POST values and assign to selects or;

You can tackle this a bit differently by using JS's Template Strings;

    <script type="text/javascript">
        //This is a reference object, you'll keep your changes here.
        var values ={
            back:"#242323",
            textinner:"#c6c6c6",
            subbttn:"linear-gradient(225deg, #ee69ff 0%, #955af9 100%)"
        }


        function updateTextArea(change,value){

            //Update your reference object values.
            if(change){
                values[change] = value
            }

            //and create a string the way you wanted
            let newCode = `<script type="text/javascript">\n`
            newCode = `var backcolor = ${values.back};\n`;
            newCode = `var textinner = ${values.textinner};\n`
            newCode = `var subbtn = ${values.subbttn};\n`
            newCode = `<\/script>`

            //Then update your textarea element.
            document.getElementById("code").value = newCode
        }
    </script>


    <select name="bckcolor" id="bckcolor">
      <option value="#242323">#242323 (default)</option>
      <option value="blue">blue</option>
      <option value="red">red</option>
      <option value="yellow">yellow</option>
    </select>

    <br/>
    
    <select name="txtinner" id="txtinner">
      <option value="#c6c6c6">#c6c6c6 (default)</option>
      <option value="black">black</option>
      <option value="white">white</option>
      <option value="blue">blue</option>
    </select>

    <br/>
    
    <select name="submitbtn" id="submitbtn">
      <option value="linear-gradient(225deg, #ee69ff 0%, #955af9 100%)">linear-gradient(225deg, #ee69ff 0%, #955af9 100%) (default)</option>
      <option value="black">black</option>
      <option value="white">white</option>
      <option value="blue">blue</option>
    </select>

<textarea id="code" style="width:100%;height:300px;padding:10px;margin-bottom:10px;" disabled></textarea>
<script>
        //This block is after the element because otherwise wouldn't be accessible.
        var textcode = document.getElementById("code").innerHTML; 
        var bckcolor = document.querySelector('#bckcolor');
        var txtinner = document.querySelector('#txtinner');
        var submitbtn = document.querySelector('#submitbtn');

        //All these event listeners can use same function, therefore;
        bckcolor.addEventListener('change', e => {
            updateTextArea("back",bckcolor.value)
        })
        txtinner.addEventListener('change', e => {
            updateTextArea("textinner",txtinner.value)
        })
        submitbtn.addEventListener('change', e => {
            updateTextArea("subbttn",submitbtn.value)
        })

        //Initially we run once without parameters, to use it with defaults.
        updateTextArea()
</script>
  • Related