0

Is it possible to style the value in the attribute ngModel of an input tag?

Example:

<input class="input" type="text" [(ngModel)] = "myService.text">

Let's say the value of text is '28 packages', can I put 28 in bold?

Observablerxjs
  • 692
  • 6
  • 22
  • 3
    Styling only a part of the input's content does not seem doable in pure HTML/CSS. – Arnaud Denoyelle Aug 02 '18 at 15:10
  • is it doable in javascript? – Observablerxjs Aug 02 '18 at 15:12
  • Maybe you could do something with a `
    ` put on top of the input (which is hidden by the `
    `). When the user clicks on the div, you actually focus the hidden input. When the user types text, you capture it and use it to fill the div. By doing that, you will be able to place some `` in the div around `28` and then style it from CSS.
    – Arnaud Denoyelle Aug 02 '18 at 15:20
  • Does the text packages always be there? – Aslam Aug 02 '18 at 15:31
  • No the text packages will not always be there, it may changes, depends on the type. – Observablerxjs Aug 02 '18 at 15:35
  • may be you can use conteneditable attribute to do like text box https://stackoverflow.com/questions/51206076/contenteditable-div-is-not-working-properly-with-angular-two-way-binding-in-fire/51400089#51400089 – Chellappan வ Aug 02 '18 at 15:37
  • check this also may be this will help you https://stackblitz.com/edit/input-event-wh85s6 – Chellappan வ Aug 02 '18 at 15:38
  • It would be much easier if the `input` was used only to set the quantity. Another `input`, or a `select` element, could be used for the type of items. – ConnorsFan Aug 02 '18 at 15:42

3 Answers3

0

So if i understand correctly you want to have it bold whenever the value is 28 ?

yes its possible you can use a ng-class with a ternary expression like this

.bold{
font-weight:600;
}
<input type="text" ng-class="myService.text == '28 ? 'bold' : '''" class="input" ng-model="myService.text" />
Martin Larocque
  • 190
  • 2
  • 10
  • No I don't want it to be bold whenever the value is 28, I want the value to be in bold and the text following the value to be normal.exemple: **15** items – Observablerxjs Aug 02 '18 at 15:37
  • @Observablerxjs I don' think assigning different `font-weight` to the same HTML input is possible. If it is you'll need some clever tricks – DevEng Aug 02 '18 at 15:42
0

This is not angular-related rather a CSS related question.

You cannot style only a part of an input in HTML/CSS so you won't be able to do it in angular.

Instead, you can use an input that is hidden behind a div. The idea is that when the user clicks the div, you actually focus the input. When the user types text, you capture the content of the input and fill the div with it, eventually adding <span class"highlight"> around the number of packages.

I prepared you a stackblitz in pure CSS/JS. You can adapt it in angular if you want.

Relevant pieces of code :

HTML :

<span id="hiddenSpan">This is the hidden div. Click it and start typing</span>

<div>
  <label for="in">The real input</label>
  <input id="in" type="text">
</div>

JS :

const input = document.getElementById('in')
const hiddenSpan = document.getElementById('hiddenSpan')

function onInputChanged() {
  let text = input.value

  const regex = new RegExp('(\\d+) packages')
  let result = regex.exec(text)

  if(result) {
    hiddenSpan.innerHTML = '<span class="highlight">'+result[1]+'</span> packages'
  } else {
    hiddenSpan.innerHTML = text
  }
}

// Capture keystrokes.
input.addEventListener('keyup', onInputChanged)

// Focus the input when the user clicks the pink div.
hiddenSpan.addEventListener('click', function() {
  input.focus()
})

CSS :

#hiddenSpan {
  background-color: pink;
}

.highlight {
  font-weight: bold;
  background-color: greenyellow;
}

Note : the downside is that the blinking caret is not visible anymore. You can take a look at this resource if you want to simulate one.

Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
0

It is not possible to style certain parts of a text <input> field in bold. However, you can use a contenteditable div instead of a text <input> field. Inside the contenteditable div you can have other HTML tags like <strong> to style certain parts of the text however you like.

I created an Angular directive called contenteditableModel (check out the StackBlitz demo here) and you can use it to perform 2-way binding on a contenteditable element like this:

<div class="input" contenteditable [(contenteditableModel)]="myService.text"></div>

The directive uses regular expressions to automatically check for numbers in the inputted text, and surrounds them in a <strong> tag to make them bold. For example, if you input "28 packages", the innerHTML of the div will be formatted like this (to make "28" bolded):

<strong>28</strong> packages

This is the code used in the directive to perform the formatting:

var inputElement = this.elementRef.nativeElement;
inputElement.innerHTML = inputElement.textContent.replace(/(\d+)/g, "<strong>$1</strong>");
this.change.emit(inputElement.textContent);

You can change the <strong> tag to something else (e.g. <span style="text-decoration: underline"> if you want the text to be underlined instead of bolded).

When performing the formatting, there is an issue where the user's text cursor position will be unexpectedly reset back to the beginning of the contenteditable div. To fix this, I used 2 functions (getOriginalCaretPosition and restoreCaretPosition) to store the user's original cursor position and then restore the position back after the text formatting is performed. These 2 functions are kind of complex and they're not entirely relevant to the OP's question so I will not go into much detail about them here. You can PM me if you want to learn more about them.

Horace Lee
  • 146
  • 6