Refresh your textarea content using the replace method in jQuery

My goal is to extract and manipulate specific values within a user-entered code using jQuery. The code includes custom tags called setting, which I want to extract and display in input fields for easy editing. I have successfully retrieved and displayed the values in the inputs, but I am struggling to update the code with the modified values.

Here is the structure of the HTML code:

<div id='tab-1'>
  <textarea id='template-code' cols='67' rows='27'></textarea>
  <button id='submit-code'>Submit Code</button>
</div>

<div id='tab-2' class='unactive'>
  <form id='settings-form' method='POST'>
    <div id='result'></div>
    <button id='update-code'>Update Code</button>
  </form>
</div>

The CSS code used to hide elements:

.unactive {
    display: none
}

And here is the jQuery code snippet:

$('#template-code').change(function (){

  var $that = $(this),
      template_code = $that.val(),
      code = '',
      new_data = '',
      text = '',
      newCode = '';

  // Logic to extract settings and display in #result              
  $(document).on('click', '#submit-code', function (){

      $('#tab-1').addClass('unactive');
      $('#tab-2').removeClass('unactive');

      $(template_code).find('setting').each(function (i){

        var $this = $(this),
            setting_std = $this.text(),
            setting_id = $this.attr('id');

        code += '<input id="'+setting_id+'" name="'+setting_id+'" type="text" value="'+setting_std+'"><br>';

      });

      if(code !== ''){
        $('#result').html(code);
      }

  });

  // Update old data with the new one
  $(document).on('click', '#update-code', function (){

    new_data = $( "#settings-form" ).serializeArray();
    $.each( new_data, function( i, new_field ) {

        var start_key = "id='"+new_field.name+"'>",
            end_key = '</setting>',
            start  = template_code.indexOf(start_key), 
            end = template_code.indexOf(end_key);

        text = template_code.substring(start + start_key.length, end);
        
        template_code.replace(text, new_field.value);
    });

    $('#template-code').val(template_code);
    $('#tab-1').removeClass('unactive');

    return false;

  });

});

An example of the theme code that will be inserted into the textarea:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
  <head>

    <b:include data='blog' name='all-head-content'/>

    <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'/>
    <link href='http://fonts.googleapis.com/css?family=Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'/>
    <link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' rel='stylesheet'/>

    <title><data:blog.pageTitle/></title>

    <div id='option-panel' style='display:none!important'>

      <setting id='post_thumbnail'>http://lorempixel.com/640/300/</setting>
      <setting id='search_icon'>on</setting>

    </div>
</head>
<body>

</body>
</html>

If you want to test the functionality, visit this JsFiddle link, copy the code, paste it into the textarea, click "Submit Code", and you will see the input fields populated based on the values inside the setting tags. Feel free to update the inputs and click "Update Code" to attempt changing the setting tag values.

Answer №1

Give this a try and see if it meets your needs:

HTML

<div id='tab-1'>
  <textarea id='template' cols='67' rows='27'></textarea>
  <button id='submit'>Submit Code</button>
</div>

<div id='tab-2'>
  <form id='settings-form' method='POST'>
    <div id='result'></div>
    <button id='update'>Update Code</button>
  </form>
</div>

JavaScript:

function wrapContent(data) {
  var output = '';
  var i, numItems;

  output += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";
  output += "<!DOCTYPE html>\r\n";
  output += "<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>\r\n";
  output += "  <head>\r\n";
  output += "    <b:include data='blog' name='all-head-content'/>\r\n";
  output += "    <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'/>\r\n";
  output += "    <link href='http://fonts.googleapis.com/css?family=Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'/>\r\n";
  output += "    <link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' rel='stylesheet'/>\r\n";
  output += "    <title><data:blog.pageTitle/></title>\r\n";
  output += "  </head>\r\n";
  output += "  <body>\r\n";
  output += "    <div id='option-panel' style='display:none!important'>\r\n";

  for (i = 0, numItems = data.length; i < numItems; i++)
    output += "      " + data[i].toString() + "\r\n";

  output += "    </div>\r\n";
  output += "  </body>\r\n";
  output += "</html>\r\n";

  return output;
}

