Skip to content

Commit

Permalink
Merge pull request #8609 from surveyjs/issue/textarea-component-enhan…
Browse files Browse the repository at this point in the history
…cement

textarea component enhancement
  • Loading branch information
OlgaLarina authored Sep 11, 2024
2 parents f1fee0c + 53abd56 commit 18ac6f6
Show file tree
Hide file tree
Showing 38 changed files with 872 additions and 547 deletions.
3 changes: 3 additions & 0 deletions packages/survey-angular-ui/src/angular-ui.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";
import { TextAreaComponent } from "./components/text-area/text-area.component";
import { SurveyComponent } from "./survey.component";
import { PopupSurveyComponent } from "./popup.survey.component";
import { PageComponent } from "./page.component";
Expand Down Expand Up @@ -129,6 +130,7 @@ import { SvgBundleComponent } from "./svgbundle.component";
declarations: [
VisibleDirective, Key2ClickDirective, PanelDynamicAddBtn, PanelDynamicNextBtn, PanelDynamicPrevBtn, PanelDynamicProgressText, ElementComponent, TemplateRendererComponent,
SurveyComponent, SurveyContentComponent, PopupSurveyComponent, PageComponent, PanelComponent, QuestionComponent, StringViewerComponent, SurveyStringComponent, StringEditorComponent,
TextAreaComponent,
QuestionSkeletonComponent, TextQuestionComponent, RadiogroupComponent, RadiogroupItemComponent, CheckboxComponent, CheckboxItemComponent,
DropdownComponent, DropdownQuestionComponent, DropdownSelectComponent, DropdownOptionItemComponent,
PopupComponent, PopupBaseContainerComponent, PopupPointerComponent,
Expand All @@ -150,6 +152,7 @@ import { SvgBundleComponent } from "./svgbundle.component";
exports: [
VisibleDirective, Key2ClickDirective, PanelDynamicAddBtn, PanelDynamicNextBtn, PanelDynamicPrevBtn, PanelDynamicProgressText, ElementComponent, TemplateRendererComponent,
SurveyComponent, SurveyContentComponent, PopupSurveyComponent, PageComponent, PanelComponent, QuestionComponent, StringViewerComponent, SurveyStringComponent, StringEditorComponent,
TextAreaComponent,
QuestionSkeletonComponent, TextQuestionComponent, RadiogroupComponent, RadiogroupItemComponent, CheckboxComponent, CheckboxItemComponent,
CharacterCounterComponent,
DropdownComponent, DropdownQuestionComponent, DropdownSelectComponent, DropdownOptionItemComponent,
Expand Down
1 change: 1 addition & 0 deletions packages/survey-angular-ui/src/angular-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./popup.survey.component";
export * from "./page.component";
export * from "./question.component";
export * from "./string-viewer.component";
export * from "./components/text-area/text-area.component";
export * from "./components/popup/popup-pointer.component";
export * from "./components/popup/popup.component";
export * from "./components/popup/popup-container.component";
Expand Down
12 changes: 3 additions & 9 deletions packages/survey-angular-ui/src/comment-other.component.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
<textarea *ngIf="!question.isReadOnlyRenderDiv()" [id]="otherId" [attr.maxlength]="question.getOthersMaxLength()" [attr.aria-required]="question.ariaRequired || question.a11y_input_ariaRequired" [attr.aria-label]="question.ariaLabel || question.a11y_input_ariaLabel" [attr.placeholder]="otherPlaceholder"
[value]="otherValue"
[style.resize]="question.resizeStyle"
[attr.rows]="question.commentAreaRows"
[disabled]="question.isInputReadOnly"
(change)="onOtherValueChange($event)"
(input)="onOtherValueInput($event)"
[class]="question.cssClasses.other">
</textarea>
<ng-container *ngIf="!question.isReadOnlyRenderDiv()">
<ng-template [component]="{ name: 'sv-text-area', data: { model: textAreaModel } }"></ng-template>
</ng-container>
<div *ngIf="question.isReadOnlyRenderDiv()">{{ otherValue }}</div>
15 changes: 3 additions & 12 deletions packages/survey-angular-ui/src/comment-other.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, Input } from "@angular/core";
import { Question, QuestionSelectBase } from "survey-core";
import { Question, QuestionSelectBase, TextAreaModel } from "survey-core";

@Component({
selector: "sv-ng-comment-other, '[sv-ng-comment-other]'",
Expand All @@ -13,16 +13,7 @@ export class SurveyCommentOtherComponent {
const val = (<QuestionSelectBase>this.question).otherValue;
return !!val ? val : "";
}
public onOtherValueChange(event: any): void {
(<QuestionSelectBase>this.question).onOtherValueChange(event);
}
public onOtherValueInput(event: any): void {
(<QuestionSelectBase>this.question).onOtherValueInput(event);
}
public get otherId(): string {
return (<QuestionSelectBase>this.question).otherId;
}
public get otherPlaceholder(): string {
return (<QuestionSelectBase>this.question).otherPlaceholder;
public get textAreaModel(): TextAreaModel {
return (<QuestionSelectBase>this.question).otherTextAreaModel;
}
}
12 changes: 3 additions & 9 deletions packages/survey-angular-ui/src/comment.component.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
<textarea *ngIf="!question.isReadOnlyRenderDiv()" [id]="question.commentId" [attr.maxlength]="question.getOthersMaxLength()" [attr.aria-required]="question.ariaRequired || question.a11y_input_ariaRequired" [attr.aria-label]="question.ariaLabel || question.a11y_input_ariaLabel" [attr.placeholder]="question.renderedCommentPlaceholder"
[value]="comment"
[style.resize]="question.resizeStyle"
[attr.rows]="question.commentAreaRows"
[disabled]="question.isInputReadOnly"
(change)="question.onCommentChange($event)"
(input)="question.onCommentInput($event)"
[class]="question.cssClasses.other">
</textarea>
<ng-container *ngIf="!question.isReadOnlyRenderDiv()">
<ng-template [component]="{ name: 'sv-text-area', data: { model: question.commentTextAreaModel } }"></ng-template>
</ng-container>
<div *ngIf="question.isReadOnlyRenderDiv()">{{ question.comment }}</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<textarea
[readonly]="model.isReadOnlyAttr"
[disabled]="model.isDisabledAttr"
[id]="model.id"
[attr.maxlength]="model.maxLength"
[attr.cols]="model.cols"
[attr.rows]="model.rows"
[attr.placeholder]="model.placeholder"
[class]="model.className"
[value]="value"
(input)="model.onTextAreaInput($event)"
(keydown)="model.onTextAreaKeyDown($event)"
(focus)="model.onTextAreaFocus($event)"
(blur)="model.onTextAreaBlur($event)"
(change)="model.onTextAreaChange($event)"
[attr.aria-required]="model.ariaRequired"
[attr.aria-label]="model.ariaLabel"
[attr.aria-labelledby]="model.ariaLabelledBy"
[attr.aria-describedby]="model.ariaDescribedBy"
[attr.aria-invalid]="model.ariaInvalid"
[attr.aria-errormessage]="model.ariaErrormessage"
[style.resize]="model.question.resizeStyle"
#contentElement></textarea>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Component, ElementRef, Input, ViewChild } from "@angular/core";
import { TextAreaModel } from "survey-core";
import { AngularComponentFactory } from "../../component-factory";
import { EmbeddedViewContentComponent } from "../../embedded-view-content.component";

@Component({
selector: "sv-text-area",
templateUrl: "./text-area.component.html"
})
export class TextAreaComponent extends EmbeddedViewContentComponent {
@Input() model!: TextAreaModel;
@ViewChild("contentElement") elementContentRef!: ElementRef<HTMLElement>;

get value() {
return this.model.getTextValue() || "";
}

public ngAfterViewInit(): void {
if (!!this.model && !!this.elementContentRef?.nativeElement) {
const element = this.elementContentRef.nativeElement;
this.model.setElement(element as HTMLTextAreaElement);
}
}

ngOnDestroy(): void {
this.model.dispose();
}
}

AngularComponentFactory.Instance.registerComponent("sv-text-area", TextAreaComponent);
35 changes: 7 additions & 28 deletions packages/survey-angular-ui/src/questions/comment.component.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
<textarea
*ngIf="!model.isReadOnlyRenderDiv()"
[readonly]="model.isReadOnlyAttr"
[disabled]="model.isDisabledAttr"
[id]="model.inputId"
[attr.maxlength]="model.getMaxLength()"
[attr.cols]="model.cols"
[attr.rows]="model.rows"
[attr.placeholder]="model.renderedPlaceholder"
[class]="model.className"
[value]="model.value || null"
(input)="model.onInput($event)"
(keydown)="model.onKeyDown($event)"
(change)="onChange($event)"
(focus)="model.onFocus($event)"
(blur)="model.onBlur($event)"
[attr.aria-required]="model.a11y_input_ariaRequired"
[attr.aria-label]="model.a11y_input_ariaLabel"
[attr.aria-labelledby]="model.a11y_input_ariaLabelledBy"
[attr.aria-describedby]="model.a11y_input_ariaDescribedBy"
[attr.aria-invalid]="model.a11y_input_ariaInvalid"
[attr.aria-errormessage]="model.a11y_input_ariaErrormessage"
[style.resize]="model.resizeStyle"
#contentElement></textarea>
<sv-ng-character-counter *ngIf="!model.isReadOnlyRenderDiv() && model.getMaxLength()"
[counter]="model.characterCounter"
[remainingCharacterCounter]="model.cssClasses.remainingCharacterCounter">
</sv-ng-character-counter>
<ng-container *ngIf="!model.isReadOnlyRenderDiv()">
<ng-template [component]="{ name: 'sv-text-area', data: { model: model.textAreaModel } }"></ng-template>
<sv-ng-character-counter *ngIf="model.getMaxLength()"
[counter]="model.characterCounter"
[remainingCharacterCounter]="model.cssClasses.remainingCharacterCounter">
</sv-ng-character-counter>
</ng-container>
<div *ngIf="model.isReadOnlyRenderDiv()" #contentElement>{{ model.value }}</div>
1 change: 1 addition & 0 deletions packages/survey-core/entries/chunks/core-wo-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from "../../src/utils/animation";
export * from "../../src/actions/adaptive-container";
export * from "../../src/actions/container";
export * from "../../src/utils/dragOrClickHelper";

1 change: 1 addition & 0 deletions packages/survey-core/entries/chunks/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ export { InputMaskNumeric } from "../../src/mask/mask_numeric";
export { InputMaskDateTime } from "../../src/mask/mask_datetime";
export { InputMaskCurrency } from "../../src/mask/mask_currency";
export * from "../../src/utils/cssClassBuilder";
export * from "../../src/utils/text-area";

export { surveyCss, defaultV2Css, defaultV2ThemeName } from "../../src/defaultCss/defaultV2Css";

Expand Down
28 changes: 23 additions & 5 deletions packages/survey-core/src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { ConsoleWarnings } from "./console-warnings";
import { ProcessValue } from "./conditionProcessValue";
import { ITheme } from "./themes";
import { DomWindowHelper } from "./global_variables_utils";
import { ITextArea, TextAreaModel } from "./utils/text-area";

export interface IConditionObject {
name: string;
Expand Down Expand Up @@ -90,6 +91,27 @@ export class Question extends SurveyElement<Question>
private isReadyValue: boolean = true;
private commentElements: Array<HTMLElement>;
private dependedQuestions: Array<Question> = [];
public commentTextAreaModel: TextAreaModel;

private getCommentTextAreaOptions(): ITextArea {
const options: ITextArea = {
question: this,
id: () => this.commentId,
propertyName: "comment",
className: () => this.cssClasses.comment,
placeholder: () => this.renderedCommentPlaceholder,
isDisabledAttr: () => this.isInputReadOnly || false,
rows: () => this.commentAreaRows,
autoGrow: () => this.autoGrowComment,
maxLength: () => this.getOthersMaxLength(),
ariaRequired: () => this.a11y_input_ariaRequired,
ariaLabel: () => this.a11y_input_ariaLabel,
getTextValue: () => { return this.comment; },
onTextAreaChange: (e) => { this.onCommentChange(e); },
onTextAreaInput: (e) => { this.onCommentInput(e); },
};
return options;
}

/**
* An event that is raised when the question's ready state has changed (expressions are evaluated, choices are loaded from a web resource specified by the `choicesByUrl` property, etc.).
Expand Down Expand Up @@ -140,6 +162,7 @@ export class Question extends SurveyElement<Question>
this.createNewArray("validators", (validator: any) => {
validator.errorOwner = this;
});
this.commentTextAreaModel = new TextAreaModel(this.getCommentTextAreaOptions());

this.addExpressionProperty("visibleIf",
(obj: Base, res: any) => { this.visible = res === true; },
Expand Down Expand Up @@ -912,11 +935,6 @@ export class Question extends SurveyElement<Question>
}
public get isContainer(): boolean { return false; }
protected updateCommentElements(): void {
if (!this.autoGrowComment || !Array.isArray(this.commentElements)) return;
for (let i = 0; i < this.commentElements.length; i++) {
const el = this.commentElements[i];
if (el) increaseHeightByContent(el);
}
}
public onCommentInput(event: any): void {
if (this.isInputTextUpdate) {
Expand Down
Loading

0 comments on commit 18ac6f6

Please sign in to comment.