Is it possible to arrange the contents within a textarea by both key and value using JavaScript?

In my html page, there is a textbox labeled "Type your text" and TextArea list. The goal is to enter text into the textbox and then click the Add button so that the content of the textbox gets added to the TextArea list below. The required format for input in the textbox should be as follows:

Name=Value

Users will use this textbox to quickly add Name Value pairs to the list right below it. For example, if we type Hello=World in the textbox and click add, the entry in the list below should show as:

Hello=World

If we then type ABC=PQR in the same textbox, the list should display the entries like this, continuing to add new Name Value pairs below the existing ones.

Hello=World
ABC=PQR

An error message will pop up if incorrect syntax without a matching pair such as an equal sign or if non-allowed characters are used. Only alphanumeric characters are permitted in both names and values. So far, all functionalities are working correctly without any issues.

There are two additional buttons available - Sort by name and Sort by value. Clicking on either button will rearrange the entries in the TextArea list based on their names or values, respectively. Is it possible to achieve this using JavaScript? Attempts were made with methods named sortByKey and sortByValue, but some issues have arisen during testing and further refinement is required.

A link to the code can be found here: jsfiddle. Pure HTML and JavaScript are being utilized, with no external libraries involved to maintain simplicity and facilitate learning progress. What mistakes may be present here?

The full source code is shown below:

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

<style type="text/css">
    #my-text-box {
        font-size: 18px;
        height: 1.5em;
        width: 585px;
    }
    textarea{
        width:585px;
        height:300px;
    }
    .form-section{
        overflow:hidden;
        width:700px;
    }
    .fleft{float:left}
    .fright{float:left; padding-left:15px;}
    .fright button{display:block; margin-bottom:10px;}
</style>

<script language="javascript" type="text/javascript">
    document.getElementById('add').onclick = addtext;
    function addtext() {
        var nameValue = document.getElementById('my-text-box').value;
        if (/^([a-zA-Z0-9]+=[a-zA-Z0-9]+)$/.test(nameValue))
            document.getElementById('output').textContent += nameValue + '\n';
        else
            alert('Incorrect Name Value pair format.');
    }

    document.getElementById('sortbykey').onclick = sortByKey;
    function sortByKey() {
        var textarea = document.getElementById("output");
        textarea.value = textarea.key.split("=").sort().join("\n");
    }

    document.getElementById('sortbyvalue').onclick = sortByValue;
    function sortByValue() {
        var textarea = document.getElementById("output");
        textarea.value = textarea.value.split("=").sort().join("\n");
    }
</script>

</head>

<body>
<h3>Test</h3>

<label for="pair">Name/Value Pair</label></br>
<div class="form-section">
    <div class="fleft">
        <input type='text' id='my-text-box' value="Name=Value" />
    </div>
    <div class="fright">
        <button type="button" id='add' onclick='addtext()'>Add</button>
    </div>
</div>

</br>
</br>
</br>

<label for="pairs">Name/Value Pair List</label></br>
<div class="form-section">
    <div class="fleft">
       <textarea id='output'></textarea>
    </div>
    <div class="fright">
        <button type="button" id='sortbykey' onclick='sortByKey()'>Sort by name</button>
        <button type="button" id='sortbyvalue' onclick='sortByValue()'>Sort by value</button>
    </div>
</div>

</body>
</html>

Answer №1

If you want to properly compare names or values from a textarea, you need to split the text by lines and then further split each line. Right now, you're only splitting once.

Here is what you should do:

  • Split your lines into an array by replacing ('=') with ('\n').
  • For each line, compare either the name or the value using the sort function. The sort method will iterate through your line array and allow you to specify which element to compare.

You can achieve this with the following code snippet:

function sortByKey() {
    var textarea = document.getElementById("output");
    textarea.value = textarea.value.split("\n").sort(function(a, b){
        if(a != "" && b != ""){//this because you have empty lines to handle
            return a.split('=')[0].localeCompare(b.split('=')[0])
        } else {
            return 0
        }
    }).join("\n");
}

https://jsfiddle.net/56hs2nmn/

To sort by value, simply use

a.split('=')[1].localeCompare(b.split('=')[1])
.

You'll notice that sorting by value and by key is quite similar, so it's recommended to optimize by having a single function for both. Also, consider using variables to clarify the steps instead of combining everything in one line. This approach should guide you in the right direction.

Answer №2

Yes, this approach seems feasible

https://jsfiddle.net/68cp72s6-unique/

(function() {
    "use strict";

    var elements = getElements(["user", "output", "add", "sortbykey", "sortbyvalue"], {});
    var regex = /[\w]+=[\w]+/;
    var dataModel = [];

    function addItem() {
        var userInput = elements.user.value;
        if (!regex.test(userInput)) return;
        var splitInput = userInput.split("=");
        var object = { key: splitInput[0], value: splitInput[1] };
        dataModel.push(object);
        displayData(dataModel);
    }

    function displayData(input) {
        var jsonData = JSON.stringify(input, null, 2);
        elements.output.value = jsonData;
    }

    function getElements(array, tempObject) {
        array.forEach(function(item) {
            tempObject[item] = document.getElementById(item);
        });
        return tempObject;
    }

    function sortingFunction(property) {
        return function() {
            var sortedData = dataModel.sort(function(a, b) {
                if (a[property] < b[property]) return -1;
                if (a[property] > b[property]) return 1;
            });
            displayData(sortedData);            
        }
    }

    elements.add.addEventListener("click", addItem);  
    elements.sortbykey.addEventListener("click", sortingFunction("key"));
    elements.sortbyvalue.addEventListener("click", sortingFunction("value"));

})();

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