$("#submit").on('click', function() {
  var virtualNode = document.createElement("div");
  var tempOutput = '';

  virtualNode.innerHTML = $("#template").val();

  $(virtualNode).find('setting').each(function(i) {
    var $this = $(this),
            settingValue = $this.text(),
            settingId = $this.attr('id');

    tempOutput += '<input id="' + settingId + '" name="' + settingId + '" type="text" value="' + settingValue + '"><br>';
  });

  if (tempOutput !== '')
    $('#result').html(tempOutput);
});

$("#update").on('click', function(event) {
  var tempData = [];

  event.preventDefault();

  $("#result").find("input").each(function() {
    tempData.push("<setting id=\"" + this.id.toString() + "\">" + this.value.toString() + "</setting>");
  });

  $("#template").val(wrapContent(tempData));
});

Does this solution align with your requirements? It seems like using jQuery may have made the process more complex than necessary. I utilized a virtual node to efficiently extract only the setting tags from the textarea on submission.

I excluded styles for quicker testing, and it's important to implement proper validation for user input.

Edit: I updated the answer to include a basic wrapping function to illustrate the concept. I recommend creating a proper template instead of using this function directly, which would involve additional work beyond the scope of this question.

Latest JSFiddle after modifications: http://jsfiddle.net/zo3hh2ye/6/

Answer №2

Check out this alternative version of the code. I stored the new values in an array and then used them to replace the existing values in the textarea text. Give it a try to see if it resolves your issue.

Here's the script:

 <script type="text/javascript">
    $('#template-code').change(function () {

        var $that = $(this),
            template_code = $that.val(),
            code = '',
            new_data = '',
            text = '',
            newCode = '';

        // Extract settings from the theme and add them to #result              
        $('#submit-code').click(function () {

            $('#tab-1').addClass('unactive');
            $('#tab-2').removeClass('unactive');

            $(template_code).find('setting').each(function (i) {

                var $this = $(this),
                    setting_std = $this.text(),
                    setting_id = $this.attr('id');

                code += '<input id="' + setting_id + '" name="' + setting_id + '" type="text" value="' + setting_std + '"><br>';

            });

            if (code !== '') {
                $('#result').html(code);
            }

        });

        // Update old data with the new one
        $('#update-code').click(function () {

            new_data = $("#settings-form").serializeArray();

            $(template_code).find('setting').each(function (i) {
                template_code = template_code.replace("<setting", "").replace("id='" + $(this).attr("id") + "'>", "").replace($(this).html(), "{" + i + "}").replace("</setting>", "");
            });

            $.each(new_data, function (i, new_field) {
                template_code = template_code.replace("{" + i + "}", "<setting id='" + new_field.name + "'>" + new_field.value + "</setting>");
            });

            $('#template-code').val(template_code);
            $('#tab-1').removeClass('unactive');

            return false;

        });

    });
</script>

And here's the HTML Template:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
  <head>

    <b:include data='blog' name='all-head-content'/>

    <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'/>
    <link href='http://fonts.googleapis.com/css?family=Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'/>
    <link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' rel='stylesheet'/>

    <title><data:blog.pageTitle/></title>

    <div id='option-panel' style='display:none!important'>

      <setting id='post_thumbnail'>text1</setting>
      <setting id='search_icon'>text2</setting>

    </div>
</head>
<body>

</body>
</html>

While I was able to replace most of the text in the template you provided, I couldn't replace the text 'on', which could be due to it being a reserved keyword. However, everything else seems to be working fine.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to bind a model to a directive in Angular.js?

I have been experimenting with different methods to create a two-way binding between my directive and repeater, but so far I haven't been successful. Although I have tried various strategies suggested online, the current setup does not pass item.myDat ...

What is the best way to compare the position-x of two components that are aligned on the same line?

Check out this code snippet: <input id="homebutton" type="image" style="display:inline" src="home.png" name="saveform" class="btTxt submit ml-3" onclick="location.href='home.html&apos ...

Differences between Bootstrap-5 CSS files and SCSS files

As I delve into the world of Bootstrap, I recently utilized npm to install Bootstrap and discovered that there are both CSS and SCSS files under node_modules. My understanding of SCSS is that it is a more advanced version of CSS, leading me to question t ...

Displaying an image in AngularJS using a byte array received in the response

