alertTextField()

like alert() but using a dialog with a textarea: with newlines and editable and selectable text. Likewise for prompt(), a dialog with textarea and callback on close.

by Laurens Maneschijn

HTML

<hr>

<textarea id="ta" rows="10">
Some text.
Some more text on a long long long long long long long long long long long line.
Andaverylongunbrokenwoooooooooooooooooooooooooooooooooooooooooooooooooooooooord.
</textarea>

&larr; popup dialog with this string, using:<br>

<button onclick="s=document.querySelector('#ta').value; alert(s);">
	alert()
</button>

<button onclick="s=document.querySelector('#ta').value; alertTextField(s);">
	alertTextField()
</button>

<button onclick="s=document.querySelector('#ta').value; alertTextField2(s);">
	alertTextField2()
</button>

<button onclick="s=document.querySelector('#ta').value; console.log(prompt(s, s));">
	prompt()
</button>

<button id="button3">
	promptTextField()
</button>

<hr>

Note that you can not select the text in a default <code>alert()</code>.<br>
Also note that newlines are lost in the selectable value input of a <code>prompt()</code>.<br>
Attempt a simple custom dialog with a textarea where you keep the newlines and can select all text, and can also be modified easily to support anything you want.

<hr>

So far this is the most basic easy to use variant:
<pre id="examples"></pre>

<hr>

<details>
<summary>links/references: ...</summary>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog">MDN &lt;dialog&gt;</a>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Window/alert">MDN alert()</a>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt">MDN prompt()</a>
</ul>
</details>

CSS

#examples {
	max-width: 90%;
	overflow: auto;
	background: #8882;
}

JavaScript

// short version; useful for e.g. bookmarklet url js code:
function alertTextField(s) {
	let d = document.createElement('dialog');
	document.body.appendChild(d);
	d.innerHTML = `<form method="dialog"><textarea></textarea><button style="vertical-align: top;">x</button></form>`;
	d.querySelector('textarea').textContent = s;
	d.showModal();
}

function alertTextField2(s) {
	let textarea_auto_height = (ta) => {
		ta.style.height = "1lh";
		ta.style.height = (ta.scrollHeight) + "px";
	};
	let _, d,f,ta,b;
	_ = document.createElement.bind(document);
	d = _('dialog');
	f = _('form');
	ta = _('textarea');
	b = _('button');
	document.body.appendChild(d);
	d.appendChild(f);
	f.appendChild(ta);
	f.appendChild(b);
	f.setAttribute('method', 'dialog');
	ta.textContent = s;
	b.textContent = 'x';
	b.style.verticalAlign = 'top';
	setTimeout( () => {
		textarea_auto_height(ta);
	}, 1);
	ta.onkeyup = (e) => {textarea_auto_height(ta);};
	
	d.showModal();
	return d;
}

// dialogs are somewhat buggy if created immediately on page load:
// 	alertTextField('some\ntext');
// but this works:
// 	setTimeout( () => { alertTextField('some\ntext'); }, 1);

document.querySelector('#button3').addEventListener('click', (e) => {
	let s = document.querySelector('#ta').value;
//	console.log(prompt(s,s));
//	promptTextField(s, s, console.log);
	promptTextField(s, s, (value, dialogReturnValue, dialog, closeEvent) => {
		console.log({value, dialogReturnValue, dialog, closeEvent});
	});
});

function promptTextField(s, v, callback) {
	let d = document.createElement('dialog');
	document.body.appendChild(d);
	d.innerHTML = `
<form method="dialog">
<p style="white-space: pre; overflow: auto; max-width: calc(100vw - 50px); max-height: calc(50vh - 100px); resize: both;" onhover="this.style.maxWidth='';this.style.maxHeight='';"></p>
<textarea style="max-width: calc(100vw - 50px); max-height: calc(50vh - 100px); "></textarea>
<br>
<button value="ok">Ok</button>
<button...