You can click on the link within the Leaflet Popup to trigger JavaScript functionality

My leaflet map is functioning with GeoJSON polygons and popups attached to each one. These popups display information about the polygon. I want a link inside the popup that, when clicked, triggers a JavaScript function to retrieve and display smaller polyg ...

Creating Layouts with Bootstrap 3

I'm exploring the codepen below in an attempt to mimic the appearance of the image provided consistently across all screen sizes. However, there are two issues that I am encountering - firstly, the green numbers on the first line which represent the d ...

Limiting the style of an input element

How can I mask the input field within an <input type="text" /> tag to restrict the user to a specific format of [].[], with any number of characters allowed between the brackets? For example: "[Analysis].[Analysis]" or another instance: "[Analysi ...

JSON string inside a string-type in AWS model

My goal is to create a basic model that can accept a JSON string instead of defining all variables/elements upfront. The model will have an "options" element which will hold a JSON string. Below is the structure of my model. { "$schema": "http://json-sch ...

What is the best way to save a current HTML element for later use?

Here is a simple HTML code that I would like to save the entire div with the class test_area and then replicate it when needed. Currently, my goal is to duplicate this div and place the clone underneath the original element. How can I achieve this? Unfortu ...

React Native package identifies a primary module for handling HTTPS requests

For my latest project, I decided to experiment with incorporating HTTPS. I began by creating a new project using expo init test and then installed the HTTPS library with npm install https. Next, I made edits to App.js by adding the following line at the t ...

To achieve this, my goal is to have the reels start playing on a separate page when a user clicks on the designated image. I am currently working on a project that involves this

When a user clicks on the designated image, I want the reels to start playing on a separate page. In my main project, I have a reels project within it, with the reels project built in ReactJS and the main project in React TypeScript. For example, if a user ...

Ensure alignment of gradients between two divs, even if their widths vary

Among my collection of 10 inline divs, each one boasts a unique width and color gradient. While the 45-degree lines are uniform across all the divs, is there a way to ensure that these gradients match seamlessly? I've shared my CSS code snippet below ...

Can the following VBScript be converted into JavaScript?

I'm in the process of converting some VBScript to JavaScript, but I'm unsure if it's feasible due to its reliance on Microsoft apps and code. I am seeking assistance with either: a) converting the code to JavaScript successfully, or b) deter ...

Tips on pairing elements from a ngFor processed list with another list using ngIf

If we have a list such as the one shown below: elements = [ { id: 1, name: "one" }, { id: 3, name: "three" }, { id: 5, name: "five" }, { id: 6, name: "six" }, ]; lists = [ { id: 5, name: "five" }, { id: 9, ...

The TextField component in MUIv5 is showing some frustrating white space in the corners

I've integrated the MaterialUI_v5 library and included a TextField component within a Paper component. The background of the Paper component has been customized to appear in a shade of green. For the Textfield component, I have applied a styling tha ...

Expanding containers with flexbox to allow for flexibility in size

I need help with a page that contains 3 div elements, where 2 of them need to be resizable. These elements should be able to be moved left or right, and maximized or minimized. You can view the example on Stackblitz. The issue I'm facing is that som ...

Ways to prevent html header content from being incorporated in jquery post outcomes

I've implemented jquery's "$.post()" function to insert a new list entry into the mysql database using php. $(document).ready(function(){ $(".theSubmit").click(function(){ var content = $("textarea").val(); var listn = $("in ...

Transfer information through the react-native-ble-plx module

To initiate a project involving connected devices, I must establish a Bluetooth connection among the different devices. The objective is to develop an application using React Native and then transmit data from this application to my Raspberry Pi. The Rasp ...

Sleek transition-ready zoom functionality for THREE JS with clickable controls

Hey there, I've been attempting to animate a transition between scenes in THREE js for quite some time now. I have successfully cleared the scene and recreated the next one, but the transition between them is proving to be quite challenging. I have cr ...

To initiate dragula on button click, simply add the dragula attribute

Currently, I am working with Angular (4.0) and ng2-dragula. I have turned a div into a dragula container to enable item movement within it using the following code: <div id="dragcontainer" [dragula]='"first-bag"'> Now, I want to add a fea ...

The HTTP request arrives with no content within the body

I am in the process of developing a basic client-server application using Node and Express. The goal is for the program to receive a JSON input on the client-side, perform some operations, and then send data to the server-side. Currently, I am able to sen ...

Show initials of a name when a certain angular condition is met

I have a list of names stored in the variable Names : "Amit Singh, Kumar Anand" Names : "Ashish Singh" The names can be singular or multiple, separated by commas like "James, Anand, xyz,..." During a for loop iteration <d ...

written messages on physical chips

I am interested in creating a unique combination of chips and normal text input. On this site https://material.angular.io/components/chips/overview#chip-input, it demonstrates how to insert chips inside an input field. However, I am looking to merge them w ...

Creating duplicates of a parent mesh in THREE.js with its children and additional materials

I am inquiring about a cloning issue I am having with a mesh that has a parent and 4 children, each with different materials. When I clone the parent mesh using this code: let result = cloudObjects.sideCloudGeometry[texture].clone(); The cloned mesh look ...