Dealing with a service that adds properties to a file and returns it as a byte array in the response. I'm struggling to display it properly since it's in byte form. Attempted converting it to base64 but still showing raw bytes. PNG IHDR&L ...

Maximizing the potential of a single .js file for multiple .html pages with AngularJS

I have a JavaScript file containing a function that I want to be accessible by multiple HTML pages without duplicating it in another file. Currently, the JS file starts with the following code snippet: (function(){ var app = angular.module('Proj ...

What is the best way to add clickable links to 3D objects and meshes with ThREE?

My goal is to create a simple box that can act as a link when clicked. This seemingly straightforward task has proven difficult for me, so I would greatly appreciate any assistance. Despite my efforts to troubleshoot and research online, I have not been ...

Exploring elementary functionalities within PHP

I'm just starting out, so please excuse any confusion in how I phrase this. Currently, I'm diving into my online computer science course which is focused on functions. The task at hand is to create sentences that output three different variables ...

New Relic identifies mysterious delays caused by MongoDB's findOne method

After setting up newrelic to pinpoint the bottlenecks in my app, I discovered a major issue that has left me stumped. The source of most delays seems to be mongoDB user.findOne, but the biggest challenge is locating where in the code this delay is occurri ...

Alignment of Submenus in a CSS Vertical Menu

I'm currently facing an issue with my vertical menu and submenu alignment. Despite everything working correctly, the submenu does not align horizontally as expected, instead shifting up against the header div above it. Any assistance to resolve this w ...

JavaScript validation is failing, yet the form is still getting submitted

I'm facing an issue with my JS validation. It seems to be working fine, checking for a valid number that isn't zero, but the form is still submitting. I've searched for a solution to this problem, but none seem to work for me. Any suggestion ...

Using Rails to reference an image in CSS

My application on Heroku, built with Rails, features a striking image as the background on the landing page. Since Heroku's file system is read-only, I made the decision to store these images (selected randomly) on AWS S3. In my .css(.scss) code, the ...

Seeking a solution for inserting input values into a JSON file within a node.js environment

As I was developing my new project, a to-do list web application, Below is the code snippet from 'todo.html' : <html> <head> <title>My TODO List</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery ...

Discovering the total of varying inputs in ReactJS

//this is the API response: { "message": "success", "code": 100, "data": { "inCourseCategories": [ { "_id": "62b842f09184bf2330e6f506", "course": "601a67e6db65fb15946e6b6f ...

When rendering, HTML characters are not translated

My JavaScript code generates the following HTML structure: <div contenteditable="false" tabindex="0" class="ProseMirror"> <p> didn't project a significant increase</p> </div> When rendered in the browser, it shows the cha ...

Insert a THREE.Points element into the scene: Error in THREE.Object3D.add: The object being added is not a valid instance of THREE.Object3D (

Trying to incorporate a system of particles, a THREE.Points element into the scene has resulted in the following error: "THREE.Object3D.add: object not an instance of THREE.Object3D. undefined" The code used for this is as follows: var backCount = 1800; ...

The Angular ui-calendar introduces an innovative approach to event addition, providing users with

I need help with adding events to the angular ui calendar. Currently, I am using $scope.events.push() method to add events, but they get reset when changing the month. If anyone has experience with angular ui-calendar and event addition, please provide ...

Receiving an inaccurate value from the input with type='number' attribute

There is an input field where users can enter a string, and I need to capture the value entered into it. $("#test").on("change", function(){ console.log($(this).val()); }) <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery ...

Tips for splitting a container of specific height into sections measuring 80% and 20%

I am working on a container with a fixed position that I want to split into two halves: 80% and 20% at the bottom. This is what I want it to look like: Click here to see the image. Note: The layout should adjust itself when the window is resized. You c ...

What method can I use to adjust the font style when it overlays an image?

Sorry if this is a bit unclear, but I'm trying to figure out how to change only a section of my font when it overlaps with an image while scrolling. If you visit this example website, you'll see what I'm referring to: For a visual represen ...

Is there a way to customize the slicing of *ngFor in a component according to the components it is being injected into?

This code snippet represents a component that needs to be included in other components: <div class="row"> <div class="col-12 [...]" *ngFor="let course of courses"> <div class="card"> ...