Changed contenteditable div to textarea

This commit is contained in:
Magnus Åhall 2023-06-20 07:35:34 +02:00
parent cb9d95bcb2
commit 0175c4044c
5 changed files with 47 additions and 18 deletions

View File

@ -145,18 +145,21 @@ header .menu {
.node-content { .node-content {
justify-self: center; justify-self: center;
padding: 16px 32px; padding: 16px 32px;
white-space: pre-wrap; word-wrap: break-word;
font-family: monospace;
font-size: 0.85em; font-size: 0.85em;
color: #333; color: #333;
width: 100ex; width: 100ex;
resize: none;
border: none;
outline: none;
} }
.node-content[contenteditable] { .node-content[contenteditable] {
outline: 0px solid transparent; outline: 0px solid transparent;
} }
.node-content:empty { .node-content:invalid {
background: #ddd; border-bottom: 1px solid #eee;
border-radius: 8px; border-radius: 8px;
height: 48px;
} }
.tree { .tree {
padding: 16px; padding: 16px;

View File

@ -5,8 +5,6 @@
<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=yes" />
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/main.css"> <link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/main.css">
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/login.css"> <link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/login.css">
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/css_reload.js"></script>
<script type="importmap"> <script type="importmap">
{ {
"imports": { "imports": {
@ -22,6 +20,8 @@
} }
} }
</script> </script>
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/css_reload.js"></script>
</head> </head>
<body> <body>

View File

@ -9,7 +9,7 @@ const html = htm.bind(h)
class App extends Component { class App extends Component {
constructor() {//{{{ constructor() {//{{{
super() super()
this.websocket_uri = `wss://notes.ahall.se/ws` this.websocket_uri = `ws://localhost:1371/ws`
this.websocket = null this.websocket = null
this.websocket_int_ping = null this.websocket_int_ping = null
this.websocket_int_reconnect = null this.websocket_int_reconnect = null

View File

@ -64,16 +64,18 @@ export class NodeUI extends Component {
<div class="crumbs">${crumbs}</crumbs> <div class="crumbs">${crumbs}</crumbs>
${children.length > 0 ? html`<div class="child-nodes">${children}</div>` : html``} ${children.length > 0 ? html`<div class="child-nodes">${children}</div>` : html``}
<div class="tree" onclick=${()=>this.retrieveTree()} style="color: #000">
<div class="node">Start</div>
${treeHTML}
</div>
${node.ID > 0 ? html` ${node.ID > 0 ? html`
<div class="node-name">${node.Name}</div> <div class="node-name">${node.Name}</div>
<${NodeContent} key=${node.ID} content=${node.Content} ref=${this.nodeContent} /> <${NodeContent} key=${node.ID} content=${node.Content} ref=${this.nodeContent} />
` : html``} ` : html``}
` `
/*
<div class="tree" onclick=${()=>this.retrieveTree()} style="color: #000">
<div class="node">Start</div>
${treeHTML}
</div>
*/
}//}}} }//}}}
componentDidMount() {//{{{ componentDidMount() {//{{{
let urlParams = new URLSearchParams(window.location.search) let urlParams = new URLSearchParams(window.location.search)
@ -118,7 +120,11 @@ export class NodeUI extends Component {
.catch(this.props.app.responseError) .catch(this.props.app.responseError)
}//}}} }//}}}
saveNode() {//{{{ saveNode() {//{{{
let content = this.nodeContent.current.contentDiv.current.innerText let content = this.nodeContent.current.contentDiv.current.value
content = content
.replaceAll("\r", "")
.replaceAll("<br>", "")
this.props.app.request('/node/update', { this.props.app.request('/node/update', {
NodeID: this.node.value.ID, NodeID: this.node.value.ID,
Content: content, Content: content,
@ -178,7 +184,24 @@ class NodeContent extends Component {
} }
}//}}} }//}}}
render({ content }) {//{{{ render({ content }) {//{{{
return html`<div class="node-content" ref=${this.contentDiv} contenteditable=true oninput=${()=>window._app.current.nodeModified.value = true}>${content}</div>` return html`
<textarea class="node-content" ref=${this.contentDiv} oninput=${()=>this.contentChanged()} required rows=1>${content}</textarea>
`
}//}}}
componentDidMount() {//{{{
this.resize()
}//}}}
componentDidUpdate() {//{{{
this.resize()
}//}}}
contentChanged() {//{{{
window._app.current.nodeModified.value = true
this.resize()
}//}}}
resize() {//{{{
let textarea = this.contentDiv.current;
textarea.style.height = "auto";
textarea.style.height = textarea.scrollHeight + 16 + "px";
}//}}} }//}}}
} }
@ -193,7 +216,6 @@ class Node {
this.Children = [] this.Children = []
this.Crumbs = [] this.Crumbs = []
}//}}} }//}}}
retrieve(callback) {//{{{ retrieve(callback) {//{{{
this.app.request('/node/retrieve', { ID: this.ID }) this.app.request('/node/retrieve', { ID: this.ID })
.then(res=>{ .then(res=>{

View File

@ -172,19 +172,23 @@ header {
.node-content { .node-content {
justify-self: center; justify-self: center;
padding: 16px 32px; padding: 16px 32px;
white-space: pre-wrap; word-wrap: break-word;
font-family: monospace;
font-size: 0.85em; font-size: 0.85em;
color: #333; color: #333;
width: 100ex; width: 100ex;
resize: none;
border: none;
outline: none;
&[contenteditable] { &[contenteditable] {
outline: 0px solid transparent; outline: 0px solid transparent;
} }
&:empty { &:invalid {
background: #ddd; //background: #eee;
border-bottom: 1px solid #eee;
border-radius: 8px; border-radius: 8px;
height: 48px;
} }
} }