Switch back and forth between input and textarea, but only if the content exceeds a certain length

In my current project, I am working on a feature where I need to display a textarea whenever the user clicks in the input and the length of its content exceeds 20 characters. If not, the normal input should continue to be displayed.

However, I seem to be facing some unexpected behavior in my implementation.

The issue arises when the user clicks for the first time with short content and then follows it up with long content. In this scenario, both inputs end up becoming textarea, whereas only the input with long content should trigger this change.

I'm currently trying to figure out what is missing in my logic?

var longContentChecked = null;

scope.isLongContent = function(l){
    return l && longContentChecked
};

scope.adaptLongContent = function(e){
    var textarea = $(e.target).next();

    if (textarea.val().length > 20) {
        longContentChecked = true;
    }else{
        longContentChecked = false;
    }

    textarea.previous().focus();
    textarea.focus();
};

VIEW

        <td ng-if="gridLoadColumn($index)" ng-repeat="item in items track by $index">
            <input
                type="text"
                ng-model="item.value"
                ng-click="showLongContent = !showLongContent; adaptLongContent($event);"
                ng-show="!isLongContent(showLongContent);"
            />
            <textarea
                class="dgrid-cell-long-content"
                ng-blur="!showLongContent"
                ng-show="isLongContent(showLongContent);"
                ng-model="item.value"
            ></textarea>
        </td>

UPDATED:

After making some adjustments, I believe I am getting closer to resolving the issue.

var longContentChecked = null;
var longContentIndex = null;

scope.isLongContent = function(l, idx){
    var ret = (l && longContentChecked) && (longContentIndex == idx);
    return ret;
};

scope.adaptLongContent = function(e, idx){
    var textarea = $(e.target).next();

    if (textarea.val().length > 20) {
        longContentChecked = true;
        longContentIndex = idx;
        //textarea.focus();
    }else{
        longContentChecked = false;
        longContentIndex = null;
    }

};

VIEW

    <tr ng-if="gridLoadRow($index)" ng-repeat="items in dataGrid track by $index">
        <td><strong>{{$index+1}}</strong></td>
        <td ng-if="gridLoadColumn($index)" ng-repeat="item in items track by $index">
            <input
                type="text"
                ng-model="item.value"
                ng-click="showLongContent = !showLongContent; adaptLongContent($event, $index);"
                ng-show="!isLongContent(showLongContent, $index);"
            />
            <textarea
                class="dgrid-cell-long-content"
                ng-blur="!showLongContent; test();"
                ng-show="isLongContent(showLongContent, $index);"
                ng-model="item.value"
            ></textarea>
        </td>
    </tr>

I am now attempting to handle the $index variable, although it's still not functioning as expected. As you can see, I added another TR element with repetition, as I am trying to work with the index values.

One challenge I'm facing is that the $index value repeats each time with the same value, for example: TD(0), TD(1), second line TD(0), TD(1). This lack of unique identification is causing issues. Even using $parent.$index doesn't solve the problem. How can I make the index an unique identifier in this scenario?

Answer №1

Consider trying out something along these lines?

<td ng-if="gridLoadColumn($index)" ng-repeat="item in items track by $index">
    <input
        type="text"
        ng-model="item.value"
        ng-click="showLongContent = !showLongContent; adaptLongContent($event);"
        ng-if="item.value.length <= 20"
    />
    <textarea
        class="dgrid-cell-long-content"
        ng-blur="!showLongContent"
        ng-if="item.value.length > 20"
        ng-model="item.value"
    ></textarea>
</td>

Answer №2

Everything is running smoothly with the final outcome.

var contentCheck = null;
var contentIndex = null;

scope.checkContentLength = function(idx){
    return contentCheck && (contentIndex == idx);
};

scope.adjustContent = function(e, idx){
    var textarea = $(e.target).next();

    if (textarea.val().length > 20) {
        contentCheck = true;
        contentIndex = idx;
    }else{
        contentCheck = false;
        contentIndex = null;
    }

};

VIEW

<tbody>
<tr ng-if="displayRow($index)" ng-repeat="itemList in dataGrid track by $index" ng-init="counter = $index">
<td><strong>{{$index+1}}</strong></td>
<td ng-if="showColoumn($index)" ng-repeat="item in itemList track by $index" ng-init="iteration = (counter * itemList.length + $index)">
    <input
        type="text"
        ng-model="item.value"
        ng-click="adjustContent($event, iteration);"
        ng-show="!checkContentLength(iteration);"
    />
    <textarea
        class="dgrid-cell-long-content"
        ng-show="checkContentLength(iteration);"
        ng-model="item.value"
    ></textarea>
</td>
</tr>
</tbody>

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

Why isn't setInterval set to a duration of one thousand milliseconds?

While trying to use some code from w3schools, I noticed that the setInterval in the example is set to 5 instead of 5000. Shouldn't it be in milliseconds? If not, how can I speed up this animation? When I try reducing it to decimals like 0.01, the anim ...

