Showing a document to write text on with javascript - javascript

I am attempting to design a very basic word processor. I want to have a "page" shown in the background (like you might see on Google Docs, or MS Word) that your text is written on.
How do I draw this page? Should it be an SVG? A stylized DIV? A big canvas? I am very new to designing using the DOM, so any help is appreciated.

Take a look at the contenteditable property here. This actually allows some elements content to be edited by the end user. For example, if I have
<div contenteditable="true">Hello!</div>
I can actually edit the text and change it as it fits my needs, right from the browser. This will come in handy when you try to implement features like bold or italic text, and a div element is also much easier to generally style than a huge textarea or input field.
As a notice, also don't forget about XSS.

You may be interested in the getting the page-like appearance at Google Docs. If so, then check out this really nice tutorial on building a collaborative text editor with Javascript. It's well written and introduces concepts gradually and even has a GitHub repo.
I streamlined the example into a single file HTML file that you can play with. This example also uses the contenteditable property mentioned in Armen's answer. By the way, the page-like effect is achieved via CSS which I've included within the HTML file using the <style> tag.
<html><head><style>
body { font-size: 14px; line-height: 20px; background: #e8e8e8; }
.ribbon { height: 200px; background: #3F51B5; }
.editor { width: 60%; padding: 40px 28px; min-height: 300px;
background: #fff; margin: 0 auto; position: relative;
top: -150px; font-size: 24px; }
</style>
<body>
<div class="ribbon"></div>
<div id="doc" class="editor" contenteditable="true"></div>
<script>document.getElementById('doc').focus();</script>
</head></body></html>

You can use a textarea element and set a specific height and width.
const bold = document.getElementById('bold');
const text = document.getElementById('text');
bold.addEventListener('click', () => {
if (text.style.fontWeight != 'bolder') {
text.style.fontWeight = 'bolder';
}
else {
text.style.fontWeight = 'normal';
}
});
textarea {
height: 500px;
width: 300px;
}
<button id="bold">bold</button>
<br>
<textarea id="text" placeholder="write text here!"></textarea>

Related

Is it possible/feasible to replace certain characters with <span>[character]</span> as they are typed?

I'd like to have it so that whenever a user types a '#' into the search form, the '#' is styled a specific color.
I assume that the only way to do this would be to replace every instance of that character with a <span class="colorHash"></span> and to then apply the color to the class with css.
Is this possible? Can anyone point me in the right direction?
One solution would be to have an element that mimics a text input by looking as much like one as possible be placed over the actual input. This mimic would be updated every time the input changes, and include the color-changed hashes. It would have no pointer events, so clicking on it would allow the user to interact with the underlying real input.
Here is a reference implementation. It is by no means perfect, and I do not recommend copying code from it.
Good things:
Input data is stored unchanged in an <input> element, so works fine with forms.
Bad things:
What is shown is not an actual <input> element, but a mimic. This causes there to be no cursor (bad), and may cause other issues. It means all styling on input[type=text] should be on the mimic, too.
Slight input lag.
A slightly different way of doing this would be to have the mimic be invisible, except for the red hashes.
Here is a reference implementation. It is by no means perfect, and I do not recommend copying code from it.
Good things:
Removes lag on input
Cursor is visible
User sees the real input element (good in my book)
Bad things:
Red color lags (mostly visible when using the jQuery version of the code)
Likely much harder to maintain. The mimic must be positioned to pixel-perfection on top of the real input.
Since this seems to be closer to what you're looking for, I'll include the code for this version here...
This code is by no means perfect, and I do not recommend copying code from it.
<div id="wrapper">
<input type="text" id="data-input">
<pre class="text-input-mimic" id="shown-data"></pre>
</div>
#wrapper { position: relative; }
#shown-data {
/* Stacked in top-left corner */
position: absolute;
top: 0;
left: 0;
/* Clicking and typing goes through to real input */
pointer-events: none;
}
.text-input-mimic, input[type=text] {
border: 1px solid grey;
width: 250px;
height: 20px;
padding: 5px;
display: inline-block;
margin: 0;
font-family: Calibri !important;
font-size: 16px !important;
}
.text-input-mimic {
/* Make invisible except for hashes */
background: none !important;
border: none !important;
color: rgba(0, 0, 0, 0);
/* Pixel-perfect adjustments */
padding-top: 7px;
padding-left: 6px;
}
.colored { color: red !important; }
JS (jQ):
$('#data-input').on("change keyup paste", function() {
let inp = $('#data-input').val();
let modified = inp.replace(/#/g, '<span class="colored">#</span>');
$('#shown-data').html(modified);
});
Alternatively, JS (plain):
real = document.getElementById('data-input');
mimic = document.getElementById('shown-data');
real.addEventListener('input', function() {
let inputVal = real.value;
let modified = inputVal.replace(/#/g, '<span class="colored">#</span>');
mimic.innerHTML = modified;
});

i want to put some text infront of some line on the border style?, is this a z-index style?

I can't post images because it says that I need 10 reputation to post images so here's the link.
click here
Because I want to put some text in-front of some of the border line,
Need your suggestion/tips guys.
What you are showing in your image is a fieldset.
<fieldset>
<legend>I'm a Fieldset</legend>
Stuff<br>
Stuff
</fieldset>
Just a text blocks splitted with vertical lines like that?
.lined {
display: table;
border: 1px solid;
}
.lined > div {
position: relative;
display: table-cell;
padding: 1em;
}
.lined > div + div:before {
content: "";
position: absolute;
top: 10%;
left: -1px;
width: 0;
height: 80%;
border-left: 1px solid;
}
<div class="lined">
<div>The display property specifies the type of rendering box used for an element. In HTML, default display property values are taken from behaviors described in the HTML specifications or from the browser/user default stylesheet. The default value in XML is inline.</div>
<div>In addition to the many different display box types, the value none lets you turn off the display of an element; when you use none, all descendant elements also have their display turned off. The document is rendered as though the element doesn't exist in the document tree.</div>
<div>CSS is one of the core languages of the open web and has a standardized W3C specification. Developed in levels, CSS1 is now obsolete, CSS2.1 is a recommendation, and CSS3, now split into smaller modules, is progressing on the standardization track.</div>
</div>

Code editor response window

I am working on a site that is an online code editor. Users can load a page where they can type HTML code, which is then displayed (as web format) in a small frame that represents the compiled webpage.
The frame that the HTML is rendered in looks like this:
#responseWindow {
width: 100%;
height: 200px;
background-color: white;
margin-top: 30px;
margin-bottom: 30px;
overflow: auto;
padding-left: 8px;
padding-right: 8px;
padding-top: 10px;
padding-bottom: 10px;
}
The Javascript which transfers the code from the editor to the responseWindow looks like this:
editor.getSession().on('change', function() {
document.getElementById('responseWindow').innerHTML = editor.getValue();
});
Usually everything typed stays within that frame, but if the user gives a div fixed positioning, then the text does not stay within the frame and appears somewhere else on the page. For example:
<p style="top: 100px; right: 10px;">Hello world</p>
Then the text Hello World is not in the frame. My question is how can I make some type of independent space for the code to render in? How can I make my users code render in a box/frame so they can preview what it looks like?
Set #responseWindow to position: relative
Positioned elements are relative to their closest positioned ancestor. Right now your #responseWindow's position is static, which is not considered to be "positioned".

How to draw a line from the middle of the page to the right side?

How to draw a line (using css, html or js) from the middle of the page to the right side?
This should work on a different screen resolutions.
The example provided in the picture.
Using a horizontal rule in css.
hr {
color: white;
background: blue;
width: 75%;
height: 5px;
margin-left:25%;
}
<body>
<hr />
<hr/>
</body>
Please see jsfiddle
http://jsfiddle.net/yvytty/jJRAt/
Maybe like this?
HTML
<div class="line"></div>
CSS
div.line {
width: 75%;
height: 1px;
margin-left: 25%;
background: red;
}
Demo
Try before buy
html:
<div id="lineID" class="line"></div>
css:
.line{
background:red;
height: 1px;
margin-left:50%;
}
javascript for more dynamic control:
//you can also put all the css in here
var scr=screen.width/2
var myLine = document.getElementById('lineID');
myLine.style.cssText= "width:"+scr+"px";
fiddle of course!
To my mind the best way to get a line from the middle to the right which scales correctly and is pure CSS is the following:
HTML
<div class="lineblock"></div>
CSS
.lineblock{
width: 50%; /*width can vary yours looks to be ~75% */
height: 20px; /* Random thickness I chose to make sure I saw it on the page */
float: right; /* Always forces to the right-hand side of the parent (so make sure
you're in the top level of the page or have no 'container' div
surrounding your line)*/
background: magenta; /*shows on anything*/
}
This method is both - a) Going to scale to all device screen sizes and be 50% of the viewport, and, b) be dumb enough to be IE 8 + safe (probably more but I only test to 8 it is used by about 10-12% of people internationally* and below that is almost nobody these days).
Sources:
HTML - Simple div
CSS - Experimentation
Browser Stats - Stat Counter's browser version usage for this month past.
Correct at time of writing.

