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

**But I am aiming for something like this **

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

Incorporate a popup triggered by a specific class (highly probable)

I've been attempting to utilize Tampermonkey to incorporate a popup feature on pages within the Canvas Learning Management System (LMS). Specifically, I'm focusing on a forum where there is a "Reply" option following each post. This is where I wa ...

Utilize Puppeteer for Web Scraping to Extract Products with an Array of Images

I am currently developing my portfolio by working on a variety of small projects, with my current focus on web scraping. Using Puppeteer, I have successfully scraped basic test websites. However, my goal now is to tackle more advanced challenges, such as ...

Improper headings can prevent Chrome from continuously playing HTML5 audio

Recently, I encountered a peculiar and unlikely issue. I created a custom python server using SimpleHTTPServer, where I had to set my own headers. This server was used to serve .wav files, but I faced an unusual problem. While the files would play in an ...

Responsive CSS design that adjusts to fit the content

Struggling to make the wrapper expand with its content... This is the structure: * { padding: 0; margin: 0; } body { background-color: #ccc; background-repeat:repeat; font: Tahoma, Geneva, sans-serif; color: #FFF; } .wrapper { width: 95%; margin: 0 au ...

How to Access a div from another website using jQuery

I have a question. How can I call a div from another website using JavaScript? Here is the page: Now, I want to call the <div id="testa"> in another page. The other page is called Otherpage.html: jQuery(function($){ $(&ap ...

Invoke a Python function from JavaScript

As I ask this question, I acknowledge that it may have been asked many times before. If I missed the answers due to my ignorance, I apologize. I have a hosting plan that restricts me from installing Django, which provided a convenient way to set up a REST ...

Having trouble adding your own styling to bootstrap-4 using a custom CSS file?

Here is the code I used to connect my two stylesheets, with the custom css file being linked second as per what I believe is the correct way to do it. <!doctype html> <html> <head> <link rel="stylesheet" type="text/css" href=" ...

React and Express failing to display content

After relocating my React frontend folder to my collaborator's Express backend folder, here is our updated file structure. https://i.stack.imgur.com/i77XJ.png This code snippet represents app.js which is responsible for rendering the website. const ...

Is it possible to eliminate the port number in Angular 7?

Currently, I am utilizing Angular in conjunction with an ASP.Net Web application. One interesting observation I've made is that when I use ng build, the app builds and runs on a URL without any port number. However, if I run the app using ng serve, it ...

Unable to transfer data successfully from popup to extension.js

I am currently developing a browser extension using Crossrider and I'm facing an issue with sending data from the popup to extension.js Here is my code for the popup: <!DOCTYPE html> <html> <head> <!-- This meta tag is relevant ...

Change the color of the plotly button when it is clicked

I recently implemented a custom button on my plotly modeBar and I would like it to retain a distinct color when clicked. This would help visually indicate its "active" state, allowing users to easily discern whether it is enabled or disabled based on its ...

Unable to conceal a div element on mobile devices

Creating a unique bootstrap theme for Wordpress and encountering an issue with hiding the "sptxt" text on mobile screens. <div class="row"> <div class="col-lg-5 col-sm-12"><div id="gr"></div></div> <div class="col- ...

An error was encountered: The object 'object object' does not have the 'on' method available

I want to experiment with this website: However, I am encountering an error without any events triggering. I am confused why the method "on" is not being found even on page load. <head> <link href="css/scrollable-horizontal.css" rel="styleshe ...

Guide to configuring Winston logging with Sequelize correctly

Currently, I am setting up winston with Sequelize and have the code snippet below: const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: path. ...

Oops, it seems like the project is missing a `pages` directory. Please kindly create one in the project root. Thank you!

Initially, my project setup looked like this: public .next src pages components assets next.config.js It was functioning properly, but I made a structural change to the following: public src client next.config.js jsconfig.json pa ...

Is it possible to implement smooth scrolling in HTML without using anchor animation?

Is it feasible to implement a more seamless scrolling experience for a website? I'm referring to the smooth scrolling effect seen in MS Word 2013, but I haven't come across any other instances of this. I've heard that AJAX can make such th ...

Type inference in TypeScript with transitivity

Consider this code snippet for illustration: function foo(t: "number"): number function foo(t: "string"): string function foo(t: "boolean"): boolean function foo(t: "number" | "string ...

Extracting information from within Ajax's Jsonp

How can I retrieve data from the Ajax function(result)? Why isn't this app working? Please assist me. function star(a) { var res; $.ajax({ url: 'https://api-metrica.yandex.com/analytics/v3/data/ga?end-date=today&ids=ga%3A35 ...

Are the events objects failing to render or is the scope not being broadcasted properly

I'm having trouble displaying my events using the ionic-calendar plugin by calling the $scope.loadEvents method. Unfortunately, the events are not showing up on the calendar. Here is the link to the plugin I am using: https://github.com/twinssbc/Ioni ...

Streamline event listeners with a pair of attributes

I am working with a function that requires one parameter: function magical(element){ ... } In my project, I have multiple click handlers attached to different elements and classes that are invoking this function: $('#div1').click(function(){ ...