I am creating a site where admins on the site will routinely post articles (much like a blog). I as an admin can write a basic HTML document easily, but the other admins are not at all familiar with HTML.
I have a form that they will use to publish their articles with author, title, and content fields. I am currently taking the 'content' field and displaying it as HTML after the form is submitted. To help the other users I have added buttons that say "header", "paragraph", "image", and "line break". When these buttons are clicked I would like to add html tags to the existing field (usually already filled with article text).
The idea is this:
I click the paragraph button and my field shows this:
"<p>type here</p>
".
I then type the paragraph and go to a new line. I decide to add a sub heading after it and click the heading button:
<p>I replaced the text</p>
<h3>type sub-heading here</h3>
I don't want the button to create a new input or add to the form in any way. I also don't want it to replace or reset the text that is there, but simply add text where the cursor is located. I've found plenty of methods to add form fields, replace them, hide them, etc, but can't dig up any posts about editing existing text with a button.
Anyone know how I can do this? I am using angular 2 as a framework, so any solution that fits with it (javascript, typescript, angular 2 data binding, etc) will work.
Here is my HTML:
<div class="edit-article">
<h2 *ngIf="isEdit">Edit an Article</h2>
<h2 *ngIf="!isEdit">Add an Article</h2>
<div class="input-group">
<label for="title">Title</label>
<input mdInput id="title" type="text" [(ngModel)]="title">
<label for="author">Author</label>
<input mdInput id="author" type="text" [(ngModel)]="author">
<label for="article-content">Content</label>
<input mdInput id="article-content" type="textarea" class="multi-line-input" [(ngModel)]="content">
</div>
<div class="button-group left">
<button class="button secondary" (click)='onAddHeader()'>Header</button>
<button class="button secondary" (click)='onAddParagraph()'>Paragraph</button>
<button class="button secondary" (click)='onAddImage()'>Image</button>
</div>
<div class="button-group right">
<button class="button primary" (click)="onSaveArticle()">Save</button>
TS file:
export class ArticleEditComponent {
isEdit = false;
public title: string;
public author: string;
public content: string;
constructor(
public dialogRef: MdDialogRef<any>, @Inject(MD_DIALOG_DATA) private dialogData: any,
public afAuth: AngularFireAuth, public afDB: AngularFireDatabase,
public articleService: ArticleService) {
}
onSaveArticle() {
this.articleService.createArticle(new Article(
this.title, this.author, this.content));
}
onAddHeader(){
document.getElementById("article-content").innerText += '<h3></h3>';
console.log('running header function');
}
onAddImage(){
document.getElementById("article-content").innerText += 'add image tag';
console.log('running header function');
}
onAddParagraph(){
document.getElementById("article-content").innerText += '<p></p>';
console.log('running header function');
}
I am creating a site where admins on the site will routinely post articles (much like a blog). I as an admin can write a basic HTML document easily, but the other admins are not at all familiar with HTML.
I have a form that they will use to publish their articles with author, title, and content fields. I am currently taking the 'content' field and displaying it as HTML after the form is submitted. To help the other users I have added buttons that say "header", "paragraph", "image", and "line break". When these buttons are clicked I would like to add html tags to the existing field (usually already filled with article text).
The idea is this:
I click the paragraph button and my field shows this:
"<p>type here</p>
".
I then type the paragraph and go to a new line. I decide to add a sub heading after it and click the heading button:
<p>I replaced the text</p>
<h3>type sub-heading here</h3>
I don't want the button to create a new input or add to the form in any way. I also don't want it to replace or reset the text that is there, but simply add text where the cursor is located. I've found plenty of methods to add form fields, replace them, hide them, etc, but can't dig up any posts about editing existing text with a button.
Anyone know how I can do this? I am using angular 2 as a framework, so any solution that fits with it (javascript, typescript, angular 2 data binding, etc) will work.
Here is my HTML:
<div class="edit-article">
<h2 *ngIf="isEdit">Edit an Article</h2>
<h2 *ngIf="!isEdit">Add an Article</h2>
<div class="input-group">
<label for="title">Title</label>
<input mdInput id="title" type="text" [(ngModel)]="title">
<label for="author">Author</label>
<input mdInput id="author" type="text" [(ngModel)]="author">
<label for="article-content">Content</label>
<input mdInput id="article-content" type="textarea" class="multi-line-input" [(ngModel)]="content">
</div>
<div class="button-group left">
<button class="button secondary" (click)='onAddHeader()'>Header</button>
<button class="button secondary" (click)='onAddParagraph()'>Paragraph</button>
<button class="button secondary" (click)='onAddImage()'>Image</button>
</div>
<div class="button-group right">
<button class="button primary" (click)="onSaveArticle()">Save</button>
TS file:
export class ArticleEditComponent {
isEdit = false;
public title: string;
public author: string;
public content: string;
constructor(
public dialogRef: MdDialogRef<any>, @Inject(MD_DIALOG_DATA) private dialogData: any,
public afAuth: AngularFireAuth, public afDB: AngularFireDatabase,
public articleService: ArticleService) {
}
onSaveArticle() {
this.articleService.createArticle(new Article(
this.title, this.author, this.content));
}
onAddHeader(){
document.getElementById("article-content").innerText += '<h3></h3>';
console.log('running header function');
}
onAddImage(){
document.getElementById("article-content").innerText += 'add image tag';
console.log('running header function');
}
onAddParagraph(){
document.getElementById("article-content").innerText += '<p></p>';
console.log('running header function');
}
Share
Improve this question
asked Aug 22, 2017 at 20:45
Logan KitchenLogan Kitchen
7743 gold badges13 silver badges29 bronze badges
2 Answers
Reset to default 1The following is an example that you could adapt:
HTML:
<input #input type="text">
<button (click)="addText()">Click me to add some text</button>
<button (click)="reset()">Reset</button>
TypeScript:
@ViewChild('input') private input;
addText(){
this.input.nativeElement.focus();
let startPos = this.input.nativeElement.selectionStart;
let value = this.input.nativeElement.value;
this.input.nativeElement.value=
value.substring(0, startPos) +' I am inserted ' + value.substring(startPos, value.length)
}
reset(){
this.input.nativeElement.value='';
}
Plunker
If you're using ngModel, the contents of whatever is in the corresponding input field will be bound to the variable you have listed.
<input mdInput id="title" type="text" [(ngModel)]="title">
Anything the user types will be bound to the "title" variable in the above input, and you can modify that variable anywhere in your ponent or template and it will be reflected in the view. So if you just wanted to add text to the input field, you could do something like:
<button class="button secondary" (click)="title = '<p> type here </p>' + title">Paragraph</button>
or you could do it in the ponent code
<button class="button secondary" (click)="addText()">Paragraph</button>
...somewhere in your ponent....
addText() {
f.title = '<p> type here </p>' + f.title;
}
(The above is assuming you have wrapped your form in an ngForm group, and given it the identifier #f , as they have done here: https://angular.io/api/forms/NgForm )
That method will add that text to the beginning of whatever is already in the title input field (note: you may have to escape that backslash, I can't remember). You shouldn't need to use the document.getElementById queries at all. Those are best avoided in Angular. And you shouldn't really need to access the innerText attribute either, if you're using ngModel. The beauty of 2-way binding is its basically already giving you that innerText attribute in the form of the 'title' variable. In fact, accessing the document object and nativeElement properties can almost always be avoided and should whenever possible.
You may need to import NgForm from '@angular/forms' if you haven't already. I can't remember if ngModel works properly without it.