Replacing normal file upload input with an image

Bit of a newbie question here.
I have a form and one of it's fields is for a file upload. Instead of having the boring old usual text input box with a 'choose file' button beside it, I'd like to have an image which when you click opens the dialog box to browse for the photo.
The way I was hoping to be able to do this was with two forms. IE when the user clicks the image a modal box appears with form upload input in it. User chooses file and clicks submit the user is returned to the form.
That doesn't seem to work because having a form inside a form must be bad practice i suppose :) Is there a way to do it like this?
The alternative is that I can somehow replace the usual text input box with the 'choose file' button with my own graphic but despite google I ain't found out how to do that.
Any ideas
Very simple solution - simply put a label tag for your input
<label for="uploadFile">
<div id="image"></div>
</label>
<input type="file" id="uploadFile" style="display:none" />
And the just add a background-image property to the #image div :)
Because of the heap of security issues around how file inputs work, they're pretty hard to fix. What does work, however, is a scheme like this:
Design your own look for a file input that's fairly close to the default one in size and shape
Position your file input and a real file input at the same place in your form, with the real one on top of yours
Make the real input be transparent (that is, set the opacity to zero)
Now clicks on your elements styled the way you want them to look will actually be interpreted by the browser as clicks on the file input. You have to tweak things somewhat for IE, because IE7 allows the user to type directly into the input while other browsers all immediately launch the file chooser when the element is clicked anywhere.
edit — here is a jsfiddle that works in Chrome at least. The HTML:
<div class='fancy-file'>
<div class='fancy-file-name'> </div>
<button class='fancy-file-button'>Browse...</button>
<div class='input-container'>
<input type='file'>
</div>
</div>
That wraps the "fake" file input that I'll style with my own CSS, as well as the real <input> element. Here's the CSS:
div.fancy-file {
position: relative;
overflow: hidden;
cursor: pointer;
}
div.fancy-file-name {
float: left;
border-radius: 3px;
background-color: #aaa;
box-shadow:
inset 1px 1px 3px #eee,
inset -1px -1px 3px #888,
1px 1px 3px #222;
font-weight: bold;
font-family: Courier New, fixed;
width: 155px;
font-size: 12px;
padding: 1px 4px;
}
button.fancy-file-button {
float: left;
border-radius: 3px;
border: 1px solid red;
background-color: #F5BD07;
font-weight: bold;
vertical-align: top;
margin: 0 0 0 3px;
}
div.input-container {
position: absolute;
top: 0; left: 0;
}
div.input-container input {
opacity: 0;
}
The outer container is made "position: relative" to make it easy to position the real <input> over the fake stuff. The fake stuff has my made-up fancy styles, and it's sized so that it's just about the same as the overall size of a real file input. The real one is absolutely positioned and transparent.
Here's some jQuery to drive it:
$('div.fancy-file input:file').bind('change blur', function() {
var $inp = $(this), fn;
fn = $inp.val();
if (/fakepath/.test(fn))
fn = fn.replace(/^.*\\/, '');
$inp.closest('.fancy-file').find('.fancy-file-name').text(fn);
});
Browsers won't give you the complete pathname, but they'll give you a part of it. Some browsers (Chrome and IE) give you an obviously-fake path prefix, so the code strips that out (because it's useless).
File upload fields are quite limited. See: http://www.quirksmode.org/dom/inputfile.html

Categories