contenteditable -- Utilizing AngularJS to create a block element for the title only

When I click on an input field that is editable, I want the background color to change to white within the box. Can someone please assist me with this?

Below is my code:

HTML

<div id="section{{section.index}}">
    <h2 class="title" contenteditable="true" ng-model="section.title"
        onclick="document.execCommand('selectAll',false,null)"
        ng-keydown="disable_enter($event)"
        ng-change="check_section_title($index)"
        maxlength="40">
    </h2>
</div>

The current output looks like this

https://i.sstatic.net/0ssry.png

**But I am aiming for something like this ** https://i.sstatic.net/tB1BP.png

Answer №1

Creating a Unique Directive for Contenteditable Elements

If you want to enable a contenteditable element to work with the ng-model directive and the ngModelController:

 <div contenteditable
      name="myWidget" ng-model="userContent"
      strip-br="true"
      required>Change me!
 </div>

You can create a custom directive like this:

  app.directive('contenteditable', ['$sce', function($sce) {
    return {
      restrict: 'A', // only activate on element attribute
      require: '?ngModel', // get a hold of NgModelController
      link: function(scope, element, attrs, ngModel) {
        if (!ngModel) return; // do nothing if no ng-model

        // Define how UI should be updated
        ngModel.$render = function() {
          element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
        };

        // Listen for change events to enable binding
        element.on('blur keyup change', function() {
          scope.$evalAsync(read);
        });
        read(); // initialize

        // Write data to the model
        function read() {
          var html = element.html();
          // Remove any leftover <br> when clearing content editable
          // Strip out <br> if "strip-br" attribute is present
          if (attrs.stripBr && html === '<br>') {
            html = '';
          }
          ngModel.$setViewValue(html);
        }
      }
    };
  }]);

Check Out the DEMO

angular.module('app', ['ngSanitize'])
.directive('contenteditable', ['$sce', function($sce) {
    return {
      restrict: 'A', // only activate on element attribute
      require: '?ngModel', // get a hold of NgModelController
      link: function(scope, element, attrs, ngModel) {
        if (!ngModel) return; // do nothing if no ng-model

        // Define how UI should be updated
        ngModel.$render = function() {
          element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
        };

        // Listen for change events to enable binding
        element.on('blur keyup change', function() {
          scope.$evalAsync(read);
        });
        read(); // initialize

        // Write data to the model
        function read() {
          var html = element.html();
          // Remove any leftover <br> when clearing content editable
          // Strip out <br> if "strip-br" attribute is present
          if (attrs.stripBr && html === '<br>') {
            html = '';
          }
          ngModel.$setViewValue(html);
        }
      }
    };
}])
  <script src="//unpkg.com/angular/angular.js"></script>
  <script src="//unpkg.com/angular-sanitize/angular-sanitize.js"></script>
<body ng-app="app">
  <form name="myForm">
 <p>Click on below div to edit</p>
 <div contenteditable
      name="myWidget" ng-model="userContent"
      strip-br="true"
      required>Change me!</div>
  <span ng-show="myForm.myWidget.$error.required">Required!</span>
 <hr>
 <textarea ng-model="userContent" aria-label="Dynamic textarea"></textarea>
</form>
</body>

Want to learn more? Take a look at AngularJS ngModelController API Reference - Custom Control Example

Answer №3

It's recommended to use the maxlength attribute in your input control instead of div or h1 tags.

For Angular version 1, you can use the following:

<input type="text" ng-maxlength="40" />

For Angular version 2, you can use:

<input type="text" [maxlength]="40" />

JS Code :

document.getElementById("myInput").style.backgroundColor = "lightblue";
   function changeColor() { 
   var textBoxLength = document.getElementById('myInput').value.length;
  if(textBoxLength >= 5){
    document.getElementById("myInput").style.backgroundColor = "white";
  }    
  }
<!DOCTYPE html>
<html>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js">
  </script>
  <body ng-app="">
    <form name="myForm">
      <h1>Type in textbox</h1>
      <input name="myInput" id="myInput" ng-model="myInput" ng-maxlength="5" onkeypress="changeColor()">
      <h1 ng-if="!myForm.myInput.$valid">The value is too long</h1>
    </form>
  </body>
</html>

In the above code, the background color is initially set to lightblue and changes to white when characters exceed 5. However, in your case, it should be set to 40.

Answer №4

It is not recommended to use ng-model on an h2 tag in AngularJS. Instead, you can pair an input field with the h2 tag and toggle their visibility. You can limit the input character count to 40 using the maxlength attribute and set up validations with ng-maxlength.

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.val={};
  $scope.val.type="Hello";
  $scope.contenteditable=false; 
  $scope.check_section_title = function() {
         $scope.contenteditable=!$scope.contenteditable;  
        };
});
<!DOCTYPE html>
<html ng-app="plunker">

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b6d7d8d1c3dad7c498dcc5f687988398ce">[email protected]</a>" data-semver="1.5.11"></script>
</head>

<body ng-controller="MainCtrl">
    <form name="myForm" novalidate>
        <div style="padding: 10px">
        <div id="section{{section.index}}">
    <h2 class="title" ng-click="check_section_title()"  ng-if="!contenteditable">{{val.type}}</h2>
</div>
            <input name="Hazmat" ng-model="val.type" maxlength="40" ng-maxlength="40" required ng-if="contenteditable" ng-blur="check_section_title()">
        </div>
    </form>
