Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move overflowed text to beginning when focusing out contentEditable element

Take a look at this example: https://jsfiddle.net/qpysmb9t/

Whenever text in the contentEditable element becomes bigger that the max-width of the div(try typing some long text), than the left part gets hidden and what's on the right is shown. This is okay while you type, but on focus out I'd like to reverse this and show text from the beginning.

<div tabindex="-1" contenteditable="true" class="name-data">This is test</div>

.name-data{
  max-width:180px;
  white-space: nowrap;
  overflow-x: hidden;
}

The usual answer is to move caret position to the start, however that does not move the text along the way and it also messes with element not focusing out anymore. Check it out: https://jsfiddle.net/qpysmb9t/1/

What do you recommend that I do?

like image 536
potato Avatar asked Feb 26 '19 09:02

potato


2 Answers

A dash of JavaScript helps. When the div loses focus we can use scrollLeft to get back to the begin position.

//scroll the text back to the beginning when focus is lost
document.querySelector("div.name-data[contenteditable='true']").addEventListener("blur", function(e){
  this.scrollLeft = "0px";
}, true);
.name-data{
  max-width:180px;
  white-space: nowrap;
  overflow-x: hidden;
  border: 1px solid #949494;
}
<div tabindex="-1" contenteditable="true" class="name-data">This is test</div>
like image 108
Mouser Avatar answered Oct 18 '22 18:10

Mouser


IDEA: Make your div display: flex and toggle justify-content propertive when user focus out to force browser re-paint the content

CSS only solution:

.project-name-data {
  max-width: 180px;
  white-space: nowrap;
  overflow-x: hidden;

  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
  border: solid 1px gray;
}

.project-name-data:focus{
  justify-content: flex-end;
}
<div tabindex="-1" contenteditable="true" #projectName class="project-name-data">This is test</div>

I like CSS only solution but it weird because the div content have different align from two state focus and normal. So i add a bit javscript to fix it

Javascript solution:

document.getElementsByClassName("project-name-data")[0].addEventListener("focusout", function() {
  this.style.justifyContent = "flex-end";
  // Wait a tick then change the justifyContent back to force browser re-paint
  setTimeout(() => {
    this.style.justifyContent = "flex-start";
  }, 0)
});
.project-name-data {
  max-width: 180px;
  white-space: nowrap;
  overflow-x: hidden;
  
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
  border: solid 1px gray;
}
<div tabindex="-1" contenteditable="true" #projectName class="project-name-data">This is test</div>
like image 23
Duannx Avatar answered Oct 18 '22 20:10

Duannx