Set the rowspan to 2 when the v-for index does not equal 2

This is the table I am working with: <table class="table table-condensed table-sm table-striped table-bordered" id="list"> <thead> <tr> <th v-for="(column, index) in columns" :key=& ...

Having trouble displaying dynamically added images in my jsx-react component. The images are not showing up as expected

import React from "react"; import ReactDOM from "react-dom"; var bImg = prompt("Enter the URL of the image you want to set as the background:"); const bStyle = { backgroundImage: "url(bImg)"; // The link is stored ...

Potential unhandled promise error in react-native

When I use the code below, it produces a "Possible unhandled promise rejection" error: constructor(props){ super(props) DatabaseHandler.getInstance().getItems(function (items) { console.log(items)//successfully print data ...

A handy guide on setting up webpack 5.x to automatically clear the dist folder before starting the build process

Prior to the next build, I am considering removing the previous build. If we do not delete the old build, any changes that did not result in an output file may go unnoticed for a while. Currently, I am attempting to achieve this using the following command ...

Retrieving ng-repeat object in Angular

How can I retrieve the current object from an ng-repeat on ng-click without using $index? The $index method is giving me the wrong index due to my use of orderBy. Ideally, I would like to be able to click on the object (thumbnail) and have $scope.activePer ...

Transform javascript classes into flash

Is there a way to transform a JavaScript class into Flash and implement it the same way as the original one? For example: var MyClass = function() { var exports = {}; var message = exports.message = function showMessage(msg) alert(msg); ...

Looking for some essential reading to kickstart your learning journey in webOS/Mojo SDK development?

As I embark on my journey into webOS and the Mojo SDK, I am thoroughly enjoying the experience. However, I keep finding myself having to veer off course to learn about various topics like JSON, JavaScript, and more. In hindsight, I realize that it might ha ...

Swap the value of a button's text using a dropdown list when clicked in VueJS with TypeScript

I have a button with a click event that opens a dropdown list. I would like for the button text to be updated and for the selected option to be removed from the dropdown list when the user makes a selection. Currently, using {{interestSortingOptions.label} ...

The Material UI React radio buttons have the ability to modify the value of previous buttons

I'm facing an issue with my Material UI React Stepper Component that contains a group of radio buttons. The problem is that changing the radio button in one step affects the selected value in previous and future steps. I've experimented with diff ...

Exploring the Significance of jQuery in a Real-

I manage a large website with an extensive amount of jQuery code spread across multiple pages. The total codebase is around 1000 lines, well-optimized and excluding plugins. Despite jQuery being efficient in ignoring listeners for non-existent page elemen ...

Setting ng-click on a custom element directive in Angular 1.x: A guide

Within this code, I have assigned ng-click to a custom element directive with the expectation that clicking the rendered text would trigger an alert saying "Worked from directive!" However, the functionality does not seem to be working as intended. Althou ...

Loop through and store data in Node.JS within an array

Initially, I attempted to use a simple for loop to iterate through the data. However, this approach didn't work due to the nature of request.save being a function. After some experimentation, I decided to utilize forEach instead. Everything seemed to ...

Loop through arrays using Object.keys

I currently have two different iterations in my code: For objects (snippet 1): for (let key in object) { if (object.hasOwnProperty(key)) { // perform actions with key and object[key] } } For arrays (snippet 2): for (let i = 0, length = ...

Streaming the request body in NodeJS using ExpressJS without buffering

Looking for a solution to process requests with no specified content-type as binary files. const app = express(); app.use(bodyParser.raw({type: (req) => !req.headers['content-type'], limit: '500mb' })); Some of these files can be ...

Use the CSS class

To create tables with 3 rows and 2 columns using divs, I have utilized the ng-repeat directive. Within this setup, there are two CSS classes - red and green, that need to be applied in the following manner: - Red class for the 1st column of the 1st row - ...

Error 500: An invalid data type was encountered in an express.js node.js environment

Currently, I am in the process of developing an Authentication page using a combination of node.js, express.js, and mysql2. The user ID and password entered on the webpage are then passed through app.post('/login',...). However, upon submitting t ...

Meteor Routing Issue: The path "/"" you are trying to access does not exist in the routing system

After upgrading Meteor to version 1.3.2.4, I encountered an issue where the error message "Error : There is no route for the path: /" appeared. I made sure to update all packages to their latest versions as well. I tested the application in both "meteor" ...

Monitoring the initiation and completion of web requests within the Ionic framework

Currently utilizing the ionic framework in conjunction with Angular JS. In need of assistance on how to monitor the initiation of a web request. To handle the completion of a request, I have created a directive with an onLoad attribute. Here is the exam ...

What is the best way to retrieve a single result from a JavaScript for loop?

I've been working on a small JavaScript Zombie game using the p5 library. The goal is to keep track of hits when clicking on a Zombie and misses when failing to hit one. However, I'm facing an issue where 10 results are displayed per click when t ...