</body>

</html>

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

Deciphering the hidden power of anonymous functions within Express.js

Recently, I started learning about express and am grappling with understanding callbacks in RESTful actions. In the following PUT request code snippet, I am puzzled by the specific line that is highlighted below. Why is response.pageInfo.book being assigne ...

Learn the best way to send query parameters through the Next.js navigation router and take advantage of

Currently, I am implementing import { useHistory } from 'react-router-dom' const history = useHistory() ... history.push('/foo?bar=10') However, only the 'foo' part is being pushed into the url. What is the correct way to pas ...

Troubles encountered while processing STL file readers

Utilizing STLLoader.js, I am able to render components successfully, however, they all appear with one uniform color which does not resemble real-world components. The image above showcases my implementation in Three.js using STLLoader.js (Binary STL file ...

A guide on creating and accessing a variable within a Jinja for loop

Whenever a link is clicked by the user, I would like Jinja to establish a variable known as {{ contact_clicked }} that holds the same value as {{ contact }}. I thought about using <a href="/?{% contact_clicked = contact %}">.....</a> ...

Creating a JavaScript object and retrieving the values of numerous input fields with identical classes

I have encountered an issue that I need assistance with: <input title="1" type="text" class="email"> <input title="2" type="text" class="email"> <input title="3" type="text" class="email"> The HTML code above shows my attempt to extract ...

Oops! We encountered an issue in locating the Entry Module. The error message is indicating that it cannot find the specified source file

Currently enrolled in a Udemy course focusing on Wordpress development, I encountered an issue while attempting to integrate Google Maps into a custom post type. This required updating a JavaScript file, however, running 'gulp scripts' resulted i ...

Inserting a variable into a JSON string

Within my code, I have a basic variable containing strings that are converted into a JSON object. My goal is to create an input field where a person's name can be entered and added to the text. The current setup looks like this var text = '{"st ...

Guide to dynamically incorporating items from an array into the filter operation

How can I dynamically insert items from an array into the filter on the wizard.html page, so that when the templateUrl in the route is called, it can be rendered on the wizard.html page? Controller angular.module('tareasApp') .controller(&apo ...

After sending a test email, inline CSS in Gmail seems to be functioning to some extent

While working on applying inline CSS styling to HTML for email, I have encountered an issue where the styling partially works when sending a test email. Can anyone provide guidance on how to resolve this problem? Steps to reproduce: Step 1 - apply CSS st ...

Store and retrieve user input using JavaScript or JSON

Can someone please assist me in finding a solution to this problem? I have 3 input fields where users can type in their answers. There is also a "SAVE" button that allows users to download their input values into a file.txt. Additionally, there is a "choos ...

Tips for parsing information contained in a cdata tag using python

I have successfully used Beautiful Soup to extract CDATA from an HTML page, but now I need to parse the contents and save them in a CSV file. Here is the code I am using: from bs4 import BeautifulSoup from urllib.request import urlopen import re import c ...

Steps for executing a function when a directory is clicked

Currently, I am working on creating a file browser and facing some issues with calling a function when the user clicks on a directory. Initially, I tried using onClick inside an href in the class part (right before FUNCTION folderSize), intending to open ...

The selected data is not being displayed

My input field is not displaying anything. Below is the script function in my view: <script> var Features = []; function LoadFeatures(element) { if(Features.length === 0) { $.ajax({ url:'@Url.Action("GetFeatures"," ...

Avoid displaying null values in SELECT and GET operations when using node-postgres

Within my Express API functionality, I aim to offer the client flexibility in providing their contact details, namely phone number or website address, with the option of leaving them blank. The SELECT queries in use are as follows: -- Retrieve all users S ...

Can express-handlebars tags be utilized within an HTML script tag when on the client side?

For a while now, I've been facing a challenge. I'm in the process of building an application with express-handlebars and so far everything is going smoothly. The data that needs to be displayed on the webpages looks good thanks to the Helper func ...

Ways to invoke a controller function from a different controller in AngularJS

Could you please take a look at this code? I have a button that needs to call the function checkResults() from controller CtrlTwo. How can I achieve this? var myApp = angular.module('myApp', []); function CtrlOne($scope){ $scope.greet = & ...

What could be preventing my logo from properly resizing with html/css?

* { box-sizing: border-box; padding: 0; margin: 0; } ul { list-style-type: none; } .nav-links, .logo { text-decoration: none; color: #000; } .logo { max-width: 80%; width: 20%; height: 20%; } .navbar { padding: 20px; height: 50vh; ...

Steps to Create an HTML Text Box that cannot be clicked

Does anyone know of a way to prevent a text box from being clicked without disabling it or blocking mouse hover events? I can't disable the text box because that would interfere with my jQuery tool tips, and blocking mouse hover events is not an opti ...

Creating semantic advertisement content using HTML5 tags

With the abundance of Semantic tags in html5 for sectioning content and their importance for Search Engines, I now have a need to incorporate advertisements into my articles. My query revolves around identifying a tag that can clearly indicate when child ...

Having difficulties accessing the properties of a dynamically created JSON object with ng-repeat functionality

Within an ng-repeat loop, I have implemented a radio button that assigns the entire person object to a scope variable as shown below: <li ng-repeat="person in people"> <label>{{person.name}} <input type="radio" ng-model="$parent.s ...