diff --git a/.gitignore b/.gitignore index eb5303f177..4952ffa8dc 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,10 @@ wwwroot/* *.cs project.lock.json *.cmd +.idea +*.cmd /package *.js /src/template_question.html.ts /src/template_page.html.ts -/src/templateEditor.ko.html.ts +/src/templateEditor.ko.html.ts \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index c17e422056..995be41063 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -14,7 +14,9 @@ var gulp = require('gulp'), sequence = require("gulp-sequence"), html2ts = require("gulp-html-to-ts"), jsonTransform = require('gulp-json-transform'), - project = require("./project.json"); + project = require("./project.json"), + webpackStream = require('webpack-stream'), + getWebpackConfig = require('./webpack.config'); var Server = require("karma").Server; var editorVersion = "0.9.12"; @@ -50,6 +52,15 @@ var copyright = ["/*!", "* Github - https://github.com/andrewtelnov/survey.js.editor", "*/", "", ""].join("\n"); +var webpack_params = { + bundleName: "surveyeditor", + entryPoint: "./src/entries/index" +}; + +var webpack_params_test = { + bundleName: "surveyeditor.test", + entryPoint: "./tests/entries/index" +}; gulp.task('copyfiles', function (callback) { gulp.src(gnf(null, 'package.json'), { base: './' }) @@ -81,97 +92,89 @@ gulp.task('updatesurveyjsversion', function (callback) { .pipe(gulp.dest("")); }); -(function () { - (function () { - "use strict"; - gulp.task("typescript:sources", function () { - var tsResult = gulp.src([ - paths.webroot + "/lib/survey/**/*.d.ts", - paths.typings - ].concat(paths.ts)) - .pipe(insert.prepend(copyright)) - .pipe(sourcemaps.init()) - .pipe(ts({ - target: "ES5", - noImplicitAny: false, - declarationFiles: true - })); - - return tsResult.js - .pipe(concat(paths.mainJSfile)) - .pipe(sourcemaps.write({ sourceRoot: "src" })) - //Source map is a part of generated file - .pipe(gulp.dest(paths.dist)) - .pipe(gulp.dest(paths.jsFolder)) - .pipe(gulp.dest(paths.packageDist)); - }); - - gulp.task("typescript:tests", function () { - var tsResult = gulp.src([ - paths.webroot + "/lib/survey/**/*.d.ts", - paths.typings, - //"./src/model/*.ts", - paths.tsTests]) - .pipe(sourcemaps.init()) - .pipe(ts({ - target: "ES5", - noImplicitAny: false - })); - - return tsResult.js - .pipe(concat('surveyeditor.tests.js')) - .pipe(sourcemaps.write({ sourceRoot: "tests" })) - //Source map is a part of generated file - .pipe(gulp.dest(paths.testsFolder)); - }); - - gulp.task('test:copy-index-html', function () { - return gulp.src('./tests/index.html') - // Perform minification tasks, etc here - .pipe(gulp.dest(paths.testsFolder)); - }); - - gulp.task("typescript", ["typescript:sources", "typescript:tests", "test:copy-index-html"]); - })("TypeScript compilation"); - - gulp.task('compress', function () { - "use strict"; - return gulp.src(paths.dist + paths.mainJSfile) - .pipe(uglify()) - .pipe(rename({ - extname: '.min.js' - })) - .pipe(concat.header(copyright)) - .pipe(gulp.dest(paths.dist)) - .pipe(gulp.dest(paths.packageDist)); - }); - - gulp.task('sass', function () { - "use strict"; - return gulp.src(paths.styles) - .pipe(sass.sync().on('error', sass.logError)) - .pipe(concat("surveyeditor.css")) - .pipe(gulp.dest(paths.webroot + 'css')) - .pipe(gulp.dest(paths.dist + 'css')) - .pipe(gulp.dest(paths.packageDist)); - }); - - gulp.task('templates', function () { - "use strict"; - gulp.src(paths.template_page) - .pipe(html2ts()) - .pipe(gulp.dest("./src/")); - gulp.src(paths.template_question) - .pipe(html2ts()) - .pipe(gulp.dest("./src/")); - return gulp.src(paths.templates_ko) - .pipe(concat("templateEditor.ko.html")) - .pipe(html2ts()) - .pipe(gulp.dest("./src/")); - }); - - gulp.task("makedist", sequence("templates", ["typescript", "sass"], "compress", "createPackage", "updatesurveyjsversion")); -})("TypeScript compilation"); +gulp.task("typescript:sources", function () { + var params = webpack_params; + var tsResult = gulp.src(params.entryPoint) + .pipe(webpackStream(getWebpackConfig(params))); + + return tsResult + .pipe(concat(paths.mainJSfile)) + .pipe(insert.prepend(copyright)) + .pipe(gulp.dest(paths.dist)) + .pipe(gulp.dest(paths.jsFolder)) + .pipe(gulp.dest(paths.packageDist)); +}); + +gulp.task("typescript:tests", function () { + var params = webpack_params_test; + var tsResult = gulp.src(params.entryPoint) + .pipe(webpackStream(getWebpackConfig(params))); + + return tsResult + .pipe(concat('surveyeditor.tests.js')) + .pipe(sourcemaps.write({ sourceRoot: "tests" })) + //Source map is a part of generated file + .pipe(gulp.dest(paths.testsFolder)); +}); + +gulp.task('test:copy-index-html', function () { + return gulp.src('./tests/index.html') + // Perform minification tasks, etc here + .pipe(gulp.dest(paths.testsFolder)); +}); + +gulp.task("typescript", ["typescript:sources", "typescript:tests", "test:copy-index-html"]); + +gulp.task('compress', function () { + "use strict"; + return gulp.src(paths.dist + paths.mainJSfile) + .pipe(uglify()) + .pipe(rename({ + extname: '.min.js' + })) + .pipe(concat.header(copyright)) + .pipe(gulp.dest(paths.dist)) + .pipe(gulp.dest(paths.packageDist)); +}); + +gulp.task('sass', function () { + "use strict"; + return gulp.src(paths.styles) + .pipe(sass.sync().on('error', sass.logError)) + .pipe(concat("surveyeditor.css")) + .pipe(gulp.dest(paths.webroot + 'css')) + .pipe(gulp.dest(paths.dist + 'css')) + .pipe(gulp.dest(paths.packageDist)); +}); + +gulp.task('templates', function () { + "use strict"; + gulp.src(paths.template_page) + .pipe(html2ts()) + .pipe(insert.transform(function(contents, file) { + contents = contents.slice(0, -1); //remove last symbol '}' + return contents.replace('module template_page { ', ''); + })) + .pipe(gulp.dest("./src/")); + gulp.src(paths.template_question) + .pipe(html2ts()) + .pipe(insert.transform(function(contents, file) { + contents = contents.slice(0, -1); //remove last symbol '}' + return contents.replace('module template_question { ', ''); + })) + .pipe(gulp.dest("./src/")); + + return gulp.src(paths.templates_ko) + .pipe(concat("templateEditor.ko.html")) + .pipe(html2ts()) + .pipe(insert.transform(function(contents, file) { + contents = contents.slice(0, -1); //remove last symbol '}' + return contents.replace('module templateEditor.ko { ', ''); + })) + .pipe(gulp.dest("./src/")); +}); + +gulp.task("makedist", sequence("templates", ["typescript", "sass"], "compress", "createPackage", "updatesurveyjsversion")); gulp.task("test_ci", function (done) { new Server({ diff --git a/karma.conf.js b/karma.conf.js index 46239e37c5..64dcc404e6 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,7 +14,7 @@ module.exports = function (config) { files: [ "wwwroot/js/qunit.css", "wwwroot/js/knockout.js", - "wwwroot/js/survey.bootstrap.js", + "wwwroot/js/survey.ko.js", "wwwroot/js/surveyeditor.js", "wwwroot/tests/surveyeditor.tests.js", diff --git a/package.json b/package.json index b5f0f7f73b..c843c34d67 100644 --- a/package.json +++ b/package.json @@ -2,33 +2,40 @@ "version": "0.9.0", "name": "surveyjs.editor", "devDependencies": { - "qunit": "^0.9.1", - "rimraf": "^2.5.4", + "babel-core": "^6.17.0", + "babel-loader": "^6.2.5", + "babel-preset-es2015": "^6.16.0", + "babel-preset-react": "^6.16.0", "gulp": "^3.9.1", - "gulp-typescript": "^2.13.6", - "gulp-insert": "^0.5.0", "gulp-concat-util": "^0.5.5", "gulp-cssmin": "^0.1.7", - "gulp-uglify": "^2.0.0", + "gulp-html-to-ts": "^0.1.3", + "gulp-insert": "^0.5.0", + "gulp-json-transform": "^0.4.2", + "gulp-load-plugins": "^1.2.4", + "gulp-npm-files": "^0.1.3", + "gulp-qunit": "^1.4.0", "gulp-rename": "^1.2.2", + "gulp-sass": "^2.3.2", "gulp-sequence": "^0.4.5", + "gulp-serve": "^1.4.0", "gulp-sourcemaps": "^1.6.0", - "gulp-sass": "^2.3.2", - "gulp-qunit": "^1.4.0", - "gulp-load-plugins": "^1.2.4", - "gulp-html-to-ts": "^0.1.3", - "gulp-npm-files": "^0.1.3", - "gulp-json-transform": "^0.4.2", + "gulp-typescript": "^2.13.6", + "gulp-uglify": "^2.0.0", "karma": "^1.1.2", - "karma-qunit": "^1.1.0", - "karma-phantomjs-launcher": "^1.0.1", - "karma-junit-reporter": "^1.1.0", "karma-coverage": "^1.1.1", - "gulp-serve": "^1.4.0" + "karma-junit-reporter": "^1.1.0", + "karma-phantomjs-launcher": "^1.0.1", + "karma-qunit": "^1.1.0", + "qunit": "^0.9.1", + "rimraf": "^2.5.4", + "ts-loader": "^0.9.4", + "typescript": "^2.0.2", + "webpack-stream": "^3.2.0" }, "dependencies": { "knockout": "^3.4.0", "ace-builds": "^1.2.2", - "survey-knockout-bootstrap": "^0.9.12" + "survey-knockout": "^0.10.0" } } \ No newline at end of file diff --git a/src/dragdrophelper.ts b/src/dragdrophelper.ts index e82dfefdce..9e2a6edbac 100644 --- a/src/dragdrophelper.ts +++ b/src/dragdrophelper.ts @@ -1,144 +1,144 @@ -module SurveyEditor { - export class DragDropHelper { - static dataStart: string = "surveyjs,"; - static dragData: any = {text: "", json: null }; - static prevEvent = { question: null, x: -1, y: -1 }; - private onModifiedCallback: () => any; - constructor(public data: Survey.ISurvey, onModifiedCallback: () => any) { - this.onModifiedCallback = onModifiedCallback; - } - public get survey(): Survey.Survey { return this.data; } - public startDragNewQuestion(event: DragEvent, questionType: string, questionName: string) { - this.setData(event, DragDropHelper.dataStart + "questiontype:" + questionType + ",questionname:" + questionName); - } - public startDragQuestion(event: DragEvent, questionName: string) { - this.setData(event, DragDropHelper.dataStart + "questionname:" + questionName); - } - public startDragCopiedQuestion(event: DragEvent, questionName: string, questionJson: any) { - this.setData(event, DragDropHelper.dataStart + "questionname:" + questionName, questionJson); - } - public isSurveyDragging(event: DragEvent): boolean { - if (!event) return false; - var data = this.getData(event).text; - return data && data.indexOf(DragDropHelper.dataStart) == 0; - } - public doDragDropOver(event: DragEvent, question: Survey.QuestionBase) { - event = this.getEvent(event); - if (!question || !this.isSurveyDragging(event) || this.isSamePlace(event, question)) return; - var index = this.getQuestionIndex(event, question); - this.survey.currentPage["koDragging"](index); - } - public doDrop(event: DragEvent, question: Survey.QuestionBase = null) { - if (event.stopPropagation) { - event.stopPropagation(); - } - if (!this.isSurveyDragging(event)) return; - this.survey.currentPage["koDragging"](-1); - var index = this.getQuestionIndex(event, question); - var dataInfo = this.getDataInfo(event); - this.clearData(); - if (!dataInfo) return; - var targetQuestion = null; - var json = dataInfo["json"]; - if (json) { - targetQuestion = Survey.QuestionFactory.Instance.createQuestion(json["type"], name); - new Survey.JsonObject().toObject(json, targetQuestion); - targetQuestion.name = dataInfo["questionname"]; - } - if (!targetQuestion) { - targetQuestion = this.survey.getQuestionByName(dataInfo["questionname"]); - } - if (!targetQuestion && dataInfo["questiontype"]) { - targetQuestion = Survey.QuestionFactory.Instance.createQuestion(dataInfo["questiontype"], dataInfo["questionname"]); - } - if (!targetQuestion) return; - this.moveQuestionTo(targetQuestion, index); - } - private getQuestionIndex(event: DragEvent, question: Survey.QuestionBase) { - var page = this.survey.currentPage; - if (!question) return page.questions.length; - var index = page.questions.indexOf(question); - event = this.getEvent(event); - var height = event.currentTarget["clientHeight"]; - var y = event.offsetY; - if (event.hasOwnProperty('layerX')) { - y = event.layerY - event.currentTarget["offsetTop"]; - } - if (y > height / 2) index++ - return index; - } - private isSamePlace(event: DragEvent, question: Survey.QuestionBase): boolean { - var prev = DragDropHelper.prevEvent; - if (prev.question != question || Math.abs(event.clientX - prev.x) > 5 || Math.abs(event.clientY - prev.y) > 5) { - prev.question = question; - prev.x = event.clientX; - prev.y = event.clientY; - return false; - } - return true; - } - private getEvent(event: DragEvent): DragEvent { - return event["originalEvent"] ? event["originalEvent"] : event; - } - private moveQuestionTo(targetQuestion: Survey.QuestionBase, index: number) { - if (targetQuestion == null) return; - var page = this.survey.getPageByQuestion(targetQuestion); - if (page) { - page.removeQuestion(targetQuestion); - } - this.survey.currentPage.addQuestion(targetQuestion, index); - if (this.onModifiedCallback) this.onModifiedCallback(); - } - private getDataInfo(event: DragEvent): any { - var data = this.getData(event); - if (!data) return null; - var text = data.text.substr(DragDropHelper.dataStart.length); - var array = text.split(','); - var result = {json: null}; - for (var i = 0; i < array.length; i++) { - var item = array[i].split(':'); - result[item[0]] = item[1]; - } - result.json = data.json; - return result; - } - private getY(element: HTMLElement): number { - var result = 0; +import * as Survey from "survey-knockout-bootstrap"; - while (element) { - result += (element.offsetTop - element.scrollTop + element.clientTop); - element = element.offsetParent; - } - return result; +export class DragDropHelper { + static dataStart: string = "surveyjs,"; + static dragData: any = {text: "", json: null }; + static prevEvent = { question: null, x: -1, y: -1 }; + private onModifiedCallback: () => any; + constructor(public data: Survey.ISurvey, onModifiedCallback: () => any) { + this.onModifiedCallback = onModifiedCallback; + } + public get survey(): Survey.Survey { return this.data; } + public startDragNewQuestion(event: DragEvent, questionType: string, questionName: string) { + this.setData(event, DragDropHelper.dataStart + "questiontype:" + questionType + ",questionname:" + questionName); + } + public startDragQuestion(event: DragEvent, questionName: string) { + this.setData(event, DragDropHelper.dataStart + "questionname:" + questionName); + } + public startDragCopiedQuestion(event: DragEvent, questionName: string, questionJson: any) { + this.setData(event, DragDropHelper.dataStart + "questionname:" + questionName, questionJson); + } + public isSurveyDragging(event: DragEvent): boolean { + if (!event) return false; + var data = this.getData(event).text; + return data && data.indexOf(DragDropHelper.dataStart) == 0; + } + public doDragDropOver(event: DragEvent, question: Survey.QuestionBase) { + event = this.getEvent(event); + if (!question || !this.isSurveyDragging(event) || this.isSamePlace(event, question)) return; + var index = this.getQuestionIndex(event, question); + this.survey.currentPage["koDragging"](index); + } + public doDrop(event: DragEvent, question: Survey.QuestionBase = null) { + if (event.stopPropagation) { + event.stopPropagation(); + } + if (!this.isSurveyDragging(event)) return; + this.survey.currentPage["koDragging"](-1); + var index = this.getQuestionIndex(event, question); + var dataInfo = this.getDataInfo(event); + this.clearData(); + if (!dataInfo) return; + var targetQuestion = null; + var json = dataInfo["json"]; + if (json) { + targetQuestion = Survey.QuestionFactory.Instance.createQuestion(json["type"], name); + new Survey.JsonObject().toObject(json, targetQuestion); + targetQuestion.name = dataInfo["questionname"]; + } + if (!targetQuestion) { + targetQuestion = this.survey.getQuestionByName(dataInfo["questionname"]); + } + if (!targetQuestion && dataInfo["questiontype"]) { + targetQuestion = Survey.QuestionFactory.Instance.createQuestion(dataInfo["questiontype"], dataInfo["questionname"]); + } + if (!targetQuestion) return; + this.moveQuestionTo(targetQuestion, index); + } + private getQuestionIndex(event: DragEvent, question: Survey.QuestionBase) { + var page = this.survey.currentPage; + if (!question) return page.questions.length; + var index = page.questions.indexOf(question); + event = this.getEvent(event); + var height = event.currentTarget["clientHeight"]; + var y = event.offsetY; + if (event.hasOwnProperty('layerX')) { + y = event.layerY - event.currentTarget["offsetTop"]; + } + if (y > height / 2) index++ + return index; + } + private isSamePlace(event: DragEvent, question: Survey.QuestionBase): boolean { + var prev = DragDropHelper.prevEvent; + if (prev.question != question || Math.abs(event.clientX - prev.x) > 5 || Math.abs(event.clientY - prev.y) > 5) { + prev.question = question; + prev.x = event.clientX; + prev.y = event.clientY; + return false; + } + return true; + } + private getEvent(event: DragEvent): DragEvent { + return event["originalEvent"] ? event["originalEvent"] : event; + } + private moveQuestionTo(targetQuestion: Survey.QuestionBase, index: number) { + if (targetQuestion == null) return; + var page = this.survey.getPageByQuestion(targetQuestion); + if (page) { + page.removeQuestion(targetQuestion); + } + this.survey.currentPage.addQuestion(targetQuestion, index); + if (this.onModifiedCallback) this.onModifiedCallback(); + } + private getDataInfo(event: DragEvent): any { + var data = this.getData(event); + if (!data) return null; + var text = data.text.substr(DragDropHelper.dataStart.length); + var array = text.split(','); + var result = {json: null}; + for (var i = 0; i < array.length; i++) { + var item = array[i].split(':'); + result[item[0]] = item[1]; + } + result.json = data.json; + return result; + } + private getY(element: HTMLElement): number { + var result = 0; + + while (element) { + result += (element.offsetTop - element.scrollTop + element.clientTop); + element = element.offsetParent; } - private setData(event: DragEvent, text: string, json: any = null) { - if (event["originalEvent"]) { - event = event["originalEvent"]; - } - if (event.dataTransfer) { - event.dataTransfer.setData("Text", text); - event.dataTransfer.effectAllowed = "copy"; - } - DragDropHelper.dragData = { text: text, json: json }; + return result; + } + private setData(event: DragEvent, text: string, json: any = null) { + if (event["originalEvent"]) { + event = event["originalEvent"]; } - private getData(event: DragEvent): any { - if (event["originalEvent"]) { - event = event["originalEvent"]; - } - if (event.dataTransfer) { - var text = event.dataTransfer.getData("Text"); - if (text) { - DragDropHelper.dragData.text = text; - } - } - return DragDropHelper.dragData; + if (event.dataTransfer) { + event.dataTransfer.setData("Text", text); + event.dataTransfer.effectAllowed = "copy"; } - private clearData() { - DragDropHelper.dragData = {text: "", json: null}; - var prev = DragDropHelper.prevEvent; - prev.question = null; - prev.x = -1; - prev.y = -1; + DragDropHelper.dragData = { text: text, json: json }; + } + private getData(event: DragEvent): any { + if (event["originalEvent"]) { + event = event["originalEvent"]; + } + if (event.dataTransfer) { + var text = event.dataTransfer.getData("Text"); + if (text) { + DragDropHelper.dragData.text = text; + } } + return DragDropHelper.dragData; + } + private clearData() { + DragDropHelper.dragData = {text: "", json: null}; + var prev = DragDropHelper.prevEvent; + prev.question = null; + prev.x = -1; + prev.y = -1; } } \ No newline at end of file diff --git a/src/editor.ts b/src/editor.ts index a74220636c..8fd176e9c0 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,627 +1,631 @@ -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// +import {editorLocalization} from "./editorLocalization"; +import {SurveyObjectEditor} from "./objectEditor"; +import {SurveyPagesEditor} from "./pagesEditor"; +import {SurveyEmbedingWindow} from "./surveyEmbedingWindow"; +import {SurveyObjects} from "./surveyObjects"; +import {SurveyVerbs} from "./objectVerbs"; +import {SurveyTextWorker} from "./textWorker"; +import {SurveyUndoRedo, UndoRedoItem} from "./undoredo"; +import {SurveyHelper, ObjType} from "./surveyHelper"; +import {DragDropHelper} from "./dragdrophelper"; +import {SurveyJSON5} from "./json5"; +import {html as templateEditorHtml} from "./templateEditor.ko.html"; +import {html as templatePageHtml} from "./template_page.html"; +import {html as templateQuestionHtml} from "./template_question.html"; +import * as Survey from "survey-knockout-bootstrap"; -module SurveyEditor { - export class SurveyEditor { - public static updateTextTimeout: number = 1000; - public static defaultNewSurveyText: string = "{ pages: [ { name: 'page1'}] }"; - private renderedElement: HTMLElement; - private surveyjs: HTMLElement; - private surveyjsExample: HTMLElement; +export class SurveyEditor { + public static updateTextTimeout: number = 1000; + public static defaultNewSurveyText: string = "{ pages: [ { name: 'page1'}] }"; + private renderedElement: HTMLElement; + private surveyjs: HTMLElement; + private surveyjsExample: HTMLElement; - private jsonEditor: AceAjax.Editor; - private isProcessingImmediately: boolean; - private selectedObjectEditor: SurveyObjectEditor; - private pagesEditor: SurveyPagesEditor; - private surveyEmbeding: SurveyEmbedingWindow - private surveyObjects: SurveyObjects; - private surveyVerbs: SurveyVerbs; - private textWorker: SurveyTextWorker; - private undoRedo: SurveyUndoRedo; - private surveyValue: Survey.Survey; - private saveSurveyFuncValue: (no: number, onSaveCallback: (no: number, isSuccess: boolean) => void) => void; - private options: any; - private stateValue: string = ""; + private jsonEditor: AceAjax.Editor; + private isProcessingImmediately: boolean; + private selectedObjectEditor: SurveyObjectEditor; + private pagesEditor: SurveyPagesEditor; + private surveyEmbeding: SurveyEmbedingWindow; + private surveyObjects: SurveyObjects; + private surveyVerbs: SurveyVerbs; + private textWorker: SurveyTextWorker; + private undoRedo: SurveyUndoRedo; + private surveyValue: Survey.Survey; + private saveSurveyFuncValue: (no: number, onSaveCallback: (no: number, isSuccess: boolean) => void) => void; + private options: any; + private stateValue: string = ""; - public surveyId: string = null; - public surveyPostId: string = null; - public questionTypes: string[]; - public koCopiedQuestions: any; - public generateValidJSONChangedCallback: (generateValidJSON: boolean) => void; - public alwaySaveTextInPropertyEditors: boolean = false; - - koIsShowDesigner: any; - koViewType: any; - koCanDeleteObject: any; - koObjects: any; koSelectedObject: any; - koShowSaveButton: any; - koGenerateValidJSON: any; koShowOptions: any; koTestSurveyWidth: any; - selectDesignerClick: any; selectEditorClick: any; selectTestClick: any; selectEmbedClick: any; - generateValidJSONClick: any; generateReadableJSONClick: any; - doUndoClick: any; doRedoClick: any; - deleteObjectClick: any; - koState: any; - runSurveyClick: any; embedingSurveyClick: any; - saveButtonClick: any; - draggingQuestion: any; clickQuestion: any; - draggingCopiedQuestion: any; clickCopiedQuestion: any; + public surveyId: string = null; + public surveyPostId: string = null; + public questionTypes: string[]; + public koCopiedQuestions: any; + public generateValidJSONChangedCallback: (generateValidJSON: boolean) => void; + public alwaySaveTextInPropertyEditors: boolean = false; - constructor(renderedElement: any = null, options: any = null) { - this.options = options; - this.questionTypes = this.getQuestionTypes(); - this.koCopiedQuestions = ko.observableArray(); - this.koCanDeleteObject = ko.observable(false); + koIsShowDesigner: any; + koViewType: any; + koCanDeleteObject: any; + koObjects: any; koSelectedObject: any; + koShowSaveButton: any; + koGenerateValidJSON: any; koShowOptions: any; koTestSurveyWidth: any; + selectDesignerClick: any; selectEditorClick: any; selectTestClick: any; selectEmbedClick: any; + generateValidJSONClick: any; generateReadableJSONClick: any; + doUndoClick: any; doRedoClick: any; + deleteObjectClick: any; + koState: any; + runSurveyClick: any; embedingSurveyClick: any; + saveButtonClick: any; + draggingQuestion: any; clickQuestion: any; + draggingCopiedQuestion: any; clickCopiedQuestion: any; - var self = this; + constructor(renderedElement: any = null, options: any = null) { + this.options = options; + this.questionTypes = this.getQuestionTypes(); + this.koCopiedQuestions = ko.observableArray(); + this.koCanDeleteObject = ko.observable(false); - this.koState = ko.observable(); - this.koShowSaveButton = ko.observable(false); - this.koShowOptions = ko.observable(false); - this.koTestSurveyWidth = ko.observable("100%"); - this.saveButtonClick = function () { self.doSave(); }; - this.koObjects = ko.observableArray(); - this.koSelectedObject = ko.observable(); - this.koSelectedObject.subscribe(function (newValue) { self.selectedObjectChanged(newValue != null ? newValue.value : null); }); - this.koGenerateValidJSON = ko.observable(this.options && this.options.generateValidJSON); - this.koGenerateValidJSON.subscribe(function (newValue) { - if (!self.options) self.options = {}; - self.options.generateValidJSON = newValue; - if (self.generateValidJSONChangedCallback) self.generateValidJSONChangedCallback(newValue); - }); - this.surveyObjects = new SurveyObjects(this.koObjects, this.koSelectedObject); - this.undoRedo = new SurveyUndoRedo(); + var self = this; - this.surveyVerbs = new SurveyVerbs(function () { self.setModified(); }); + this.koState = ko.observable(); + this.koShowSaveButton = ko.observable(false); + this.koShowOptions = ko.observable(false); + this.koTestSurveyWidth = ko.observable("100%"); + this.saveButtonClick = function () { self.doSave(); }; + this.koObjects = ko.observableArray(); + this.koSelectedObject = ko.observable(); + this.koSelectedObject.subscribe(function (newValue) { self.selectedObjectChanged(newValue != null ? newValue.value : null); }); + this.koGenerateValidJSON = ko.observable(this.options && this.options.generateValidJSON); + this.koGenerateValidJSON.subscribe(function (newValue) { + if (!self.options) self.options = {}; + self.options.generateValidJSON = newValue; + if (self.generateValidJSONChangedCallback) self.generateValidJSONChangedCallback(newValue); + }); + this.surveyObjects = new SurveyObjects(this.koObjects, this.koSelectedObject); + this.undoRedo = new SurveyUndoRedo(); - this.selectedObjectEditor = new SurveyObjectEditor(this.options); - this.selectedObjectEditor.onPropertyValueChanged.add((sender, options) => { - self.onPropertyValueChanged(options.property, options.object, options.newValue); - }); - this.pagesEditor = new SurveyPagesEditor(() => { self.addPage(); }, (page: Survey.Page) => { self.surveyObjects.selectObject(page); }, - (indexFrom: number, indexTo: number) => { self.movePage(indexFrom, indexTo); }, (page: Survey.Page) => { self.deleteCurrentObject(); }); - this.surveyEmbeding = new SurveyEmbedingWindow(); + this.surveyVerbs = new SurveyVerbs(function () { self.setModified(); }); - this.koViewType = ko.observable("designer"); - this.koIsShowDesigner = ko.computed(function () { return self.koViewType() == "designer"; }); - this.selectDesignerClick = function () { self.showDesigner(); }; - this.selectEditorClick = function () { self.showJsonEditor(); }; - this.selectTestClick = function () { self.showTestSurvey(); }; - this.selectEmbedClick = function () { self.showEmbedEditor(); }; - this.generateValidJSONClick = function () { self.koGenerateValidJSON(true); } - this.generateReadableJSONClick = function () { self.koGenerateValidJSON(false); } - this.runSurveyClick = function () { self.showLiveSurvey(); }; - this.embedingSurveyClick = function () { self.showSurveyEmbeding(); }; - this.deleteObjectClick = function () { self.deleteCurrentObject(); }; - this.draggingQuestion = function (questionType, e) { self.doDraggingQuestion(questionType, e); } - this.clickQuestion = function (questionType) { self.doClickQuestion(questionType); } - this.draggingCopiedQuestion = function (item, e) { self.doDraggingCopiedQuestion(item.json, e); } - this.clickCopiedQuestion = function (item) { self.doClickCopiedQuestion(item.json); } + this.selectedObjectEditor = new SurveyObjectEditor(this.options); + this.selectedObjectEditor.onPropertyValueChanged.add((sender, options) => { + self.onPropertyValueChanged(options.property, options.object, options.newValue); + }); + this.pagesEditor = new SurveyPagesEditor(() => { self.addPage(); }, (page: Survey.Page) => { self.surveyObjects.selectObject(page); }, + (indexFrom: number, indexTo: number) => { self.movePage(indexFrom, indexTo); }, (page: Survey.Page) => { self.deleteCurrentObject(); }); + this.surveyEmbeding = new SurveyEmbedingWindow(); - this.doUndoClick = function () { self.doUndoRedo(self.undoRedo.undo()); }; - this.doRedoClick = function () { self.doUndoRedo(self.undoRedo.redo()); }; + this.koViewType = ko.observable("designer"); + this.koIsShowDesigner = ko.computed(function () { return self.koViewType() == "designer"; }); + this.selectDesignerClick = function () { self.showDesigner(); }; + this.selectEditorClick = function () { self.showJsonEditor(); }; + this.selectTestClick = function () { self.showTestSurvey(); }; + this.selectEmbedClick = function () { self.showEmbedEditor(); }; + this.generateValidJSONClick = function () { self.koGenerateValidJSON(true); }; + this.generateReadableJSONClick = function () { self.koGenerateValidJSON(false); }; + this.runSurveyClick = function () { self.showLiveSurvey(); }; + this.embedingSurveyClick = function () { self.showSurveyEmbeding(); }; + this.deleteObjectClick = function () { self.deleteCurrentObject(); }; + this.draggingQuestion = function (questionType, e) { self.doDraggingQuestion(questionType, e); }; + this.clickQuestion = function (questionType) { self.doClickQuestion(questionType); }; + this.draggingCopiedQuestion = function (item, e) { self.doDraggingCopiedQuestion(item.json, e); }; + this.clickCopiedQuestion = function (item) { self.doClickCopiedQuestion(item.json); }; - if (renderedElement) { - this.render(renderedElement); - } + this.doUndoClick = function () { self.doUndoRedo(self.undoRedo.undo()); }; + this.doRedoClick = function () { self.doUndoRedo(self.undoRedo.redo()); }; + + if (renderedElement) { + this.render(renderedElement); } - public get survey(): Survey.Survey { - return this.surveyValue; + } + public get survey(): Survey.Survey { + return this.surveyValue; + } + public render(element: any = null) { + var self = this; + if (element && typeof element == "string") { + element = document.getElementById(element); } - public render(element: any = null) { - var self = this; - if (element && typeof element == "string") { - element = document.getElementById(element); - } - if (element) { - this.renderedElement = element; - } - element = this.renderedElement; - if (!element) return; - element.innerHTML = templateEditor.ko.html; - self.applyBinding(); + if (element) { + this.renderedElement = element; } - public loadSurvey(surveyId: string) { - var self = this; - new Survey.dxSurveyService().loadSurvey(surveyId, function (success: boolean, result: string, response: any) { - if (success && result) { - self.text = JSON.stringify(result); - } - }); - } - public get text() { - if (this.koIsShowDesigner()) return this.getSurveyTextFromDesigner(); - return this.jsonEditor != null ? this.jsonEditor.getValue() : ""; - } - public set text(value: string) { - this.textWorker = new SurveyTextWorker(value); - if (this.textWorker.isJsonCorrect) { - this.initSurvey(new Survey.JsonObject().toJsonObject(this.textWorker.survey)); - this.showDesigner(); - this.setUndoRedoCurrentState(true); - } else { - this.setTextValue(value); - this.koViewType("editor"); + element = this.renderedElement; + if (!element) return; + element.innerHTML = templateEditorHtml; + self.applyBinding(); + } + public loadSurvey(surveyId: string) { + var self = this; + new Survey.dxSurveyService().loadSurvey(surveyId, function (success: boolean, result: string, response: any) { + if (success && result) { + self.text = JSON.stringify(result); } + }); + } + public get text() { + if (this.koIsShowDesigner()) return this.getSurveyTextFromDesigner(); + return this.jsonEditor != null ? this.jsonEditor.getValue() : ""; + } + public set text(value: string) { + this.textWorker = new SurveyTextWorker(value); + if (this.textWorker.isJsonCorrect) { + this.initSurvey(new Survey.JsonObject().toJsonObject(this.textWorker.survey)); + this.showDesigner(); + this.setUndoRedoCurrentState(true); + } else { + this.setTextValue(value); + this.koViewType("editor"); } - public get state(): string { return this.stateValue; } - protected setState(value: string) { - this.stateValue = value; - this.koState(this.state); - } - saveNo: number = 0; - protected doSave() { - this.setState("saving") - if (this.saveSurveyFunc) { - this.saveNo++; - var self = this; - this.saveSurveyFunc(this.saveNo, - function doSaveCallback(no: number, isSuccess: boolean) { - self.setState("saved"); - if (self.saveNo == no) { - if (isSuccess) self.setState("saved"); - //else TODO - } - }); - } + } + public get state(): string { return this.stateValue; } + protected setState(value: string) { + this.stateValue = value; + this.koState(this.state); + } + saveNo: number = 0; + protected doSave() { + this.setState("saving"); + if (this.saveSurveyFunc) { + this.saveNo++; + var self = this; + this.saveSurveyFunc(this.saveNo, + function doSaveCallback(no: number, isSuccess: boolean) { + self.setState("saved"); + if (self.saveNo == no) { + if (isSuccess) self.setState("saved"); + //else TODO + } + }); } - protected setModified() { - this.setState("modified"); - this.setUndoRedoCurrentState(); + } + protected setModified() { + this.setState("modified"); + this.setUndoRedoCurrentState(); + } + private setUndoRedoCurrentState(clearState: boolean = false) { + if (clearState) { + this.undoRedo.clear(); } - private setUndoRedoCurrentState(clearState: boolean = false) { - if (clearState) { - this.undoRedo.clear(); - } - var selObj = this.koSelectedObject() ? this.koSelectedObject().value : null; - this.undoRedo.setCurrent(this.surveyValue, selObj ? selObj.name : null); - } - public get saveSurveyFunc() { return this.saveSurveyFuncValue; } - public set saveSurveyFunc(value: any) { - this.saveSurveyFuncValue = value; - this.koShowSaveButton(value != null); - } - public get showOptions() { return this.koShowOptions(); } - public set showOptions(value: boolean) { this.koShowOptions(value); } - private setTextValue(value: string) { - this.isProcessingImmediately = true; - if (this.jsonEditor) { - this.jsonEditor.setValue(value); - this.jsonEditor.renderer.updateFull(true); + var selObj = this.koSelectedObject() ? this.koSelectedObject().value : null; + this.undoRedo.setCurrent(this.surveyValue, selObj ? selObj.name : null); + } + public get saveSurveyFunc() { return this.saveSurveyFuncValue; } + public set saveSurveyFunc(value: any) { + this.saveSurveyFuncValue = value; + this.koShowSaveButton(value != null); + } + public get showOptions() { return this.koShowOptions(); } + public set showOptions(value: boolean) { this.koShowOptions(value); } + private setTextValue(value: string) { + this.isProcessingImmediately = true; + if (this.jsonEditor) { + this.jsonEditor.setValue(value); + this.jsonEditor.renderer.updateFull(true); + } + this.processJson(value); + this.isProcessingImmediately = false; + } + public addPage() { + var name = SurveyHelper.getNewPageName(this.survey.pages); + var page = this.surveyValue.addNewPage(name); + this.addPageToUI(page); + this.setModified(); + } + public getLocString(str: string) { return editorLocalization.getString(str); } + protected getQuestionTypes(): string[] { + var allTypes = Survey.QuestionFactory.Instance.getAllTypes(); + if (!this.options || !this.options.questionTypes || !this.options.questionTypes.length) return allTypes; + var result = []; + for (var i = 0; i < this.options.questionTypes.length; i++) { + var questionType = this.options.questionTypes[i]; + if (allTypes.indexOf(questionType) > -1) { + result.push(questionType); } - this.processJson(value); - this.isProcessingImmediately = false; } - public addPage() { - var name = SurveyHelper.getNewPageName(this.survey.pages); - var page = this.surveyValue.addNewPage(name); - this.addPageToUI(page); - this.setModified(); - } - public getLocString(str: string) { return editorLocalization.getString(str); } - protected getQuestionTypes(): string[] { - var allTypes = Survey.QuestionFactory.Instance.getAllTypes(); - if (!this.options || !this.options.questionTypes || !this.options.questionTypes.length) return allTypes; - var result = []; - for (var i = 0; i < this.options.questionTypes.length; i++) { - var questionType = this.options.questionTypes[i]; - if (allTypes.indexOf(questionType) > -1) { - result.push(questionType); - } + return result; + } + private movePage(indexFrom: number, indexTo: number) { + var page = this.survey.pages[indexFrom]; + this.survey.pages.splice(indexFrom, 1); + this.survey.pages.splice(indexTo, 0, page); + this.pagesEditor.survey = this.survey; + this.surveyObjects.selectObject(page) + this.setModified(); + } + private addPageToUI(page: Survey.Page) { + this.pagesEditor.survey = this.surveyValue; + this.surveyObjects.addPage(page); + } + private onQuestionAdded(question: Survey.QuestionBase) { + var page = this.survey.getPageByQuestion(question); + this.surveyObjects.addQuestion(page, question); + this.survey.render(); + } + private onQuestionRemoved(question: Survey.QuestionBase) { + this.surveyObjects.removeObject(question); + this.survey.render(); + } + private onPropertyValueChanged(property: Survey.JsonObjectProperty, obj: any, newValue: any) { + var isDefault = property.isDefaultValue(newValue); + obj[property.name] = newValue; + if (property.name == "name") { + this.surveyObjects.nameChanged(obj); + if (SurveyHelper.getObjectType(obj) == ObjType.Page) { + this.pagesEditor.changeName(obj); } - return result; - } - private movePage(indexFrom: number, indexTo: number) { - var page = this.survey.pages[indexFrom]; - this.survey.pages.splice(indexFrom, 1); - this.survey.pages.splice(indexTo, 0, page); - this.pagesEditor.survey = this.survey; - this.surveyObjects.selectObject(page) - this.setModified(); } - private addPageToUI(page: Survey.Page) { - this.pagesEditor.survey = this.surveyValue; - this.surveyObjects.addPage(page); - } - private onQuestionAdded(question: Survey.QuestionBase) { - var page = this.survey.getPageByQuestion(question); - this.surveyObjects.addQuestion(page, question); - this.survey.render(); - } - private onQuestionRemoved(question: Survey.QuestionBase) { - this.surveyObjects.removeObject(question); - this.survey.render(); - } - private onPropertyValueChanged(property: Survey.JsonObjectProperty, obj: any, newValue: any) { - var isDefault = property.isDefaultValue(newValue); - obj[property.name] = newValue; - if (property.name == "name") { - this.surveyObjects.nameChanged(obj); - if (SurveyHelper.getObjectType(obj) == ObjType.Page) { - this.pagesEditor.changeName(obj); - } - } - this.setModified(); - this.survey.render(); - } - private doUndoRedo(item: UndoRedoItem) { - this.initSurvey(item.surveyJSON); - if (item.selectedObjName) { - var selObj = this.findObjByName(item.selectedObjName); - if (selObj) { - this.surveyObjects.selectObject(selObj); - } - } - this.setState(this.undoRedo.koCanUndo() ? "modified" : "saved"); - } - private findObjByName(name: string): Survey.Base { - var page = this.survey.getPageByName(name); - if (page) return page; - var question = this.survey.getQuestionByName(name); - if (question) return question; - return null; - } - private canSwitchViewType(newType: string): boolean { - if (newType && this.koViewType() == newType) return false; - if (this.koViewType() != "editor" || !this.textWorker) return true; - if (!this.textWorker.isJsonCorrect) { - alert(this.getLocString("ed.correctJSON")); - return false; + this.setModified(); + this.survey.render(); + } + private doUndoRedo(item: UndoRedoItem) { + this.initSurvey(item.surveyJSON); + if (item.selectedObjName) { + var selObj = this.findObjByName(item.selectedObjName); + if (selObj) { + this.surveyObjects.selectObject(selObj); } - this.initSurvey(new Survey.JsonObject().toJsonObject(this.textWorker.survey)); - return true; - } - private showDesigner() { - if (!this.canSwitchViewType("designer")) return; - this.koViewType("designer"); } - private showJsonEditor() { - if (this.koViewType() == "editor") return; - this.jsonEditor.setValue(this.getSurveyTextFromDesigner()); - this.jsonEditor.focus(); - this.koViewType("editor"); + this.setState(this.undoRedo.koCanUndo() ? "modified" : "saved"); + } + private findObjByName(name: string): Survey.Base { + var page = this.survey.getPageByName(name); + if (page) return page; + var question = this.survey.getQuestionByName(name); + if (question) return question; + return null; + } + private canSwitchViewType(newType: string): boolean { + if (newType && this.koViewType() == newType) return false; + if (this.koViewType() != "editor" || !this.textWorker) return true; + if (!this.textWorker.isJsonCorrect) { + alert(this.getLocString("ed.correctJSON")); + return false; + } + this.initSurvey(new Survey.JsonObject().toJsonObject(this.textWorker.survey)); + return true; + } + private showDesigner() { + if (!this.canSwitchViewType("designer")) return; + this.koViewType("designer"); + } + private showJsonEditor() { + if (this.koViewType() == "editor") return; + this.jsonEditor.setValue(this.getSurveyTextFromDesigner()); + this.jsonEditor.focus(); + this.koViewType("editor"); + } + private showTestSurvey() { + if (!this.canSwitchViewType(null)) return; + this.showLiveSurvey(); + this.koViewType("test"); + } + private showEmbedEditor() { + if (!this.canSwitchViewType("embed")) return; + this.showSurveyEmbeding(); + this.koViewType("embed"); + } + private getSurveyTextFromDesigner() { + var json = new Survey.JsonObject().toJsonObject(this.survey); + if (this.options && this.options.generateValidJSON) return JSON.stringify(json, null, 1); + return new SurveyJSON5().stringify(json, null, 1); + } + private selectedObjectChanged(obj: Survey.Base) { + var canDeleteObject = false; + this.selectedObjectEditor.selectedObject = obj; + this.surveyVerbs.obj = obj; + var objType = SurveyHelper.getObjectType(obj); + if (objType == ObjType.Page) { + this.survey.currentPage = obj; + canDeleteObject = this.survey.pages.length > 1; + } + if (objType == ObjType.Question) { + this.survey["setselectedQuestion"](obj); + canDeleteObject = true; + this.survey.currentPage = this.survey.getPageByQuestion(this.survey["selectedQuestionValue"]); + } else { + this.survey["setselectedQuestion"](null); + } + this.koCanDeleteObject(canDeleteObject); + } + private applyBinding() { + if (this.renderedElement == null) return; + ko.cleanNode(this.renderedElement); + ko.applyBindings(this, this.renderedElement); + this.surveyjs = document.getElementById("surveyjs"); + if (this.surveyjs) { + var self = this; + this.surveyjs.onkeydown = function (e) { + if (!e) return; + if (e.keyCode == 46) self.deleteQuestion(); + if (e.keyCode == 38 || e.keyCode == 40) { + self.selectQuestion(e.keyCode == 38); + } + }; } - private showTestSurvey() { - if (!this.canSwitchViewType(null)) return; - this.showLiveSurvey(); - this.koViewType("test"); - } - private showEmbedEditor() { - if (!this.canSwitchViewType("embed")) return; - this.showSurveyEmbeding(); - this.koViewType("embed"); - } - private getSurveyTextFromDesigner() { - var json = new Survey.JsonObject().toJsonObject(this.survey); - if (this.options && this.options.generateValidJSON) return JSON.stringify(json, null, 1); - return new SurveyJSON5().stringify(json, null, 1); - } - private selectedObjectChanged(obj: Survey.Base) { - var canDeleteObject = false; - this.selectedObjectEditor.selectedObject = obj; - this.surveyVerbs.obj = obj; - var objType = SurveyHelper.getObjectType(obj); - if (objType == ObjType.Page) { - this.survey.currentPage = obj; - canDeleteObject = this.survey.pages.length > 1; - } - if (objType == ObjType.Question) { - this.survey["setselectedQuestion"](obj); - canDeleteObject = true; - this.survey.currentPage = this.survey.getPageByQuestion(this.survey["selectedQuestionValue"]); - } else { - this.survey["setselectedQuestion"](null); - } - this.koCanDeleteObject(canDeleteObject); - } - private applyBinding() { - if (this.renderedElement == null) return; - ko.cleanNode(this.renderedElement); - ko.applyBindings(this, this.renderedElement); - this.surveyjs = document.getElementById("surveyjs"); - if (this.surveyjs) { - var self = this; - this.surveyjs.onkeydown = function (e) { - if (!e) return; - if (e.keyCode == 46) self.deleteQuestion(); - if (e.keyCode == 38 || e.keyCode == 40) { - self.selectQuestion(e.keyCode == 38); - } - }; - } - this.jsonEditor = ace.edit("surveyjsEditor"); - this.surveyjsExample = document.getElementById("surveyjsExample"); + this.jsonEditor = ace.edit("surveyjsEditor"); + this.surveyjsExample = document.getElementById("surveyjsExample"); - this.initSurvey(new SurveyJSON5().parse(SurveyEditor.defaultNewSurveyText)); - this.setUndoRedoCurrentState(true); - this.surveyValue.mode = "designer"; - this.surveyValue.render(this.surveyjs); + this.initSurvey(new SurveyJSON5().parse(SurveyEditor.defaultNewSurveyText)); + this.setUndoRedoCurrentState(true); + this.surveyValue.mode = "designer"; + this.surveyValue.render(this.surveyjs); - this.initJsonEditor(); - SurveyTextWorker.newLineChar = this.jsonEditor.session.doc.getNewLineCharacter(); + this.initJsonEditor(); + SurveyTextWorker.newLineChar = this.jsonEditor.session.doc.getNewLineCharacter(); + } + private initJsonEditor() { + var self = this; + this.jsonEditor.setTheme("ace/theme/monokai"); + this.jsonEditor.session.setMode("ace/mode/json"); + this.jsonEditor.setShowPrintMargin(false); + this.jsonEditor.getSession().on("change", function () { + self.onJsonEditorChanged(); + }); + this.jsonEditor.getSession().setUseWorker(true); + } + private initSurvey(json: any) { + this.surveyValue = new Survey.Survey(json); + if (this.surveyValue.isEmpty) { + this.surveyValue = new Survey.Survey(new SurveyJSON5().parse(SurveyEditor.defaultNewSurveyText)); + } + this.survey.mode = "designer"; + this.survey.render(this.surveyjs); + this.surveyObjects.survey = this.survey; + this.pagesEditor.survey = this.survey; + this.pagesEditor.setSelectedPage(this.survey.currentPage); + this.surveyVerbs.survey = this.survey; + var self = this; + this.surveyValue["onSelectedQuestionChanged"].add((sender: Survey.Survey, options) => { self.surveyObjects.selectObject(sender["selectedQuestionValue"]); }); + this.surveyValue["onCopyQuestion"].add((sender: Survey.Survey, options) => { self.copyQuestion(self.koSelectedObject().value); }); + this.surveyValue["onCreateDragDropHelper"] = function () { return self.createDragDropHelper() }; + this.surveyValue.onProcessHtml.add((sender: Survey.Survey, options) => { options.html = self.processHtml(options.html); }); + this.surveyValue.onCurrentPageChanged.add((sender: Survey.Survey, options) => { self.pagesEditor.setSelectedPage(sender.currentPage); }); + this.surveyValue.onQuestionAdded.add((sender: Survey.Survey, options) => { self.onQuestionAdded(options.question); }); + this.surveyValue.onQuestionRemoved.add((sender: Survey.Survey, options) => { self.onQuestionRemoved(options.question); }); + } + private processHtml(html: string): string { + if (!html) return html; + var scriptRegEx = /)<[^<]*)*<\/script>/gi; + while (scriptRegEx.test(html)) { + html = html.replace(scriptRegEx, ""); } - private initJsonEditor() { - var self = this; - this.jsonEditor.setTheme("ace/theme/monokai"); - this.jsonEditor.session.setMode("ace/mode/json"); - this.jsonEditor.setShowPrintMargin(false); - this.jsonEditor.getSession().on("change", function () { - self.onJsonEditorChanged(); - }); - this.jsonEditor.getSession().setUseWorker(true); - } - private initSurvey(json: any) { - this.surveyValue = new Survey.Survey(json); - if (this.surveyValue.isEmpty) { - this.surveyValue = new Survey.Survey(new SurveyJSON5().parse(SurveyEditor.defaultNewSurveyText)); - } - this.survey.mode = "designer"; - this.survey.render(this.surveyjs); - this.surveyObjects.survey = this.survey; - this.pagesEditor.survey = this.survey; - this.pagesEditor.setSelectedPage(this.survey.currentPage); - this.surveyVerbs.survey = this.survey; + return html; + } + private timeoutId: number = -1; + private onJsonEditorChanged(): any { + if (this.timeoutId > -1) { + clearTimeout(this.timeoutId); + } + if (this.isProcessingImmediately) { + this.timeoutId = -1; + } else { var self = this; - this.surveyValue["onSelectedQuestionChanged"].add((sender: Survey.Survey, options) => { self.surveyObjects.selectObject(sender["selectedQuestionValue"]); }); - this.surveyValue["onCopyQuestion"].add((sender: Survey.Survey, options) => { self.copyQuestion(self.koSelectedObject().value); }); - this.surveyValue["onCreateDragDropHelper"] = function () { return self.createDragDropHelper() }; - this.surveyValue.onProcessHtml.add((sender: Survey.Survey, options) => { options.html = self.processHtml(options.html); }); - this.surveyValue.onCurrentPageChanged.add((sender: Survey.Survey, options) => { self.pagesEditor.setSelectedPage(sender.currentPage); }); - this.surveyValue.onQuestionAdded.add((sender: Survey.Survey, options) => { self.onQuestionAdded(options.question); }); - this.surveyValue.onQuestionRemoved.add((sender: Survey.Survey, options) => { self.onQuestionRemoved(options.question); }); - } - private processHtml(html: string): string { - if (!html) return html; - var scriptRegEx = /)<[^<]*)*<\/script>/gi; - while (scriptRegEx.test(html)) { - html = html.replace(scriptRegEx, ""); - } - return html; - } - private timeoutId: number = -1; - private onJsonEditorChanged(): any { - if (this.timeoutId > -1) { - clearTimeout(this.timeoutId); - } - if (this.isProcessingImmediately) { - this.timeoutId = -1; - } else { - var self = this; - this.timeoutId = setTimeout(function () { - self.timeoutId = -1; - self.processJson(self.text); - }, SurveyEditor.updateTextTimeout); - } - } - private processJson(text: string): any { - this.textWorker = new SurveyTextWorker(text); - if (this.jsonEditor) { - this.jsonEditor.getSession().setAnnotations(this.createAnnotations(text, this.textWorker.errors)); - } + this.timeoutId = setTimeout(function () { + self.timeoutId = -1; + self.processJson(self.text); + }, SurveyEditor.updateTextTimeout); } - private doDraggingQuestion(questionType: any, e) { - this.createDragDropHelper().startDragNewQuestion(e, questionType, this.getNewQuestionName()); + } + private processJson(text: string): any { + this.textWorker = new SurveyTextWorker(text); + if (this.jsonEditor) { + this.jsonEditor.getSession().setAnnotations(this.createAnnotations(text, this.textWorker.errors)); } - private doDraggingCopiedQuestion(json: any, e) { - this.createDragDropHelper().startDragCopiedQuestion(e, this.getNewQuestionName(), json); + } + private doDraggingQuestion(questionType: any, e) { + this.createDragDropHelper().startDragNewQuestion(e, questionType, this.getNewQuestionName()); + } + private doDraggingCopiedQuestion(json: any, e) { + this.createDragDropHelper().startDragCopiedQuestion(e, this.getNewQuestionName(), json); + } + private createDragDropHelper(): DragDropHelper { + var self = this; + return new DragDropHelper(this.survey, function () { self.setModified() }); + } + private doClickQuestion(questionType: any) { + this.doClickQuestionCore(Survey.QuestionFactory.Instance.createQuestion(questionType, this.getNewQuestionName())); + } + private doClickCopiedQuestion(json: any) { + var name = this.getNewQuestionName(); + var question = Survey.QuestionFactory.Instance.createQuestion(json["type"], name); + new Survey.JsonObject().toObject(json, question); + question.name = name; + this.doClickQuestionCore(question); + } + private getNewQuestionName(): string { + return SurveyHelper.getNewQuestionName(this.survey.getAllQuestions()); + } + private doClickQuestionCore(question: Survey.QuestionBase) { + var page = this.survey.currentPage; + var index = -1; + if (this.survey["selectedQuestionValue"] != null) { + index = page.questions.indexOf(this.survey["selectedQuestionValue"]) + 1; + } + page.addQuestion(question, index); + this.setModified(); + } + private deleteQuestion() { + var question = this.getSelectedObjAsQuestion(); + if (question) { + this.deleteCurrentObject(); } - private createDragDropHelper(): DragDropHelper { - var self = this; - return new DragDropHelper(this.survey, function () { self.setModified() }); - } - private doClickQuestion(questionType: any) { - this.doClickQuestionCore(Survey.QuestionFactory.Instance.createQuestion(questionType, this.getNewQuestionName())); - } - private doClickCopiedQuestion(json: any) { - var name = this.getNewQuestionName(); - var question = Survey.QuestionFactory.Instance.createQuestion(json["type"], name); - new Survey.JsonObject().toObject(json, question); - question.name = name; - this.doClickQuestionCore(question); - } - private getNewQuestionName(): string { - return SurveyHelper.getNewQuestionName(this.survey.getAllQuestions()); - } - private doClickQuestionCore(question: Survey.QuestionBase) { - var page = this.survey.currentPage; - var index = -1; - if (this.survey["selectedQuestionValue"] != null) { - index = page.questions.indexOf(this.survey["selectedQuestionValue"]) + 1; - } - page.addQuestion(question, index); - this.setModified(); + } + private selectQuestion(isUp: boolean) { + var question = this.getSelectedObjAsQuestion(); + if (question) { + this.surveyObjects.selectNextQuestion(isUp) } - private deleteQuestion() { - var question = this.getSelectedObjAsQuestion(); - if (question) { - this.deleteCurrentObject(); - } + } + private getSelectedObjAsQuestion(): Survey.QuestionBase { + var obj = this.koSelectedObject().value; + if (!obj) return null; + return SurveyHelper.getObjectType(obj) == ObjType.Question ? (obj): null; + } + private deleteCurrentObject() { + this.deleteObject(this.koSelectedObject().value); + } + public copyQuestion(question: Survey.QuestionBase) { + var objType = SurveyHelper.getObjectType(question); + if (objType != ObjType.Question) return; + var json = new Survey.JsonObject().toJsonObject(question); + json.type = question.getType(); + var item = this.getCopiedQuestionByName(question.name); + if (item) { + item.json = json; + } else { + this.koCopiedQuestions.push({ name: question.name, json: json }); + } + if (this.koCopiedQuestions().length > 3) { + this.koCopiedQuestions.splice(0, 1); } - private selectQuestion(isUp: boolean) { - var question = this.getSelectedObjAsQuestion(); - if (question) { - this.surveyObjects.selectNextQuestion(isUp) - } + } + private getCopiedQuestionByName(name: string) { + var items = this.koCopiedQuestions(); + for (var i = 0; i < items.length; i++) { + if (items[i].name == name) return items[i]; } - private getSelectedObjAsQuestion(): Survey.QuestionBase { - var obj = this.koSelectedObject().value; - if (!obj) return null; - return SurveyHelper.getObjectType(obj) == ObjType.Question ? (obj): null; - } - private deleteCurrentObject() { - this.deleteObject(this.koSelectedObject().value); - } - public copyQuestion(question: Survey.QuestionBase) { - var objType = SurveyHelper.getObjectType(question); - if (objType != ObjType.Question) return; - var json = new Survey.JsonObject().toJsonObject(question); - json.type = question.getType(); - var item = this.getCopiedQuestionByName(question.name); - if (item) { - item.json = json; - } else { - this.koCopiedQuestions.push({ name: question.name, json: json }); - } - if (this.koCopiedQuestions().length > 3) { - this.koCopiedQuestions.splice(0, 1); - } + return null; + } + private deleteObject(obj: any) { + this.surveyObjects.removeObject(obj); + var objType = SurveyHelper.getObjectType(obj); + if (objType == ObjType.Page) { + this.survey.removePage(obj); + this.pagesEditor.removePage(obj); + this.setModified(); } - private getCopiedQuestionByName(name: string) { - var items = this.koCopiedQuestions(); - for (var i = 0; i < items.length; i++) { - if (items[i].name == name) return items[i]; - } - return null; - } - private deleteObject(obj: any) { - this.surveyObjects.removeObject(obj); - var objType = SurveyHelper.getObjectType(obj); - if (objType == ObjType.Page) { - this.survey.removePage(obj); - this.pagesEditor.removePage(obj); - this.setModified(); - } - if (objType == ObjType.Question) { - this.survey.currentPage.removeQuestion(obj); - this.survey["setselectedQuestion"](null); - this.surveyObjects.selectObject(this.survey.currentPage); - this.setModified(); - } - this.survey.render(); - } - private showLiveSurvey() { - if (!this.surveyjsExample) return; - var json = this.getSurveyJSON(); - if (json != null) { - if (json.cookieName) { - delete json.cookieName; - } - var survey = new Survey.Survey(json); - var self = this; - var surveyjsExampleResults = document.getElementById("surveyjsExampleResults"); - var surveyjsExamplereRun = document.getElementById("surveyjsExamplereRun"); - if (surveyjsExampleResults) surveyjsExampleResults.innerHTML = ""; - if (surveyjsExamplereRun) surveyjsExamplereRun.style.display = "none"; - survey.onComplete.add((sender: Survey.Survey) => { if (surveyjsExampleResults) surveyjsExampleResults.innerHTML = this.getLocString("ed.surveyResults") + JSON.stringify(survey.data); if (surveyjsExamplereRun) surveyjsExamplereRun.style.display = ""; }); - survey.render(this.surveyjsExample); - } else { - this.surveyjsExample.innerHTML = this.getLocString("ed.correctJSON"); - } + if (objType == ObjType.Question) { + this.survey.currentPage.removeQuestion(obj); + this.survey["setselectedQuestion"](null); + this.surveyObjects.selectObject(this.survey.currentPage); + this.setModified(); } - private showSurveyEmbeding() { - var json = this.getSurveyJSON(); - this.surveyEmbeding.json = json; - this.surveyEmbeding.surveyId = this.surveyId; - this.surveyEmbeding.surveyPostId = this.surveyPostId; - this.surveyEmbeding.generateValidJSON = this.options && this.options.generateValidJSON; - this.surveyEmbeding.show(); - } - private getSurveyJSON(): any { - if (this.koIsShowDesigner()) return new Survey.JsonObject().toJsonObject(this.survey); - if (this.textWorker.isJsonCorrect) return new Survey.JsonObject().toJsonObject(this.textWorker.survey); - return null; - } - private createAnnotations(text: string, errors: any[]): AceAjax.Annotation[] { - var annotations = new Array(); - for (var i = 0; i < errors.length; i++) { - var error = errors[i]; - var annotation: AceAjax.Annotation = { row: error.position.start.row, column: error.position.start.column, text: error.text, type: "error" }; - annotations.push(annotation); + this.survey.render(); + } + private showLiveSurvey() { + if (!this.surveyjsExample) return; + var json = this.getSurveyJSON(); + if (json != null) { + if (json.cookieName) { + delete json.cookieName; } - return annotations; + var survey = new Survey.Survey(json); + var self = this; + var surveyjsExampleResults = document.getElementById("surveyjsExampleResults"); + var surveyjsExamplereRun = document.getElementById("surveyjsExamplereRun"); + if (surveyjsExampleResults) surveyjsExampleResults.innerHTML = ""; + if (surveyjsExamplereRun) surveyjsExamplereRun.style.display = "none"; + survey.onComplete.add((sender: Survey.Survey) => { if (surveyjsExampleResults) surveyjsExampleResults.innerHTML = this.getLocString("ed.surveyResults") + JSON.stringify(survey.data); if (surveyjsExamplereRun) surveyjsExamplereRun.style.display = ""; }); + survey.render(this.surveyjsExample); + } else { + this.surveyjsExample.innerHTML = this.getLocString("ed.correctJSON"); } } - - new Survey.SurveyTemplateText().replaceText(template_page.html, "page"); - new Survey.SurveyTemplateText().replaceText(template_question.html, "question"); - - Survey.Survey.prototype["onCreating"] = function () { - this.selectedQuestionValue = null; - this.onSelectedQuestionChanged = new Survey.Event<(sender: Survey.Survey, options: any) => any, any>(); - this.onCopyQuestion = new Survey.Event<(sender: Survey.Survey, options: any) => any, any>(); - this.onCreateDragDropHelper = null; - var self = this; - this.copyQuestionClick = function () { self.onCopyQuestion.fire(self); }; + private showSurveyEmbeding() { + var json = this.getSurveyJSON(); + this.surveyEmbeding.json = json; + this.surveyEmbeding.surveyId = this.surveyId; + this.surveyEmbeding.surveyPostId = this.surveyPostId; + this.surveyEmbeding.generateValidJSON = this.options && this.options.generateValidJSON; + this.surveyEmbeding.show(); } - Survey.Survey.prototype["setselectedQuestion"] = function(value: Survey.QuestionBase) { - if (value == this.selectedQuestionValue) return; - var oldValue = this.selectedQuestionValue; - this.selectedQuestionValue = value; - if (oldValue != null) { - oldValue["onSelectedQuestionChanged"](); - } - if (this.selectedQuestionValue != null) { - this.selectedQuestionValue["onSelectedQuestionChanged"](); - } - this.onSelectedQuestionChanged.fire(this, { 'oldSelectedQuestion': oldValue, 'newSelectedQuestion': value }); - } - Survey.Survey.prototype["getEditorLocString"] = function (value: string): string { - return editorLocalization.getString(value); + private getSurveyJSON(): any { + if (this.koIsShowDesigner()) return new Survey.JsonObject().toJsonObject(this.survey); + if (this.textWorker.isJsonCorrect) return new Survey.JsonObject().toJsonObject(this.textWorker.survey); + return null; } - Survey.Page.prototype["onCreating"] = function () { - var self = this; - this.dragEnterCounter = 0; - this.koDragging = ko.observable(-1); - this.koDraggingQuestion = ko.observable(null); - this.koDraggingBottom = ko.observable(false); - this.koDragging.subscribe(function (newValue) { - if (newValue < 0) { - self.dragEnterCounter = 0; - self.koDraggingQuestion(null); - self.koDraggingBottom(false); - } - else { - var question = newValue >= 0 && newValue < self.questions.length ? self.questions[newValue] : null; - self.koDraggingQuestion(question); - self.koDraggingBottom(question == null); - } - }); - this.koDraggingQuestion.subscribe(function (newValue) { if (newValue) newValue.koIsDragging(true); }); - this.koDraggingQuestion.subscribe(function (oldValue) { if (oldValue) oldValue.koIsDragging(false); }, this, "beforeChange"); - this.dragEnter = function (e) { e.preventDefault(); self.dragEnterCounter++; self.doDragEnter(e); }; - this.dragLeave = function (e) { self.dragEnterCounter--; if (self.dragEnterCounter === 0) self.koDragging(-1); }; - this.dragDrop = function (e) { self.doDrop(e); }; + private createAnnotations(text: string, errors: any[]): AceAjax.Annotation[] { + var annotations = new Array(); + for (var i = 0; i < errors.length; i++) { + var error = errors[i]; + var annotation: AceAjax.Annotation = { row: error.position.start.row, column: error.position.start.column, text: error.text, type: "error" }; + annotations.push(annotation); + } + return annotations; } - Survey.Page.prototype["doDrop"] = function (e) { - var dragDropHelper = this.data["onCreateDragDropHelper"] ? this.data["onCreateDragDropHelper"]() : new DragDropHelper(this.data, null); - dragDropHelper.doDrop(e); +} + +new Survey.SurveyTemplateText().replaceText(templatePageHtml, "page"); +new Survey.SurveyTemplateText().replaceText(templateQuestionHtml, "question"); + +Survey.Survey.prototype["onCreating"] = function () { + this.selectedQuestionValue = null; + this.onSelectedQuestionChanged = new Survey.Event<(sender: Survey.Survey, options: any) => any, any>(); + this.onCopyQuestion = new Survey.Event<(sender: Survey.Survey, options: any) => any, any>(); + this.onCreateDragDropHelper = null; + var self = this; + this.copyQuestionClick = function () { self.onCopyQuestion.fire(self); }; +}; +Survey.Survey.prototype["setselectedQuestion"] = function(value: Survey.QuestionBase) { + if (value == this.selectedQuestionValue) return; + var oldValue = this.selectedQuestionValue; + this.selectedQuestionValue = value; + if (oldValue != null) { + oldValue["onSelectedQuestionChanged"](); } - Survey.Page.prototype["doDragEnter"] = function(e) { - if (this.questions.length > 0 || this.koDragging() > 0) return; - if (new DragDropHelper(this.data, null).isSurveyDragging(e)) { - this.koDragging(this.questions.length); - } + if (this.selectedQuestionValue != null) { + this.selectedQuestionValue["onSelectedQuestionChanged"](); } + this.onSelectedQuestionChanged.fire(this, { 'oldSelectedQuestion': oldValue, 'newSelectedQuestion': value }); +}; +Survey.Survey.prototype["getEditorLocString"] = function (value: string): string { + return editorLocalization.getString(value); +}; - Survey.QuestionBase.prototype["onCreating"] = function () { - var self = this; - this.dragDropHelperValue = null; - this.koIsDragging = ko.observable(false); - this.dragDropHelper = function () { - if (self.dragDropHelperValue == null) { - self.dragDropHelperValue = self.data["onCreateDragDropHelper"] ? self.data["onCreateDragDropHelper"]() : new DragDropHelper(self.data, null);; - } - return self.dragDropHelperValue; - } - this.dragOver = function (e) { self.dragDropHelper().doDragDropOver(e, self); } - this.dragDrop = function (e) { self.dragDropHelper().doDrop(e, self); } - this.dragStart = function (e) { self.dragDropHelper().startDragQuestion(e, self.name); } - this.koIsSelected = ko.observable(false); - this.koOnClick = function () { - if (self.data == null) return; - self.data["setselectedQuestion"](this); - } +Survey.Page.prototype["onCreating"] = function () { + var self = this; + this.dragEnterCounter = 0; + this.koDragging = ko.observable(-1); + this.koDraggingQuestion = ko.observable(null); + this.koDraggingBottom = ko.observable(false); + this.koDragging.subscribe(function (newValue) { + if (newValue < 0) { + self.dragEnterCounter = 0; + self.koDraggingQuestion(null); + self.koDraggingBottom(false); + } + else { + var question = newValue >= 0 && newValue < self.questions.length ? self.questions[newValue] : null; + self.koDraggingQuestion(question); + self.koDraggingBottom(question == null); + } + }); + this.koDraggingQuestion.subscribe(function (newValue) { if (newValue) newValue.koIsDragging(true); }); + this.koDraggingQuestion.subscribe(function (oldValue) { if (oldValue) oldValue.koIsDragging(false); }, this, "beforeChange"); + this.dragEnter = function (e) { e.preventDefault(); self.dragEnterCounter++; self.doDragEnter(e); }; + this.dragLeave = function (e) { self.dragEnterCounter--; if (self.dragEnterCounter === 0) self.koDragging(-1); }; + this.dragDrop = function (e) { self.doDrop(e); }; +}; +Survey.Page.prototype["doDrop"] = function (e) { + var dragDropHelper = this.data["onCreateDragDropHelper"] ? this.data["onCreateDragDropHelper"]() : new DragDropHelper(this.data, null); + dragDropHelper.doDrop(e); +}; +Survey.Page.prototype["doDragEnter"] = function(e) { + if (this.questions.length > 0 || this.koDragging() > 0) return; + if (new DragDropHelper(this.data, null).isSurveyDragging(e)) { + this.koDragging(this.questions.length); } - Survey.QuestionBase.prototype["onSelectedQuestionChanged"] = function() { - if (this.data == null) return; - this.koIsSelected(this.data["selectedQuestionValue"] == this); +}; + +Survey.QuestionBase.prototype["onCreating"] = function () { + var self = this; + this.dragDropHelperValue = null; + this.koIsDragging = ko.observable(false); + this.dragDropHelper = function () { + if (self.dragDropHelperValue == null) { + self.dragDropHelperValue = self.data["onCreateDragDropHelper"] ? self.data["onCreateDragDropHelper"]() : new DragDropHelper(self.data, null);; + } + return self.dragDropHelperValue; + }; + this.dragOver = function (e) { self.dragDropHelper().doDragDropOver(e, self); }; + this.dragDrop = function (e) { self.dragDropHelper().doDrop(e, self); }; + this.dragStart = function (e) { self.dragDropHelper().startDragQuestion(e, self.name); }; + this.koIsSelected = ko.observable(false); + this.koOnClick = function () { + if (self.data == null) return; + self.data["setselectedQuestion"](this); } -} +}; + +Survey.QuestionBase.prototype["onSelectedQuestionChanged"] = function() { + if (this.data == null) return; + this.koIsSelected(this.data["selectedQuestionValue"] == this); +}; diff --git a/src/editorLocalization.ts b/src/editorLocalization.ts index dc2b62fa21..ba9376519f 100644 --- a/src/editorLocalization.ts +++ b/src/editorLocalization.ts @@ -1,163 +1,163 @@ -module SurveyEditor { - export var editorLocalization = { - currentLocale: "", - locales: {}, - getString: function (strName: string, locale: string = null) { - if (!locale) locale = this.currentLocale; - var loc = locale ? this.locales[this.currentLocale] : defaultStrings; - if (!loc) loc = defaultStrings; - var path = strName.split('.'); - var obj = loc; - for (var i = 0; i < path.length; i++) { - obj = obj[path[i]]; - if (!obj) { - if (loc === defaultStrings) return path[i]; - return this.getString(strName, "en"); - } +export var editorLocalization = { + currentLocale: "", + locales: {}, + getString: function (strName: string, locale: string = null) { + if (!locale) locale = this.currentLocale; + var loc = locale ? this.locales[this.currentLocale] : defaultStrings; + if (!loc) loc = defaultStrings; + var path = strName.split('.'); + var obj = loc; + for (var i = 0; i < path.length; i++) { + obj = obj[path[i]]; + if (!obj) { + if (loc === defaultStrings) return path[i]; + return this.getString(strName, "en"); } - return obj; - }, - getPropertyName: function (strName: string, local: string = null) { - var obj = this.getProperty(strName, local); - if (obj["name"]) return obj["name"]; - return obj; - }, - getPropertyTitle: function (strName: string, local: string = null) { - var obj = this.getProperty(strName, local); - if (obj["title"]) return obj["title"]; - return ""; - }, - getProperty: function (strName: string, local: string = null) { - var obj = this.getString("p." + strName, local); - if (obj !== strName) return obj; - var pos = strName.indexOf('_'); - if (pos < -1) return obj; - strName = strName.substr(pos + 1); - return this.getString("p." + strName, local); - }, - getLocales: function (): Array { - var res = []; - res.push(""); - for (var key in this.locales) { - res.push(key); - } - return res; } - }; - export var defaultStrings = { - //survey templates - survey: { - dropQuestion: "Please drop a question here.", - copy: "Copy" - }, - //questionTypes - qt: { - checkbox: "Checkbox", - comment: "Comment", - dropdown: "Dropdown", - file: "File", - html: "Html", - matrix: "Matrix (single choice)", - matrixdropdown: "Matrix (multiple choice)", - matrixdynamic: "Matrix (dynamic rows)", - multipletext: "Multiple Text", - radiogroup: "Radiogroup", - rating: "Rating", - text: "Text" - }, - //Strings in Editor - ed: { - newPageName: "page", - newQuestionName: "question", - testSurvey: "Test Survey", - testSurveyAgain: "Test Survey Again", - testSurveyWidth: "Survey width: ", - embedSurvey: "Embed Survey", - saveSurvey: "Save Survey", - designer: "Designer", - jsonEditor: "JSON Editor", - undo: "Undo", - redo: "Redo", - options: "Options", - generateValidJSON: "Generate Valid JSON", - generateReadableJSON: "Generate Readable JSON", - toolbox: "Toolbox", - delSelObject: "Delete selected object", - correctJSON: "Please correct JSON.", - surveyResults: "Survey Result: " - }, - //Property Editors - pe: { - apply: "Apply", - reset: "Reset", - close: "Close", - delete: "Delete", - addNew: "Add New", - removeAll: "Remove All", - edit: "Edit", - empty: "", - testService: "Test the service", + return obj; + }, + getPropertyName: function (strName: string, local: string = null) { + var obj = this.getProperty(strName, local); + if (obj["name"]) return obj["name"]; + return obj; + }, + getPropertyTitle: function (strName: string, local: string = null) { + var obj = this.getProperty(strName, local); + if (obj["title"]) return obj["title"]; + return ""; + }, + getProperty: function (strName: string, local: string = null) { + var obj = this.getString("p." + strName, local); + if (obj !== strName) return obj; + var pos = strName.indexOf('_'); + if (pos < -1) return obj; + strName = strName.substr(pos + 1); + return this.getString("p." + strName, local); + }, + getLocales: function (): Array { + var res = []; + res.push(""); + for (var key in this.locales) { + res.push(key); + } + return res; + } +}; - value: "Value", - text: "Text", - required: "Required?", - hasOther: "Has Other Item", - name: "Name", - title: "Title", - cellType: "Cell Type", - colCount: "Column Count", +export var defaultStrings = { + //survey templates + survey: { + dropQuestion: "Please drop a question here.", + copy: "Copy" + }, + //questionTypes + qt: { + checkbox: "Checkbox", + comment: "Comment", + dropdown: "Dropdown", + file: "File", + html: "Html", + matrix: "Matrix (single choice)", + matrixdropdown: "Matrix (multiple choice)", + matrixdynamic: "Matrix (dynamic rows)", + multipletext: "Multiple Text", + radiogroup: "Radiogroup", + rating: "Rating", + text: "Text" + }, + //Strings in Editor + ed: { + newPageName: "page", + newQuestionName: "question", + testSurvey: "Test Survey", + testSurveyAgain: "Test Survey Again", + testSurveyWidth: "Survey width: ", + embedSurvey: "Embed Survey", + saveSurvey: "Save Survey", + designer: "Designer", + jsonEditor: "JSON Editor", + undo: "Undo", + redo: "Redo", + options: "Options", + generateValidJSON: "Generate Valid JSON", + generateReadableJSON: "Generate Readable JSON", + toolbox: "Toolbox", + delSelObject: "Delete selected object", + correctJSON: "Please correct JSON.", + surveyResults: "Survey Result: " + }, + //Property Editors + pe: { + apply: "Apply", + reset: "Reset", + close: "Close", + delete: "Delete", + addNew: "Add New", + removeAll: "Remove All", + edit: "Edit", + empty: "", + testService: "Test the service", - editProperty: "Edit property '{0}'", - items: "[ Items: {0} ]", + value: "Value", + text: "Text", + required: "Required?", + hasOther: "Has Other Item", + name: "Name", + title: "Title", + cellType: "Cell Type", + colCount: "Column Count", - enterNewValue: "Please, enter the value.", - noquestions: "There is no any question in the survey.", - createtrigger: "Please create a trigger", - triggerOn: "On ", - triggerMakePagesVisible: "Make pages visible:", - triggerMakeQuestionsVisible: "Make questions visible:", - triggerCompleteText: "Complete the survey if succeed.", - triggerNotSet: "The trigger is not set", - triggerRunIf: "Run if", - triggerSetToName: "Change value of: ", - triggerSetValue: "to: ", - triggerIsVariable: "Do not put the variable into the survey result.", - verbChangeType: "Change type ", - verbChangePage: "Change page " - }, - //Operators - op: { - empty: "is empty", - notempty: "is not empty", - equal: "equals", - notequal: "not equals", - contains: "contains", - notcontains: "not contains", - greater: "greater", - less: "less", - greaterorequal: "greater or equals", - lessorequal: "Less or Equals" - }, - //Embed window - ew: { - knockout: "Use Knockout version", - react: "Use React version", - bootstrap: "For bootstrap framework", - standard: "No bootstrap", - showOnPage: "Show survey on a page", - showInWindow: "Show survey in a window", - loadFromServer: "Load Survey JSON from server", - titleScript: "Scripts and styles", - titleHtml: "HTML", - titleJavaScript: "JavaScript" - }, - //Properties - p: { - name: "name", - title: { name: "title", title: "Leave it empty, if it is the same as 'Name'" }, - survey_title: { name: "title", title: "It will be shown on every page." }, - page_title: { name: "title", title: "Page title" } - } + editProperty: "Edit property '{0}'", + items: "[ Items: {0} ]", + + enterNewValue: "Please, enter the value.", + noquestions: "There is no any question in the survey.", + createtrigger: "Please create a trigger", + triggerOn: "On ", + triggerMakePagesVisible: "Make pages visible:", + triggerMakeQuestionsVisible: "Make questions visible:", + triggerCompleteText: "Complete the survey if succeed.", + triggerNotSet: "The trigger is not set", + triggerRunIf: "Run if", + triggerSetToName: "Change value of: ", + triggerSetValue: "to: ", + triggerIsVariable: "Do not put the variable into the survey result.", + verbChangeType: "Change type ", + verbChangePage: "Change page " + }, + //Operators + op: { + empty: "is empty", + notempty: "is not empty", + equal: "equals", + notequal: "not equals", + contains: "contains", + notcontains: "not contains", + greater: "greater", + less: "less", + greaterorequal: "greater or equals", + lessorequal: "Less or Equals" + }, + //Embed window + ew: { + knockout: "Use Knockout version", + react: "Use React version", + bootstrap: "For bootstrap framework", + standard: "No bootstrap", + showOnPage: "Show survey on a page", + showInWindow: "Show survey in a window", + loadFromServer: "Load Survey JSON from server", + titleScript: "Scripts and styles", + titleHtml: "HTML", + titleJavaScript: "JavaScript" + }, + //Properties + p: { + name: "name", + title: { name: "title", title: "Leave it empty, if it is the same as 'Name'" }, + survey_title: { name: "title", title: "It will be shown on every page." }, + page_title: { name: "title", title: "Page title" } } - editorLocalization.locales["en"] = defaultStrings; -} \ No newline at end of file +}; + +editorLocalization.locales["en"] = defaultStrings; \ No newline at end of file diff --git a/src/entries/index.ts b/src/entries/index.ts new file mode 100644 index 0000000000..ed886a7ef7 --- /dev/null +++ b/src/entries/index.ts @@ -0,0 +1,24 @@ +export {DragDropHelper} from "../dragdrophelper"; +export { + SurveyPropertyEditorBase, SurveyStringPropertyEditor, + SurveyDropdownPropertyEditor, SurveyBooleanPropertyEditor, SurveyNumberPropertyEditor +} from "../propertyEditors/propertyEditorBase"; +export {SurveyPropertyTextItemsEditor} from "../propertyEditors/propertyTextItemsEditor"; +export {SurveyPropertyItemsEditor} from "../propertyEditors/propertyItemsEditor"; +export {SurveyPropertyItemValuesEditor} from "../propertyEditors/propertyItemValuesEditor"; +export {SurveyPropertyDropdownColumnsEditor, SurveyPropertyMatrixDropdownColumnsItem} + from "../propertyEditors/propertyMatrixDropdownColumnsEditor"; +export {SurveyPropertyModalEditor} from "../propertyEditors/propertyModalEditor"; +export {SurveyPropertyResultfullEditor} from "../propertyEditors/propertyRestfullEditor"; +export {SurveyPropertyTriggersEditor} from "../propertyEditors/propertyTriggersEditor"; +export {SurveyPropertyValidatorsEditor} from "../propertyEditors/propertyValidatorsEditor"; + +export {SurveyObjectProperty} from "../objectProperty"; +export {SurveyObjectEditor} from "../objectEditor"; +export {SurveyPagesEditor} from "../pagesEditor"; +export {SurveyTextWorker} from "../textWorker"; +export {ObjType, SurveyHelper} from "../surveyHelper"; +export {SurveyEmbedingWindow} from "../surveyEmbedingWindow"; +export {SurveyVerbs, SurveyVerbItem, SurveyVerbChangeTypeItem, SurveyVerbChangePageItem} from "../objectVerbs"; +export {SurveyUndoRedo, UndoRedoItem} from "../undoredo"; +export {SurveyEditor} from "../editor"; \ No newline at end of file diff --git a/src/json5.ts b/src/json5.ts index dd7aa10dbb..6f98622f59 100644 --- a/src/json5.ts +++ b/src/json5.ts @@ -1,749 +1,747 @@ // This file is based on JSON5, http://json5.org/ // The modification for getting object and properties location 'at' were maden. -module SurveyEditor { - export class SurveyJSON5 { - public static positionName = "pos"; - private static escapee = { - "'": "'", - '"': '"', - '\\': '\\', - '/': '/', - '\n': '', // Replace escaped newlines in strings w/ empty string - b: '\b', - f: '\f', - n: '\n', - r: '\r', - t: '\t' - }; - private static ws = [ - ' ', - '\t', - '\r', - '\n', - '\v', - '\f', - '\xA0', - '\uFEFF' - ]; - private endAt: number; - private at: number; // The index of the current character - private ch: any; // The current character - private text: string; - private parseType: number; // 0 - stadard, 1 - get information about objects, 2 - get information about all properties - constructor(parseType: number = 0) { - this.parseType = parseType; - } - public parse(source: any, reviver: any = null, startFrom: number = 0, endAt: number = -1): any { - var result; - - this.text = String(source); - this.at = startFrom; - this.endAt = endAt; - this.ch = ' '; - result = this.value(); - this.white(); - if (this.ch) { - this.error("Syntax error"); - } +export class SurveyJSON5 { + public static positionName = "pos"; + private static escapee = { + "'": "'", + '"': '"', + '\\': '\\', + '/': '/', + '\n': '', // Replace escaped newlines in strings w/ empty string + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }; + private static ws = [ + ' ', + '\t', + '\r', + '\n', + '\v', + '\f', + '\xA0', + '\uFEFF' + ]; + private endAt: number; + private at: number; // The index of the current character + private ch: any; // The current character + private text: string; + private parseType: number; // 0 - stadard, 1 - get information about objects, 2 - get information about all properties + constructor(parseType: number = 0) { + this.parseType = parseType; + } + public parse(source: any, reviver: any = null, startFrom: number = 0, endAt: number = -1): any { + var result; + + this.text = String(source); + this.at = startFrom; + this.endAt = endAt; + this.ch = ' '; + result = this.value(); + this.white(); + if (this.ch) { + this.error("Syntax error"); + } - // If there is a reviver function, we recursively walk the new structure, - // passing each name/value pair to the reviver function for possible - // transformation, starting with a temporary root object that holds the result - // in an empty key. If there is not a reviver function, we simply return the - // result. - - return typeof reviver === 'function' ? (function walk(holder, key) { - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. + + return typeof reviver === 'function' ? (function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; } } } - return reviver.call(holder, key, value); - } ({ '': result }, '')) : result; - } - private error(m: string) { - // Call error when something is wrong. - var error = new SyntaxError(); - error.message = m; - error["at"] = this.at; - throw error; - } - private next(c: any = null) { - // If a c parameter is provided, verify that it matches the current character. - if (c && c !== this.ch) { - this.error("Expected '" + c + "' instead of '" + this.ch + "'"); - } - // Get the this.next character. When there are no more characters, - // return the empty string. - this.ch = this.chartAt(); - this.at += 1; - return this.ch; - } - private peek() { - // Get the this.next character without consuming it or - // assigning it to the this.ch varaible. - return this.chartAt(); - } - private chartAt() { - if (this.endAt > -1 && this.at >= this.endAt) return ''; - return this.text.charAt(this.at); - } - private identifier() { - // Parse an identifier. Normally, reserved words are disallowed here, but we - // only use this for unquoted object keys, where reserved words are allowed, - // so we don't check for those here. References: - // - http://es5.github.com/#x7.6 - // - https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables - // - http://docstore.mik.ua/orelly/webprog/jscript/ch02_07.htm - // TODO Identifiers can have Unicode "letters" in them; add support for those. - var key = this.ch; - - // Identifiers must start with a letter, _ or $. - if ((this.ch !== '_' && this.ch !== '$') && - (this.ch < 'a' || this.ch > 'z') && - (this.ch < 'A' || this.ch > 'Z')) { - this.error("Bad identifier"); - } - - // Subsequent characters can contain digits. - while (this.next() && ( - this.ch === '_' || this.ch === '$' || - (this.ch >= 'a' && this.ch <= 'z') || - (this.ch >= 'A' && this.ch <= 'Z') || - (this.ch >= '0' && this.ch <= '9'))) { - key += this.ch; } + return reviver.call(holder, key, value); + } ({ '': result }, '')) : result; + } + private error(m: string) { + // Call error when something is wrong. + var error = new SyntaxError(); + error.message = m; + error["at"] = this.at; + throw error; + } + private next(c: any = null) { + // If a c parameter is provided, verify that it matches the current character. + if (c && c !== this.ch) { + this.error("Expected '" + c + "' instead of '" + this.ch + "'"); + } + // Get the this.next character. When there are no more characters, + // return the empty string. + this.ch = this.chartAt(); + this.at += 1; + return this.ch; + } + private peek() { + // Get the this.next character without consuming it or + // assigning it to the this.ch varaible. + return this.chartAt(); + } + private chartAt() { + if (this.endAt > -1 && this.at >= this.endAt) return ''; + return this.text.charAt(this.at); + } + private identifier() { + // Parse an identifier. Normally, reserved words are disallowed here, but we + // only use this for unquoted object keys, where reserved words are allowed, + // so we don't check for those here. References: + // - http://es5.github.com/#x7.6 + // - https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables + // - http://docstore.mik.ua/orelly/webprog/jscript/ch02_07.htm + // TODO Identifiers can have Unicode "letters" in them; add support for those. + var key = this.ch; + + // Identifiers must start with a letter, _ or $. + if ((this.ch !== '_' && this.ch !== '$') && + (this.ch < 'a' || this.ch > 'z') && + (this.ch < 'A' || this.ch > 'Z')) { + this.error("Bad identifier"); + } - return key; + // Subsequent characters can contain digits. + while (this.next() && ( + this.ch === '_' || this.ch === '$' || + (this.ch >= 'a' && this.ch <= 'z') || + (this.ch >= 'A' && this.ch <= 'Z') || + (this.ch >= '0' && this.ch <= '9'))) { + key += this.ch; } - private number() { - // Parse a number value. + return key; + } + private number() { - var number, - sign = '', - string = '', - base = 10; + // Parse a number value. - if (this.ch === '-' || this.ch === '+') { - sign = this.ch; - this.next(this.ch); - } + var number, + sign = '', + string = '', + base = 10; - // support for Infinity (could tweak to allow other words): - if (this.ch === 'I') { - number = this.word(); - if (typeof number !== 'number' || isNaN(number)) { - this.error('Unexpected word for number'); - } - return (sign === '-') ? -number : number; + if (this.ch === '-' || this.ch === '+') { + sign = this.ch; + this.next(this.ch); + } + + // support for Infinity (could tweak to allow other words): + if (this.ch === 'I') { + number = this.word(); + if (typeof number !== 'number' || isNaN(number)) { + this.error('Unexpected word for number'); } + return (sign === '-') ? -number : number; + } - // support for NaN - if (this.ch === 'N') { - number = this.word(); - if (!isNaN(number)) { - this.error('expected word to be NaN'); - } - // ignore sign as -NaN also is NaN - return number; + // support for NaN + if (this.ch === 'N') { + number = this.word(); + if (!isNaN(number)) { + this.error('expected word to be NaN'); } + // ignore sign as -NaN also is NaN + return number; + } - if (this.ch === '0') { + if (this.ch === '0') { + string += this.ch; + this.next(); + if (this.ch === 'x' || this.ch === 'X') { string += this.ch; this.next(); - if (this.ch === 'x' || this.ch === 'X') { + base = 16; + } else if (this.ch >= '0' && this.ch <= '9') { + this.error('Octal literal'); + } + } + + switch (base) { + case 10: + while (this.ch >= '0' && this.ch <= '9') { string += this.ch; this.next(); - base = 16; - } else if (this.ch >= '0' && this.ch <= '9') { - this.error('Octal literal'); } - } - - switch (base) { - case 10: - while (this.ch >= '0' && this.ch <= '9') { + if (this.ch === '.') { + string += '.'; + while (this.next() && this.ch >= '0' && this.ch <= '9') { string += this.ch; - this.next(); } - if (this.ch === '.') { - string += '.'; - while (this.next() && this.ch >= '0' && this.ch <= '9') { - string += this.ch; - } - } - if (this.ch === 'e' || this.ch === 'E') { + } + if (this.ch === 'e' || this.ch === 'E') { + string += this.ch; + this.next(); + if (this.ch === '-' || this.ch === '+') { string += this.ch; this.next(); - if (this.ch === '-' || this.ch === '+') { - string += this.ch; - this.next(); - } - while (this.ch >= '0' && this.ch <= '9') { - string += this.ch; - this.next(); - } } - break; - case 16: - while (this.ch >= '0' && this.ch <= '9' || this.ch >= 'A' && this.ch <= 'F' || this.ch >= 'a' && this.ch <= 'f') { + while (this.ch >= '0' && this.ch <= '9') { string += this.ch; this.next(); } - break; - } + } + break; + case 16: + while (this.ch >= '0' && this.ch <= '9' || this.ch >= 'A' && this.ch <= 'F' || this.ch >= 'a' && this.ch <= 'f') { + string += this.ch; + this.next(); + } + break; + } - if (sign === '-') { - number = -string; - } else { - number = +string; - } + if (sign === '-') { + number = -string; + } else { + number = +string; + } - if (!isFinite(number)) { - this.error("Bad number"); - } else { - return number; - } + if (!isFinite(number)) { + this.error("Bad number"); + } else { + return number; } - private string() { + } + private string() { - // Parse a string value. + // Parse a string value. - var hex, - i, - string = '', - delim, // double quote or single quote - uffff; + var hex, + i, + string = '', + delim, // double quote or single quote + uffff; - // When parsing for string values, we must look for ' or " and \ characters. + // When parsing for string values, we must look for ' or " and \ characters. - if (this.ch === '"' || this.ch === "'") { - delim = this.ch; - while (this.next()) { - if (this.ch === delim) { - this.next(); - return string; - } else if (this.ch === '\\') { - this.next(); - if (this.ch === 'u') { - uffff = 0; - for (i = 0; i < 4; i += 1) { - hex = parseInt(this.next(), 16); - if (!isFinite(hex)) { - break; - } - uffff = uffff * 16 + hex; - } - string += String.fromCharCode(uffff); - } else if (this.ch === '\r') { - if (this.peek() === '\n') { - this.next(); + if (this.ch === '"' || this.ch === "'") { + delim = this.ch; + while (this.next()) { + if (this.ch === delim) { + this.next(); + return string; + } else if (this.ch === '\\') { + this.next(); + if (this.ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(this.next(), 16); + if (!isFinite(hex)) { + break; } - } else if (typeof SurveyJSON5.escapee[this.ch] === 'string') { - string += SurveyJSON5.escapee[this.ch]; - } else { - break; + uffff = uffff * 16 + hex; } - } else if (this.ch === '\n') { - // unescaped newlines are invalid; see: - // https://github.com/aseemk/json5/issues/24 - // TODO this feels special-cased; are there other - // invalid unescaped chars? - break; + string += String.fromCharCode(uffff); + } else if (this.ch === '\r') { + if (this.peek() === '\n') { + this.next(); + } + } else if (typeof SurveyJSON5.escapee[this.ch] === 'string') { + string += SurveyJSON5.escapee[this.ch]; } else { - string += this.ch; + break; } + } else if (this.ch === '\n') { + // unescaped newlines are invalid; see: + // https://github.com/aseemk/json5/issues/24 + // TODO this feels special-cased; are there other + // invalid unescaped chars? + break; + } else { + string += this.ch; } } - this.error("Bad string"); } - private inlineComment() { + this.error("Bad string"); + } + private inlineComment() { - // Skip an inline comment, assuming this is one. The current character should - // be the second / character in the // pair that begins this inline comment. - // To finish the inline comment, we look for a newline or the end of the text. + // Skip an inline comment, assuming this is one. The current character should + // be the second / character in the // pair that begins this inline comment. + // To finish the inline comment, we look for a newline or the end of the text. - if (this.ch !== '/') { - this.error("Not an inline comment"); - } + if (this.ch !== '/') { + this.error("Not an inline comment"); + } - do { + do { + this.next(); + if (this.ch === '\n' || this.ch === '\r') { this.next(); - if (this.ch === '\n' || this.ch === '\r') { - this.next(); - return; - } - } while (this.ch); - } - private blockComment() { + return; + } + } while (this.ch); + } + private blockComment() { - // Skip a block comment, assuming this is one. The current character should be - // the * character in the /* pair that begins this block comment. - // To finish the block comment, we look for an ending */ pair of characters, - // but we also watch for the end of text before the comment is terminated. + // Skip a block comment, assuming this is one. The current character should be + // the * character in the /* pair that begins this block comment. + // To finish the block comment, we look for an ending */ pair of characters, + // but we also watch for the end of text before the comment is terminated. - if (this.ch !== '*') { - this.error("Not a block comment"); - } + if (this.ch !== '*') { + this.error("Not a block comment"); + } - do { - this.next(); - while (this.ch === '*') { - this.next('*'); - if (this.ch === '/') { - this.next('/'); - return; - } + do { + this.next(); + while (this.ch === '*') { + this.next('*'); + if (this.ch === '/') { + this.next('/'); + return; } - } while (this.ch); + } + } while (this.ch); - this.error("Unterminated block comment"); + this.error("Unterminated block comment"); + } + private comment() { + + // Skip a comment, whether inline or block-level, assuming this is one. + // Comments always begin with a / character. + + if (this.ch !== '/') { + this.error("Not a comment"); } - private comment() { - // Skip a comment, whether inline or block-level, assuming this is one. - // Comments always begin with a / character. + this.next('/'); - if (this.ch !== '/') { - this.error("Not a comment"); - } + if (this.ch === '/') { + this.inlineComment(); + } else if (this.ch === '*') { + this.blockComment(); + } else { + this.error("Unrecognized comment"); + } + } + private white() { - this.next('/'); + // Skip whitespace and comments. + // Note that we're detecting comments by only a single / character. + // This works since regular expressions are not valid JSON(5), but this will + // break if there are other valid values that begin with a / character! + while (this.ch) { if (this.ch === '/') { - this.inlineComment(); - } else if (this.ch === '*') { - this.blockComment(); + this.comment(); + } else if (SurveyJSON5.ws.indexOf(this.ch) >= 0) { + this.next(); } else { - this.error("Unrecognized comment"); + return; } } - private white() { + } + private word(): any { + + // true, false, or null. + + switch (this.ch) { + case 't': + this.next('t'); + this.next('r'); + this.next('u'); + this.next('e'); + return true; + case 'f': + this.next('f'); + this.next('a'); + this.next('l'); + this.next('s'); + this.next('e'); + return false; + case 'n': + this.next('n'); + this.next('u'); + this.next('l'); + this.next('l'); + return null; + case 'I': + this.next('I'); + this.next('n'); + this.next('f'); + this.next('i'); + this.next('n'); + this.next('i'); + this.next('t'); + this.next('y'); + return Infinity; + case 'N': + this.next('N'); + this.next('a'); + this.next('N'); + return NaN; + } + this.error("Unexpected '" + this.ch + "'"); + } + private array() { - // Skip whitespace and comments. - // Note that we're detecting comments by only a single / character. - // This works since regular expressions are not valid JSON(5), but this will - // break if there are other valid values that begin with a / character! + // Parse an array value. + var array = []; + + if (this.ch === '[') { + this.next('['); + this.white(); while (this.ch) { - if (this.ch === '/') { - this.comment(); - } else if (SurveyJSON5.ws.indexOf(this.ch) >= 0) { - this.next(); + if (this.ch === ']') { + this.next(']'); + return array; // Potentially empty array + } + // ES5 allows omitting elements in arrays, e.g. [,] and + // [,null]. We don't allow this in JSON5. + if (this.ch === ',') { + this.error("Missing array element"); } else { - return; + array.push(this.value()); } - } - } - private word(): any { - - // true, false, or null. - - switch (this.ch) { - case 't': - this.next('t'); - this.next('r'); - this.next('u'); - this.next('e'); - return true; - case 'f': - this.next('f'); - this.next('a'); - this.next('l'); - this.next('s'); - this.next('e'); - return false; - case 'n': - this.next('n'); - this.next('u'); - this.next('l'); - this.next('l'); - return null; - case 'I': - this.next('I'); - this.next('n'); - this.next('f'); - this.next('i'); - this.next('n'); - this.next('i'); - this.next('t'); - this.next('y'); - return Infinity; - case 'N': - this.next('N'); - this.next('a'); - this.next('N'); - return NaN; - } - this.error("Unexpected '" + this.ch + "'"); - } - private array() { - - // Parse an array value. - - var array = []; - - if (this.ch === '[') { - this.next('['); this.white(); - while (this.ch) { - if (this.ch === ']') { - this.next(']'); - return array; // Potentially empty array - } - // ES5 allows omitting elements in arrays, e.g. [,] and - // [,null]. We don't allow this in JSON5. - if (this.ch === ',') { - this.error("Missing array element"); - } else { - array.push(this.value()); - } - this.white(); - // If there's no comma after this value, this needs to - // be the end of the array. - if (this.ch !== ',') { - this.next(']'); - return array; - } - this.next(','); - this.white(); + // If there's no comma after this value, this needs to + // be the end of the array. + if (this.ch !== ',') { + this.next(']'); + return array; } + this.next(','); + this.white(); } - this.error("Bad array"); } - private object() { + this.error("Bad array"); + } + private object() { - // Parse an object value. + // Parse an object value. - var key, - start, - isFirstProperty = true, - object = {}; - if (this.parseType > 0) { - object[SurveyJSON5.positionName] = { start: this.at - 1 }; - } - if (this.ch === '{') { - this.next('{'); - this.white(); - start = this.at - 1; - while (this.ch) { - if (this.ch === '}') { - if (this.parseType > 0) { - object[SurveyJSON5.positionName].end = start; - } - this.next('}'); - return object; // Potentially empty object + var key, + start, + isFirstProperty = true, + object = {}; + if (this.parseType > 0) { + object[SurveyJSON5.positionName] = { start: this.at - 1 }; + } + if (this.ch === '{') { + this.next('{'); + this.white(); + start = this.at - 1; + while (this.ch) { + if (this.ch === '}') { + if (this.parseType > 0) { + object[SurveyJSON5.positionName].end = start; } + this.next('}'); + return object; // Potentially empty object + } - // Keys can be unquoted. If they are, they need to be - // valid JS identifiers. - if (this.ch === '"' || this.ch === "'") { - key = this.string(); - } else { - key = this.identifier(); - } + // Keys can be unquoted. If they are, they need to be + // valid JS identifiers. + if (this.ch === '"' || this.ch === "'") { + key = this.string(); + } else { + key = this.identifier(); + } - this.white(); - if (this.parseType > 1) { - object[SurveyJSON5.positionName][key] = { start: start, valueStart: this.at }; - } - this.next(':'); - object[key] = this.value(); + this.white(); + if (this.parseType > 1) { + object[SurveyJSON5.positionName][key] = { start: start, valueStart: this.at }; + } + this.next(':'); + object[key] = this.value(); + if (this.parseType > 1) { + start = this.at - 1; + object[SurveyJSON5.positionName][key].valueEnd = start; + object[SurveyJSON5.positionName][key].end = start; + } + this.white(); + // If there's no comma after this pair, this needs to be + // the end of the object. + if (this.ch !== ',') { if (this.parseType > 1) { - start = this.at - 1; - object[SurveyJSON5.positionName][key].valueEnd = start; - object[SurveyJSON5.positionName][key].end = start; + object[SurveyJSON5.positionName][key].valueEnd--; + object[SurveyJSON5.positionName][key].end--; } - this.white(); - // If there's no comma after this pair, this needs to be - // the end of the object. - if (this.ch !== ',') { - if (this.parseType > 1) { - object[SurveyJSON5.positionName][key].valueEnd--; - object[SurveyJSON5.positionName][key].end--; - } - if (this.parseType > 0) { - object[SurveyJSON5.positionName].end = this.at - 1; - } - this.next('}'); - return object; + if (this.parseType > 0) { + object[SurveyJSON5.positionName].end = this.at - 1; } - if (this.parseType > 1) { - object[SurveyJSON5.positionName][key].valueEnd--; - if (!isFirstProperty) { - object[SurveyJSON5.positionName][key].end--; - } + this.next('}'); + return object; + } + if (this.parseType > 1) { + object[SurveyJSON5.positionName][key].valueEnd--; + if (!isFirstProperty) { + object[SurveyJSON5.positionName][key].end--; } - this.next(','); - this.white(); - isFirstProperty = false; } + this.next(','); + this.white(); + isFirstProperty = false; } - this.error("Bad object"); } - private value(): any { - - // Parse a JSON value. It could be an object, an array, a string, a number, - // or a word. - - this.white(); - switch (this.ch) { - case '{': - return this.object(); - case '[': - return this.array(); - case '"': - case "'": - return this.string(); - case '-': - case '+': - case '.': - return this.number(); - default: - return this.ch >= '0' && this.ch <= '9' ? this.number() : this.word(); - } + this.error("Bad object"); + } + private value(): any { + + // Parse a JSON value. It could be an object, an array, a string, a number, + // or a word. + + this.white(); + switch (this.ch) { + case '{': + return this.object(); + case '[': + return this.array(); + case '"': + case "'": + return this.string(); + case '-': + case '+': + case '.': + return this.number(); + default: + return this.ch >= '0' && this.ch <= '9' ? this.number() : this.word(); } + } - private replacer: any; - private indentStr: string; - private objStack; + private replacer: any; + private indentStr: string; + private objStack; - public stringify(obj: any, replacer: any = null, space: any = null) { - if (replacer && (typeof (replacer) !== "function" && !this.isArray(replacer))) { - throw new Error('Replacer must be a function or an array'); - } - this.replacer = replacer; - this.indentStr = this.getIndent(space); - this.objStack = []; - // special case...when undefined is used inside of - // a compound object/array, return null. - // but when top-level, return undefined - var topLevelHolder = { "": obj }; - if (obj === undefined) { - return this.getReplacedValueOrUndefined(topLevelHolder, '', true); - } - return this.internalStringify(topLevelHolder, '', true); - } - private getIndent(space: any): string { - if (space) { - if (typeof space === "string") { - return space; - } else if (typeof space === "number" && space >= 0) { - return this.makeIndent(" ", space, true); - } + public stringify(obj: any, replacer: any = null, space: any = null) { + if (replacer && (typeof (replacer) !== "function" && !this.isArray(replacer))) { + throw new Error('Replacer must be a function or an array'); + } + this.replacer = replacer; + this.indentStr = this.getIndent(space); + this.objStack = []; + // special case...when undefined is used inside of + // a compound object/array, return null. + // but when top-level, return undefined + var topLevelHolder = { "": obj }; + if (obj === undefined) { + return this.getReplacedValueOrUndefined(topLevelHolder, '', true); + } + return this.internalStringify(topLevelHolder, '', true); + } + private getIndent(space: any): string { + if (space) { + if (typeof space === "string") { + return space; + } else if (typeof space === "number" && space >= 0) { + return this.makeIndent(" ", space, true); } - return ""; } - private getReplacedValueOrUndefined(holder: any, key: any, isTopLevel: boolean) { - var value = holder[key]; + return ""; + } + private getReplacedValueOrUndefined(holder: any, key: any, isTopLevel: boolean) { + var value = holder[key]; - // Replace the value with its toJSON value first, if possible - if (value && value.toJSON && typeof value.toJSON === "function") { - value = value.toJSON(); - } + // Replace the value with its toJSON value first, if possible + if (value && value.toJSON && typeof value.toJSON === "function") { + value = value.toJSON(); + } - // If the user-supplied replacer if a function, call it. If it's an array, check objects' string keys for - // presence in the array (removing the key/value pair from the resulting JSON if the key is missing). - if (typeof (this.replacer) === "function") { - return this.replacer.call(holder, key, value); - } else if (this.replacer) { - if (isTopLevel || this.isArray(holder) || this.replacer.indexOf(key) >= 0) { - return value; - } else { - return undefined; - } - } else { + // If the user-supplied replacer if a function, call it. If it's an array, check objects' string keys for + // presence in the array (removing the key/value pair from the resulting JSON if the key is missing). + if (typeof (this.replacer) === "function") { + return this.replacer.call(holder, key, value); + } else if (this.replacer) { + if (isTopLevel || this.isArray(holder) || this.replacer.indexOf(key) >= 0) { return value; + } else { + return undefined; } + } else { + return value; } + } - private isWordChar(char: any): boolean { - return (char >= 'a' && char <= 'z') || - (char >= 'A' && char <= 'Z') || - (char >= '0' && char <= '9') || - char === '_' || char === '$'; - } + private isWordChar(char: any): boolean { + return (char >= 'a' && char <= 'z') || + (char >= 'A' && char <= 'Z') || + (char >= '0' && char <= '9') || + char === '_' || char === '$'; + } - private isWordStart(char: any): boolean { - return (char >= 'a' && char <= 'z') || - (char >= 'A' && char <= 'Z') || - char === '_' || char === '$'; - } + private isWordStart(char: any): boolean { + return (char >= 'a' && char <= 'z') || + (char >= 'A' && char <= 'Z') || + char === '_' || char === '$'; + } - private isWord(key: any): boolean { - if (typeof key !== 'string') { - return false; - } - if (!this.isWordStart(key[0])) { + private isWord(key: any): boolean { + if (typeof key !== 'string') { + return false; + } + if (!this.isWordStart(key[0])) { + return false; + } + var i = 1, length = key.length; + while (i < length) { + if (!this.isWordChar(key[i])) { return false; } - var i = 1, length = key.length; - while (i < length) { - if (!this.isWordChar(key[i])) { - return false; - } - i++; - } - return true; + i++; } - // polyfills - private isArray(obj: any): boolean { - if (Array.isArray) { - return Array.isArray(obj); - } else { - return Object.prototype.toString.call(obj) === '[object Array]'; - } + return true; + } + // polyfills + private isArray(obj: any): boolean { + if (Array.isArray) { + return Array.isArray(obj); + } else { + return Object.prototype.toString.call(obj) === '[object Array]'; } + } - private isDate(obj: any): boolean { - return Object.prototype.toString.call(obj) === '[object Date]'; - } + private isDate(obj: any): boolean { + return Object.prototype.toString.call(obj) === '[object Date]'; + } - private isNaN(val: any): boolean { - return typeof val === 'number' && val !== val; - } - - private checkForCircular(obj: any) { - for (var i = 0; i < this.objStack.length; i++) { - if (this.objStack[i] === obj) { - throw new TypeError("Converting circular structure to JSON"); - } + private isNaN(val: any): boolean { + return typeof val === 'number' && val !== val; + } + + private checkForCircular(obj: any) { + for (var i = 0; i < this.objStack.length; i++) { + if (this.objStack[i] === obj) { + throw new TypeError("Converting circular structure to JSON"); } } - private makeIndent(str: string, num: number, noNewLine: boolean = false) { - if (!str) { - return ""; - } - // indentation no more than 10 chars - if (str.length > 10) { - str = str.substring(0, 10); - } + } + private makeIndent(str: string, num: number, noNewLine: boolean = false) { + if (!str) { + return ""; + } + // indentation no more than 10 chars + if (str.length > 10) { + str = str.substring(0, 10); + } - var indent = noNewLine ? "" : "\n"; - for (var i = 0; i < num; i++) { - indent += str; - } + var indent = noNewLine ? "" : "\n"; + for (var i = 0; i < num; i++) { + indent += str; + } - return indent; - } - - // Copied from Crokford's implementation of JSON - // See https://github.com/douglascrockford/JSON-js/blob/e39db4b7e6249f04a195e7dd0840e610cc9e941e/json2.js#L195 - // Begin - private static cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - private static escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - private static meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"': '\\"', - '\\': '\\\\' - }; - private escapeString(str: string) { - - // If the string contains no control characters, no quote characters, and no - // backslash characters, then we can safely slap some quotes around it. - // Otherwise we must also replace the offending characters with safe escape - // sequences. - SurveyJSON5.escapable.lastIndex = 0; - return SurveyJSON5.escapable.test(str) ? '"' + str.replace(SurveyJSON5.escapable, function (a) { - var c = SurveyJSON5.meta[a]; - return typeof c === 'string' ? - c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : '"' + str + '"'; - } - // End - - private internalStringify(holder: any, key: any, isTopLevel: boolean) { - var buffer, res; - - // Replace the value, if necessary - var obj_part = this.getReplacedValueOrUndefined(holder, key, isTopLevel); - - if (obj_part && !this.isDate(obj_part)) { - // unbox objects - // don't unbox dates, since will turn it into number - obj_part = obj_part.valueOf(); - } - switch (typeof obj_part) { - case "boolean": - return obj_part.toString(); + return indent; + } + + // Copied from Crokford's implementation of JSON + // See https://github.com/douglascrockford/JSON-js/blob/e39db4b7e6249f04a195e7dd0840e610cc9e941e/json2.js#L195 + // Begin + private static cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + private static escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + private static meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"': '\\"', + '\\': '\\\\' + }; + private escapeString(str: string) { + + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + SurveyJSON5.escapable.lastIndex = 0; + return SurveyJSON5.escapable.test(str) ? '"' + str.replace(SurveyJSON5.escapable, function (a) { + var c = SurveyJSON5.meta[a]; + return typeof c === 'string' ? + c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + str + '"'; + } + // End + + private internalStringify(holder: any, key: any, isTopLevel: boolean) { + var buffer, res; + + // Replace the value, if necessary + var obj_part = this.getReplacedValueOrUndefined(holder, key, isTopLevel); + + if (obj_part && !this.isDate(obj_part)) { + // unbox objects + // don't unbox dates, since will turn it into number + obj_part = obj_part.valueOf(); + } + switch (typeof obj_part) { + case "boolean": + return obj_part.toString(); - case "number": - if (isNaN(obj_part) || !isFinite(obj_part)) { - return "null"; + case "number": + if (isNaN(obj_part) || !isFinite(obj_part)) { + return "null"; + } + return obj_part.toString(); + + case "string": + return this.escapeString(obj_part.toString()); + + case "object": + if (obj_part === null) { + return "null"; + } else if (this.isArray(obj_part)) { + this.checkForCircular(obj_part); + buffer = "["; + this.objStack.push(obj_part); + + for (var i = 0; i < obj_part.length; i++) { + res = this.internalStringify(obj_part, i, false); + buffer += this.makeIndent(this.indentStr, this.objStack.length); + if (res === null || typeof res === "undefined") { + buffer += "null"; + } else { + buffer += res; + } + if (i < obj_part.length - 1) { + buffer += ","; + } else if (this.indentStr) { + buffer += "\n"; + } } - return obj_part.toString(); - - case "string": - return this.escapeString(obj_part.toString()); - - case "object": - if (obj_part === null) { - return "null"; - } else if (this.isArray(obj_part)) { - this.checkForCircular(obj_part); - buffer = "["; - this.objStack.push(obj_part); - - for (var i = 0; i < obj_part.length; i++) { - res = this.internalStringify(obj_part, i, false); - buffer += this.makeIndent(this.indentStr, this.objStack.length); - if (res === null || typeof res === "undefined") { - buffer += "null"; - } else { - buffer += res; - } - if (i < obj_part.length - 1) { - buffer += ","; - } else if (this.indentStr) { - buffer += "\n"; + this.objStack.pop(); + buffer += this.makeIndent(this.indentStr, this.objStack.length, true) + "]"; + } else { + this.checkForCircular(obj_part); + buffer = "{"; + var nonEmpty = false; + this.objStack.push(obj_part); + for (var prop in obj_part) { + if (obj_part.hasOwnProperty(prop)) { + var value = this.internalStringify(obj_part, prop, false); + isTopLevel = false; + if (typeof value !== "undefined" && value !== null) { + buffer += this.makeIndent(this.indentStr, this.objStack.length); + nonEmpty = true; + var propKey = this.isWord(prop) ? prop : this.escapeString(prop); + buffer += propKey + ":" + (this.indentStr ? ' ' : '') + value + ","; } } - this.objStack.pop(); - buffer += this.makeIndent(this.indentStr, this.objStack.length, true) + "]"; + } + this.objStack.pop(); + if (nonEmpty) { + buffer = buffer.substring(0, buffer.length - 1) + this.makeIndent(this.indentStr, this.objStack.length) + "}"; } else { - this.checkForCircular(obj_part); - buffer = "{"; - var nonEmpty = false; - this.objStack.push(obj_part); - for (var prop in obj_part) { - if (obj_part.hasOwnProperty(prop)) { - var value = this.internalStringify(obj_part, prop, false); - isTopLevel = false; - if (typeof value !== "undefined" && value !== null) { - buffer += this.makeIndent(this.indentStr, this.objStack.length); - nonEmpty = true; - var propKey = this.isWord(prop) ? prop : this.escapeString(prop); - buffer += propKey + ":" + (this.indentStr ? ' ' : '') + value + ","; - } - } - } - this.objStack.pop(); - if (nonEmpty) { - buffer = buffer.substring(0, buffer.length - 1) + this.makeIndent(this.indentStr, this.objStack.length) + "}"; - } else { - buffer = '{}'; - } + buffer = '{}'; } - return buffer; - default: - // functions and undefined should be ignored - return undefined; - } + } + return buffer; + default: + // functions and undefined should be ignored + return undefined; } } } \ No newline at end of file diff --git a/src/objectEditor.ts b/src/objectEditor.ts index 3c0b68981b..1797ecc508 100644 --- a/src/objectEditor.ts +++ b/src/objectEditor.ts @@ -1,81 +1,81 @@ -/// +import {SurveyObjectProperty} from "./objectProperty"; +import {editorLocalization} from "./editorLocalization"; +import * as Survey from "survey-knockout-bootstrap"; -module SurveyEditor { - export class SurveyObjectEditor { - private selectedObjectValue: any; - public propertyEditorOptions: any = null; - public koProperties: any; - public koActiveProperty: any; - public koHasObject: any; - public onPropertyValueChanged: Survey.Event<(sender: SurveyObjectEditor, options: any) => any, any> = new Survey.Event<(sender: SurveyObjectEditor, options: any) => any, any>(); +export class SurveyObjectEditor { + private selectedObjectValue: any; + public propertyEditorOptions: any = null; + public koProperties: any; + public koActiveProperty: any; + public koHasObject: any; + public onPropertyValueChanged: Survey.Event<(sender: SurveyObjectEditor, options: any) => any, any> = new Survey.Event<(sender: SurveyObjectEditor, options: any) => any, any>(); - constructor(propertyEditorOptions: any = null) { - this.propertyEditorOptions = propertyEditorOptions; - this.koProperties = ko.observableArray(); - this.koActiveProperty = ko.observable(); - this.koHasObject = ko.observable(); - } - public get selectedObject(): any { return this.selectedObjectValue; } - public set selectedObject(value: any) { - if (this.selectedObjectValue == value) return; - this.koHasObject(value != null); - this.selectedObjectValue = value; - this.updateProperties(); - this.updatePropertiesObject(); - } - public getPropertyEditor(name: string) { - var properties = this.koProperties(); - for (var i = 0; i < properties.length; i++) { - if (properties[i].name == name) return properties[i]; - } - return null; - } - public changeActiveProperty(property: SurveyObjectProperty) { - this.koActiveProperty(property); - } - public ObjectChanged() { - this.updatePropertiesObject(); + constructor(propertyEditorOptions: any = null) { + this.propertyEditorOptions = propertyEditorOptions; + this.koProperties = ko.observableArray(); + this.koActiveProperty = ko.observable(); + this.koHasObject = ko.observable(); + } + public get selectedObject(): any { return this.selectedObjectValue; } + public set selectedObject(value: any) { + if (this.selectedObjectValue == value) return; + this.koHasObject(value != null); + this.selectedObjectValue = value; + this.updateProperties(); + this.updatePropertiesObject(); + } + public getPropertyEditor(name: string) { + var properties = this.koProperties(); + for (var i = 0; i < properties.length; i++) { + if (properties[i].name == name) return properties[i]; } - protected updateProperties() { - if (!this.selectedObject || !this.selectedObject.getType) { - this.koProperties([]); - this.koActiveProperty(null); - return; - } - var properties = Survey.JsonObject.metaData.getProperties(this.selectedObject.getType()); - properties.sort((a, b) => { - if (a.name == b.name) return 0; - if (a.name > b.name) return 1; - return -1; - }); - var objectProperties = []; - var self = this; - var propEvent = (property: SurveyObjectProperty, newValue: any) => { - self.onPropertyValueChanged.fire(this, { property: property.property, object: property.object, newValue: newValue }); - }; - for (var i = 0; i < properties.length; i++) { - if (!this.canShowProperty(properties[i])) continue; - var objectProperty = new SurveyObjectProperty(properties[i], propEvent, this.propertyEditorOptions); - var locName = this.selectedObject.getType() + '_' + properties[i].name; - objectProperty.displayName = editorLocalization.getPropertyName(locName); - var title = editorLocalization.getPropertyTitle(locName); - if (!title) title = objectProperty.displayName; - objectProperty.title = title; - objectProperties.push(objectProperty); - } - this.koProperties(objectProperties); - this.koActiveProperty(this.getPropertyEditor("name")); + return null; + } + public changeActiveProperty(property: SurveyObjectProperty) { + this.koActiveProperty(property); + } + public ObjectChanged() { + this.updatePropertiesObject(); + } + protected updateProperties() { + if (!this.selectedObject || !this.selectedObject.getType) { + this.koProperties([]); + this.koActiveProperty(null); + return; } - protected canShowProperty(property: Survey.JsonObjectProperty): boolean { - var name = property.name; - if (name == 'questions' || name == 'pages') return false; - return true; + var properties = Survey.JsonObject.metaData.getProperties(this.selectedObject.getType()); + properties.sort((a, b) => { + if (a.name == b.name) return 0; + if (a.name > b.name) return 1; + return -1; + }); + var objectProperties = []; + var self = this; + var propEvent = (property: SurveyObjectProperty, newValue: any) => { + self.onPropertyValueChanged.fire(this, { property: property.property, object: property.object, newValue: newValue }); + }; + for (var i = 0; i < properties.length; i++) { + if (!this.canShowProperty(properties[i])) continue; + var objectProperty = new SurveyObjectProperty(properties[i], propEvent, this.propertyEditorOptions); + var locName = this.selectedObject.getType() + '_' + properties[i].name; + objectProperty.displayName = editorLocalization.getPropertyName(locName); + var title = editorLocalization.getPropertyTitle(locName); + if (!title) title = objectProperty.displayName; + objectProperty.title = title; + objectProperties.push(objectProperty); } - protected updatePropertiesObject() { - var properties = this.koProperties(); - for (var i = 0; i < properties.length; i++) { - properties[i].object = this.selectedObject; - } + this.koProperties(objectProperties); + this.koActiveProperty(this.getPropertyEditor("name")); + } + protected canShowProperty(property: Survey.JsonObjectProperty): boolean { + var name = property.name; + if (name == 'questions' || name == 'pages') return false; + return true; + } + protected updatePropertiesObject() { + var properties = this.koProperties(); + for (var i = 0; i < properties.length; i++) { + properties[i].object = this.selectedObject; } } } \ No newline at end of file diff --git a/src/objectProperty.ts b/src/objectProperty.ts index cd2abca813..aebe58f4c5 100644 --- a/src/objectProperty.ts +++ b/src/objectProperty.ts @@ -1,81 +1,80 @@ -/// +import {SurveyPropertyEditorBase} from "./propertyEditors/propertyEditorBase"; +import {editorLocalization} from "./editorLocalization"; +import * as Survey from "survey-knockout-bootstrap"; -module SurveyEditor { +export declare type SurveyOnPropertyChangedCallback = (property: SurveyObjectProperty, newValue: any) => void; - export declare type SurveyOnPropertyChangedCallback = (property: SurveyObjectProperty, newValue: any) => void; +export class SurveyObjectProperty { + private objectValue: any; + private isValueUpdating: boolean; + private onPropertyChanged: SurveyOnPropertyChangedCallback; + public name: string; + public displayName: string; + public title: string; + public koValue: any; + public koText: any; + public modalName: string; + public modalNameTarget: string; + public koIsDefault: any; + public editor: SurveyPropertyEditorBase; + public editorType: string; + public baseEditorType: string; + public choices: Array; - export class SurveyObjectProperty { - private objectValue: any; - private isValueUpdating: boolean; - private onPropertyChanged: SurveyOnPropertyChangedCallback; - public name: string; - public displayName: string; - public title: string; - public koValue: any; - public koText: any; - public modalName: string; - public modalNameTarget: string; - public koIsDefault: any; - public editor: SurveyPropertyEditorBase; - public editorType: string; - public baseEditorType: string; - public choices: Array; - - constructor(public property: Survey.JsonObjectProperty, onPropertyChanged: SurveyOnPropertyChangedCallback = null, propertyEditorOptions: any = null) { - this.onPropertyChanged = onPropertyChanged; - this.name = this.property.name; - this.koValue = ko.observable(); - this.choices = property.choices; - var self = this; - this.editorType = property.type; - //TODO - if (this.choices != null) { - this.editorType = "dropdown"; - } - var onItemChanged = function (newValue: any) { self.onApplyEditorValue(newValue); }; - this.editor = SurveyPropertyEditorBase.createEditor(this.editorType, onItemChanged); - this.editor.options = propertyEditorOptions; - this.editorType = this.editor.editorType; - this.modalName = "modelEditor" + this.editorType + this.name; - this.modalNameTarget = "#" + this.modalName; - this.koValue.subscribe(function (newValue) { self.onkoValueChanged(newValue); }); - this.koText = ko.computed(() => { return self.getValueText(self.koValue()); }); - this.koIsDefault = ko.computed(function () { return self.property.isDefaultValue(self.koValue()); }); - } - public get object(): any { return this.objectValue; } - public set object(value: any) { - this.objectValue = value; - this.updateValue(); - } - protected updateValue() { - this.isValueUpdating = true; - this.koValue(this.getValue()); - this.editor.setObject(this.object); - this.editor.setTitle(editorLocalization.getString("pe.editProperty")["format"](this.property.name)); - this.updateEditorData(this.koValue()); - this.isValueUpdating = false; - } - private isApplyingNewValue: boolean = false; - private onApplyEditorValue(newValue: any) { - this.isApplyingNewValue = true; - this.koValue(newValue); - this.isApplyingNewValue = false; - } - private onkoValueChanged(newValue: any) { - if (!this.isApplyingNewValue) { - this.updateEditorData(newValue); - } - if (this.object == null) return; - if (this.object[this.name] == newValue) return; - if (this.onPropertyChanged != null && !this.isValueUpdating) this.onPropertyChanged(this, newValue); - } - private updateEditorData(newValue: any) { - this.editor.value = newValue; + constructor(public property: Survey.JsonObjectProperty, onPropertyChanged: SurveyOnPropertyChangedCallback = null, propertyEditorOptions: any = null) { + this.onPropertyChanged = onPropertyChanged; + this.name = this.property.name; + this.koValue = ko.observable(); + this.choices = property.choices; + var self = this; + this.editorType = property.type; + //TODO + if (this.choices != null) { + this.editorType = "dropdown"; } - protected getValue(): any { - if (this.property.hasToUseGetValue) return this.property.getValue(this.object); - return this.object[this.name]; + var onItemChanged = function (newValue: any) { self.onApplyEditorValue(newValue); }; + this.editor = SurveyPropertyEditorBase.createEditor(this.editorType, onItemChanged); + this.editor.options = propertyEditorOptions; + this.editorType = this.editor.editorType; + this.modalName = "modelEditor" + this.editorType + this.name; + this.modalNameTarget = "#" + this.modalName; + this.koValue.subscribe(function (newValue) { self.onkoValueChanged(newValue); }); + this.koText = ko.computed(() => { return self.getValueText(self.koValue()); }); + this.koIsDefault = ko.computed(function () { return self.property.isDefaultValue(self.koValue()); }); + } + public get object(): any { return this.objectValue; } + public set object(value: any) { + this.objectValue = value; + this.updateValue(); + } + protected updateValue() { + this.isValueUpdating = true; + this.koValue(this.getValue()); + this.editor.setObject(this.object); + this.editor.setTitle(editorLocalization.getString("pe.editProperty")["format"](this.property.name)); + this.updateEditorData(this.koValue()); + this.isValueUpdating = false; + } + private isApplyingNewValue: boolean = false; + private onApplyEditorValue(newValue: any) { + this.isApplyingNewValue = true; + this.koValue(newValue); + this.isApplyingNewValue = false; + } + private onkoValueChanged(newValue: any) { + if (!this.isApplyingNewValue) { + this.updateEditorData(newValue); } - protected getValueText(value: any): string { return this.editor.getValueText(value); } + if (this.object == null) return; + if (this.object[this.name] == newValue) return; + if (this.onPropertyChanged != null && !this.isValueUpdating) this.onPropertyChanged(this, newValue); + } + private updateEditorData(newValue: any) { + this.editor.value = newValue; + } + protected getValue(): any { + if (this.property.hasToUseGetValue) return this.property.getValue(this.object); + return this.object[this.name]; } + protected getValueText(value: any): string { return this.editor.getValueText(value); } } \ No newline at end of file diff --git a/src/objectVerbs.ts b/src/objectVerbs.ts index 6cd0579864..b8c7b5a161 100644 --- a/src/objectVerbs.ts +++ b/src/objectVerbs.ts @@ -1,103 +1,105 @@ - module SurveyEditor { - export class SurveyVerbs { - private surveyValue: Survey.Survey; - private objValue: any; - private choicesClasses: Array; - koVerbs: any; - koHasVerbs: any; - constructor(public onModifiedCallback: () => any) { - this.koVerbs = ko.observableArray(); - this.koHasVerbs = ko.observable(); - var classes = Survey.JsonObject.metaData.getChildrenClasses("selectbase", true); - this.choicesClasses = []; - for (var i = 0; i < classes.length; i++) { - this.choicesClasses.push(classes[i].name); - } - } - public get survey(): Survey.Survey { return this.surveyValue; } - public set survey(value: Survey.Survey) { - if (this.survey == value) return; - this.surveyValue = value; - } - public get obj(): any { return this.objValue } - public set obj(value: any) { - if (this.objValue == value) return; - this.objValue = value; - this.buildVerbs(); - } - private buildVerbs() { - var array = []; - var objType = SurveyHelper.getObjectType(this.obj); - if (objType == ObjType.Question) { - var question = this.obj; - if (this.survey.pages.length > 1) { - array.push(new SurveyVerbChangePageItem(this.survey, question, this.onModifiedCallback)); - } - if (this.choicesClasses.indexOf(question.getType()) > -1) { - array.push(new SurveyVerbChangeTypeItem(this.survey, question, this.onModifiedCallback)); - } - } - this.koVerbs(array); - this.koHasVerbs(array.length > 0); +import {editorLocalization} from "./editorLocalization"; +import {SurveyHelper, ObjType} from "./surveyHelper"; +import * as Survey from "survey-knockout-bootstrap"; + +export class SurveyVerbs { + private surveyValue: Survey.Survey; + private objValue: any; + private choicesClasses: Array; + koVerbs: any; + koHasVerbs: any; + constructor(public onModifiedCallback: () => any) { + this.koVerbs = ko.observableArray(); + this.koHasVerbs = ko.observable(); + var classes = Survey.JsonObject.metaData.getChildrenClasses("selectbase", true); + this.choicesClasses = []; + for (var i = 0; i < classes.length; i++) { + this.choicesClasses.push(classes[i].name); } } - export class SurveyVerbItem { - koItems: any; - koSelectedItem: any; - constructor(public survey: Survey.Survey, public question: Survey.QuestionBase, public onModifiedCallback: () => any) { - this.koItems = ko.observableArray(); - this.koSelectedItem = ko.observable(); - } - public get text(): string { return ""; } + public get survey(): Survey.Survey { return this.surveyValue; } + public set survey(value: Survey.Survey) { + if (this.survey == value) return; + this.surveyValue = value; + } + public get obj(): any { return this.objValue } + public set obj(value: any) { + if (this.objValue == value) return; + this.objValue = value; + this.buildVerbs(); } - export class SurveyVerbChangeTypeItem extends SurveyVerbItem { - constructor(public survey: Survey.Survey, public question: Survey.QuestionBase, public onModifiedCallback: () => any) { - super(survey, question, onModifiedCallback); - var classes = Survey.JsonObject.metaData.getChildrenClasses("selectbase", true); - var array = []; - for (var i = 0; i < classes.length; i++) { - array.push({ value: classes[i].name, text: editorLocalization.getString("qt." + classes[i].name) }); + private buildVerbs() { + var array = []; + var objType = SurveyHelper.getObjectType(this.obj); + if (objType == ObjType.Question) { + var question = this.obj; + if (this.survey.pages.length > 1) { + array.push(new SurveyVerbChangePageItem(this.survey, question, this.onModifiedCallback)); + } + if (this.choicesClasses.indexOf(question.getType()) > -1) { + array.push(new SurveyVerbChangeTypeItem(this.survey, question, this.onModifiedCallback)); } - this.koItems(array); - this.koSelectedItem(question.getType()); - var self = this; - this.koSelectedItem.subscribe(function (newValue) { self.changeType(newValue); }); - } - public get text(): string { return editorLocalization.getString("pe.verbChangeType"); } - private changeType(questionType: string) { - if (questionType == this.question.getType()) return; - var page = this.survey.getPageByQuestion(this.question); - var index = page.questions.indexOf(this.question); - var newQuestion = Survey.QuestionFactory.Instance.createQuestion(questionType, this.question.name); - var jsonObj = new Survey.JsonObject(); - var json = jsonObj.toJsonObject(this.question); - jsonObj.toObject(json, newQuestion); - page.removeQuestion(this.question); - page.addQuestion(newQuestion, index); - if (this.onModifiedCallback) this.onModifiedCallback(); } + this.koVerbs(array); + this.koHasVerbs(array.length > 0); } - export class SurveyVerbChangePageItem extends SurveyVerbItem { - private prevPage: Survey.Page; - constructor(public survey: Survey.Survey, public question: Survey.QuestionBase, public onModifiedCallback: () => any) { - super(survey, question, onModifiedCallback); - var array = []; - for (var i = 0; i < this.survey.pages.length; i++) { - var page = this.survey.pages[i]; - array.push({ value: page, text: SurveyHelper.getObjectName(page) }); - } - this.koItems(array); - this.prevPage = this.survey.getPageByQuestion(question); - this.koSelectedItem(this.prevPage); - var self = this; - this.koSelectedItem.subscribe(function (newValue) { self.changePage(newValue); }); +} +export class SurveyVerbItem { + koItems: any; + koSelectedItem: any; + constructor(public survey: Survey.Survey, public question: Survey.QuestionBase, public onModifiedCallback: () => any) { + this.koItems = ko.observableArray(); + this.koSelectedItem = ko.observable(); + } + public get text(): string { return ""; } +} +export class SurveyVerbChangeTypeItem extends SurveyVerbItem { + constructor(public survey: Survey.Survey, public question: Survey.QuestionBase, public onModifiedCallback: () => any) { + super(survey, question, onModifiedCallback); + var classes = Survey.JsonObject.metaData.getChildrenClasses("selectbase", true); + var array = []; + for (var i = 0; i < classes.length; i++) { + array.push({ value: classes[i].name, text: editorLocalization.getString("qt." + classes[i].name) }); } - public get text(): string { return editorLocalization.getString("pe.verbChangePage"); } - private changePage(newPage: Survey.Page) { - if (newPage == null || newPage == this.prevPage) return; - this.prevPage.removeQuestion(this.question); - newPage.addQuestion(this.question); - if (this.onModifiedCallback) this.onModifiedCallback(); + this.koItems(array); + this.koSelectedItem(question.getType()); + var self = this; + this.koSelectedItem.subscribe(function (newValue) { self.changeType(newValue); }); + } + public get text(): string { return editorLocalization.getString("pe.verbChangeType"); } + private changeType(questionType: string) { + if (questionType == this.question.getType()) return; + var page = this.survey.getPageByQuestion(this.question); + var index = page.questions.indexOf(this.question); + var newQuestion = Survey.QuestionFactory.Instance.createQuestion(questionType, this.question.name); + var jsonObj = new Survey.JsonObject(); + var json = jsonObj.toJsonObject(this.question); + jsonObj.toObject(json, newQuestion); + page.removeQuestion(this.question); + page.addQuestion(newQuestion, index); + if (this.onModifiedCallback) this.onModifiedCallback(); + } +} +export class SurveyVerbChangePageItem extends SurveyVerbItem { + private prevPage: Survey.Page; + constructor(public survey: Survey.Survey, public question: Survey.QuestionBase, public onModifiedCallback: () => any) { + super(survey, question, onModifiedCallback); + var array = []; + for (var i = 0; i < this.survey.pages.length; i++) { + var page = this.survey.pages[i]; + array.push({ value: page, text: SurveyHelper.getObjectName(page) }); } + this.koItems(array); + this.prevPage = this.survey.getPageByQuestion(question); + this.koSelectedItem(this.prevPage); + var self = this; + this.koSelectedItem.subscribe(function (newValue) { self.changePage(newValue); }); + } + public get text(): string { return editorLocalization.getString("pe.verbChangePage"); } + private changePage(newPage: Survey.Page) { + if (newPage == null || newPage == this.prevPage) return; + this.prevPage.removeQuestion(this.question); + newPage.addQuestion(this.question); + if (this.onModifiedCallback) this.onModifiedCallback(); } } \ No newline at end of file diff --git a/src/pagesEditor.ts b/src/pagesEditor.ts index 11941e6ef5..d3be76ffe6 100644 --- a/src/pagesEditor.ts +++ b/src/pagesEditor.ts @@ -1,121 +1,122 @@ - -module SurveyEditor { - export declare type SurveyAddNewPageCallback = () => void; - export declare type SurveySelectPageCallback = (page: Survey.Page) => void; - export declare type SurveyMovePageCallback = (indexFrom: number, indexTo: number) => void; - export class SurveyPagesEditor { - surveyValue: Survey.Survey; - koPages: any; - koIsValid: any; - selectPageClick: any; - onAddNewPageCallback: SurveyAddNewPageCallback; - onSelectPageCallback: SurveySelectPageCallback; - onDeletePageCallback: SurveySelectPageCallback; - onMovePageCallback: SurveyMovePageCallback; - draggingPage: any = null; - dragStart: any; dragOver: any; dragEnd: any; dragDrop: any; keyDown: any; +import {SurveyHelper} from "./surveyHelper"; +import * as Survey from "survey-knockout-bootstrap"; - constructor(onAddNewPageCallback: SurveyAddNewPageCallback = null, onSelectPageCallback: SurveySelectPageCallback = null, - onMovePageCallback: SurveyMovePageCallback = null, onDeletePageCallback: SurveySelectPageCallback = null) { - this.koPages = ko.observableArray(); - this.koIsValid = ko.observable(false); - this.onAddNewPageCallback = onAddNewPageCallback; - this.onSelectPageCallback = onSelectPageCallback; - this.onMovePageCallback = onMovePageCallback; - this.onDeletePageCallback = onDeletePageCallback; - var self = this; - this.selectPageClick = function(pageItem) { - if (self.onSelectPageCallback) { - self.onSelectPageCallback(pageItem.page); - } +export declare type SurveyAddNewPageCallback = () => void; +export declare type SurveySelectPageCallback = (page: Survey.Page) => void; +export declare type SurveyMovePageCallback = (indexFrom: number, indexTo: number) => void; + +export class SurveyPagesEditor { + surveyValue: Survey.Survey; + koPages: any; + koIsValid: any; + selectPageClick: any; + onAddNewPageCallback: SurveyAddNewPageCallback; + onSelectPageCallback: SurveySelectPageCallback; + onDeletePageCallback: SurveySelectPageCallback; + onMovePageCallback: SurveyMovePageCallback; + draggingPage: any = null; + dragStart: any; dragOver: any; dragEnd: any; dragDrop: any; keyDown: any; + + constructor(onAddNewPageCallback: SurveyAddNewPageCallback = null, onSelectPageCallback: SurveySelectPageCallback = null, + onMovePageCallback: SurveyMovePageCallback = null, onDeletePageCallback: SurveySelectPageCallback = null) { + this.koPages = ko.observableArray(); + this.koIsValid = ko.observable(false); + this.onAddNewPageCallback = onAddNewPageCallback; + this.onSelectPageCallback = onSelectPageCallback; + this.onMovePageCallback = onMovePageCallback; + this.onDeletePageCallback = onDeletePageCallback; + var self = this; + this.selectPageClick = function(pageItem) { + if (self.onSelectPageCallback) { + self.onSelectPageCallback(pageItem.page); } - this.keyDown = function (el: any, e: KeyboardEvent) { self.onKeyDown(el, e); } - this.dragStart = function (el: any) { self.draggingPage = el; }; - this.dragOver = function (el: any) { }; - this.dragEnd = function () { self.draggingPage = null; }; - this.dragDrop = function (el: any) { self.moveDraggingPageTo(el); }; + }; + this.keyDown = function (el: any, e: KeyboardEvent) { self.onKeyDown(el, e); } + this.dragStart = function (el: any) { self.draggingPage = el; }; + this.dragOver = function (el: any) { }; + this.dragEnd = function () { self.draggingPage = null; }; + this.dragDrop = function (el: any) { self.moveDraggingPageTo(el); }; + } + public get survey(): Survey.Survey { return this.surveyValue; } + public set survey(value: Survey.Survey) { + this.surveyValue = value; + this.koIsValid(this.surveyValue != null); + this.updatePages(); + } + public setSelectedPage(page: Survey.Page) { + var pages = this.koPages(); + for (var i = 0; i < pages.length; i++) { + pages[i].koSelected(pages[i].page == page); } - public get survey(): Survey.Survey { return this.surveyValue; } - public set survey(value: Survey.Survey) { - this.surveyValue = value; - this.koIsValid(this.surveyValue != null); - this.updatePages(); + } + public addNewPageClick() { + if (this.onAddNewPageCallback) { + this.onAddNewPageCallback(); } - public setSelectedPage(page: Survey.Page) { - var pages = this.koPages(); - for (var i = 0; i < pages.length; i++) { - pages[i].koSelected(pages[i].page == page); - } + } + public removePage(page: Survey.Page) { + var index = this.getIndexByPage(page); + if (index > -1) { + this.koPages.splice(index, 1); } - public addNewPageClick() { - if (this.onAddNewPageCallback) { - this.onAddNewPageCallback(); - } + } + public changeName(page: Survey.Page) { + var index = this.getIndexByPage(page); + if (index > -1) { + this.koPages()[index].title(SurveyHelper.getObjectName(page)); } - public removePage(page: Survey.Page) { - var index = this.getIndexByPage(page); - if (index > -1) { - this.koPages.splice(index, 1); - } + } + protected getIndexByPage(page: Survey.Page): number { + var pages = this.koPages(); + for (var i = 0; i < pages.length; i++) { + if (pages[i].page == page) return i; } - public changeName(page: Survey.Page) { - var index = this.getIndexByPage(page); - if (index > -1) { - this.koPages()[index].title(SurveyHelper.getObjectName(page)); + return -1; + } + protected onKeyDown(el: any, e: KeyboardEvent) { + if (this.koPages().length <= 1) return; + var pages = this.koPages(); + var pageIndex = -1; + for (var i = 0; i < pages.length; i++) { + if (pages[i].page && pages[i].koSelected()) { + pageIndex = i; } } - protected getIndexByPage(page: Survey.Page): number { - var pages = this.koPages(); - for (var i = 0; i < pages.length; i++) { - if (pages[i].page == page) return i; - } - return -1; + if (pageIndex < 0) return; + if (e.keyCode == 46 && this.onDeletePageCallback) this.onDeletePageCallback(el.page); + if ((e.keyCode == 37 || e.keyCode == 39) && this.onSelectPageCallback) { + pageIndex += (e.keyCode == 37 ? -1 : 1); + if (pageIndex < 0) pageIndex = pages.length - 1; + if (pageIndex >= pages.length) pageIndex = 0; + var page = pages[pageIndex].page; + this.onSelectPageCallback(page); + this.setSelectedPage(page); } - protected onKeyDown(el: any, e: KeyboardEvent) { - if (this.koPages().length <= 1) return; - var pages = this.koPages(); - var pageIndex = -1; - for (var i = 0; i < pages.length; i++) { - if (pages[i].page && pages[i].koSelected()) { - pageIndex = i; - } - } - if (pageIndex < 0) return; - if (e.keyCode == 46 && this.onDeletePageCallback) this.onDeletePageCallback(el.page); - if ((e.keyCode == 37 || e.keyCode == 39) && this.onSelectPageCallback) { - pageIndex += (e.keyCode == 37 ? -1 : 1); - if (pageIndex < 0) pageIndex = pages.length - 1; - if (pageIndex >= pages.length) pageIndex = 0; - var page = pages[pageIndex].page; - this.onSelectPageCallback(page); - this.setSelectedPage(page); - } + } + protected updatePages() { + if (this.surveyValue == null) { + this.koPages([]); + return; } - protected updatePages() { - if (this.surveyValue == null) { - this.koPages([]); - return; - } - var pages = []; - for (var i = 0; i < this.surveyValue.pages.length; i++) { - var page = this.surveyValue.pages[i]; - pages.push({ - title: ko.observable(SurveyHelper.getObjectName(page)), page: page, koSelected: ko.observable(false) - }); - } - this.koPages(pages); + var pages = []; + for (var i = 0; i < this.surveyValue.pages.length; i++) { + var page = this.surveyValue.pages[i]; + pages.push({ + title: ko.observable(SurveyHelper.getObjectName(page)), page: page, koSelected: ko.observable(false) + }); } - private moveDraggingPageTo(toPage: any) { - if (toPage == null || toPage == this.draggingPage) { - this.draggingPage = null; - return; - } - if (this.draggingPage == null) return; - var index = this.koPages().indexOf(this.draggingPage); - var indexTo = this.koPages().indexOf(toPage); - if (this.onMovePageCallback) { - this.onMovePageCallback(index, indexTo); - } + this.koPages(pages); + } + private moveDraggingPageTo(toPage: any) { + if (toPage == null || toPage == this.draggingPage) { + this.draggingPage = null; + return; + } + if (this.draggingPage == null) return; + var index = this.koPages().indexOf(this.draggingPage); + var indexTo = this.koPages().indexOf(toPage); + if (this.onMovePageCallback) { + this.onMovePageCallback(index, indexTo); } } } \ No newline at end of file diff --git a/src/propertyEditors/propertyEditorBase.ts b/src/propertyEditors/propertyEditorBase.ts index 8ad8ec98b6..f88c8d2b6b 100644 --- a/src/propertyEditors/propertyEditorBase.ts +++ b/src/propertyEditors/propertyEditorBase.ts @@ -1,67 +1,65 @@ -module SurveyEditor { - export class SurveyPropertyEditorBase { - public static defaultEditor: string = "string"; - private static editorRegisteredList = {}; - public static registerEditor(name: string, creator: () => SurveyPropertyEditorBase) { - SurveyPropertyEditorBase.editorRegisteredList[name] = creator; - } - public static createEditor(editorType: string, func: (newValue: any) => any): SurveyPropertyEditorBase { - var creator = SurveyPropertyEditorBase.editorRegisteredList[editorType]; - if (!creator) creator = SurveyPropertyEditorBase.editorRegisteredList[SurveyPropertyEditorBase.defaultEditor]; - var propertyEditor = creator(); - propertyEditor.onChanged = func; - return propertyEditor; - } +export class SurveyPropertyEditorBase { + public static defaultEditor: string = "string"; + private static editorRegisteredList = {}; + public static registerEditor(name: string, creator: () => SurveyPropertyEditorBase) { + SurveyPropertyEditorBase.editorRegisteredList[name] = creator; + } + public static createEditor(editorType: string, func: (newValue: any) => any): SurveyPropertyEditorBase { + var creator = SurveyPropertyEditorBase.editorRegisteredList[editorType]; + if (!creator) creator = SurveyPropertyEditorBase.editorRegisteredList[SurveyPropertyEditorBase.defaultEditor]; + var propertyEditor = creator(); + propertyEditor.onChanged = func; + return propertyEditor; + } - private value_: any = null; - public options: any = null; - public onChanged: (newValue: any) => any; - constructor() { - } - public get editorType(): string { throw "editorType is not defined"; } - public getValueText(value: any): string { return value; } - public get value(): any { return this.value_; } - public set value(value: any) { - value = this.getCorrectedValue(value); - this.setValueCore(value); - this.onValueChanged(); - } - protected setValueCore(value: any) { - this.value_ = value; - } - public setTitle(value: string) { } - public setObject(value: any) { } - protected onValueChanged() { - } - protected getCorrectedValue(value: any): any { return value; } + private value_: any = null; + public options: any = null; + public onChanged: (newValue: any) => any; + constructor() { + } + public get editorType(): string { throw "editorType is not defined"; } + public getValueText(value: any): string { return value; } + public get value(): any { return this.value_; } + public set value(value: any) { + value = this.getCorrectedValue(value); + this.setValueCore(value); + this.onValueChanged(); + } + protected setValueCore(value: any) { + this.value_ = value; + } + public setTitle(value: string) { } + public setObject(value: any) { } + protected onValueChanged() { } - export class SurveyStringPropertyEditor extends SurveyPropertyEditorBase { - constructor() { - super(); - } - public get editorType(): string { return "string"; } + protected getCorrectedValue(value: any): any { return value; } +} +export class SurveyStringPropertyEditor extends SurveyPropertyEditorBase { + constructor() { + super(); } - export class SurveyDropdownPropertyEditor extends SurveyPropertyEditorBase { - constructor() { - super(); - } - public get editorType(): string { return "dropdown"; } + public get editorType(): string { return "string"; } +} +export class SurveyDropdownPropertyEditor extends SurveyPropertyEditorBase { + constructor() { + super(); } - export class SurveyBooleanPropertyEditor extends SurveyPropertyEditorBase { - constructor() { - super(); - } - public get editorType(): string { return "boolean"; } + public get editorType(): string { return "dropdown"; } +} +export class SurveyBooleanPropertyEditor extends SurveyPropertyEditorBase { + constructor() { + super(); } - export class SurveyNumberPropertyEditor extends SurveyPropertyEditorBase { - constructor() { - super(); - } - public get editorType(): string { return "number"; } + public get editorType(): string { return "boolean"; } +} +export class SurveyNumberPropertyEditor extends SurveyPropertyEditorBase { + constructor() { + super(); } + public get editorType(): string { return "number"; } +} - SurveyPropertyEditorBase.registerEditor("string", function (): SurveyPropertyEditorBase { return new SurveyStringPropertyEditor(); }); - SurveyPropertyEditorBase.registerEditor("dropdown", function (): SurveyPropertyEditorBase { return new SurveyDropdownPropertyEditor(); }); - SurveyPropertyEditorBase.registerEditor("boolean", function (): SurveyPropertyEditorBase { return new SurveyBooleanPropertyEditor(); }); - SurveyPropertyEditorBase.registerEditor("number", function (): SurveyPropertyEditorBase { return new SurveyNumberPropertyEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("string", function (): SurveyPropertyEditorBase { return new SurveyStringPropertyEditor(); }); +SurveyPropertyEditorBase.registerEditor("dropdown", function (): SurveyPropertyEditorBase { return new SurveyDropdownPropertyEditor(); }); +SurveyPropertyEditorBase.registerEditor("boolean", function (): SurveyPropertyEditorBase { return new SurveyBooleanPropertyEditor(); }); +SurveyPropertyEditorBase.registerEditor("number", function (): SurveyPropertyEditorBase { return new SurveyNumberPropertyEditor(); }); \ No newline at end of file diff --git a/src/propertyEditors/propertyItemValuesEditor.ts b/src/propertyEditors/propertyItemValuesEditor.ts index 33bb74aae9..7bce52fa1c 100644 --- a/src/propertyEditors/propertyItemValuesEditor.ts +++ b/src/propertyEditors/propertyItemValuesEditor.ts @@ -1,40 +1,38 @@ -/// -/// -/// -module SurveyEditor { - export class SurveyPropertyItemValuesEditor extends SurveyPropertyItemsEditor { - constructor() { - super(); - } - public get editorType(): string { return "itemvalues"; } - public hasError(): boolean { - var result = false; - for (var i = 0; i < this.koItems().length; i++) { - var item = this.koItems()[i]; - item.koHasError(!item.koValue()); - result = result || item.koHasError(); - } - return result; +import {SurveyPropertyItemsEditor} from "./propertyItemsEditor"; +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; + +export class SurveyPropertyItemValuesEditor extends SurveyPropertyItemsEditor { + constructor() { + super(); + } + public get editorType(): string { return "itemvalues"; } + public hasError(): boolean { + var result = false; + for (var i = 0; i < this.koItems().length; i++) { + var item = this.koItems()[i]; + item.koHasError(!item.koValue()); + result = result || item.koHasError(); } - protected createNewEditorItem(): any { return { koValue: ko.observable(), koText: ko.observable(), koHasError: ko.observable(false) }; } - protected createEditorItem(item: any) { - var itemValue = item; - var itemText = null; - if (item.value) { - itemValue = item.value; - itemText = item.text; - } - return { koValue: ko.observable(itemValue), koText: ko.observable(itemText), koHasError: ko.observable(false) }; + return result; + } + protected createNewEditorItem(): any { return { koValue: ko.observable(), koText: ko.observable(), koHasError: ko.observable(false) }; } + protected createEditorItem(item: any) { + var itemValue = item; + var itemText = null; + if (item.value) { + itemValue = item.value; + itemText = item.text; } - protected createItemFromEditorItem(editorItem: any) { - var alwaySaveTextInPropertyEditors = this.options && this.options.alwaySaveTextInPropertyEditors; - var text = editorItem.koText(); - if (!alwaySaveTextInPropertyEditors && editorItem.koText() == editorItem.koValue()) { - text = null; - } - return { value: editorItem.koValue(), text: text }; + return { koValue: ko.observable(itemValue), koText: ko.observable(itemText), koHasError: ko.observable(false) }; + } + protected createItemFromEditorItem(editorItem: any) { + var alwaySaveTextInPropertyEditors = this.options && this.options.alwaySaveTextInPropertyEditors; + var text = editorItem.koText(); + if (!alwaySaveTextInPropertyEditors && editorItem.koText() == editorItem.koValue()) { + text = null; } + return { value: editorItem.koValue(), text: text }; } +} - SurveyPropertyEditorBase.registerEditor("itemvalues", function (): SurveyPropertyEditorBase { return new SurveyPropertyItemValuesEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("itemvalues", function (): SurveyPropertyEditorBase { return new SurveyPropertyItemValuesEditor(); }); \ No newline at end of file diff --git a/src/propertyEditors/propertyItemsEditor.ts b/src/propertyEditors/propertyItemsEditor.ts index eb034352a0..adfa2f41ce 100644 --- a/src/propertyEditors/propertyItemsEditor.ts +++ b/src/propertyEditors/propertyItemsEditor.ts @@ -1,54 +1,53 @@ -/// -/// -module SurveyEditor { - export class SurveyPropertyItemsEditor extends SurveyPropertyModalEditor { - public koItems: any; - public onDeleteClick: any; - public onAddClick: any; - public onClearClick: any; +import {SurveyPropertyModalEditor} from "./propertyModalEditor"; +import {editorLocalization} from "../editorLocalization"; - constructor() { - super(); - this.koItems = ko.observableArray(); - this.value = []; - var self = this; - self.onDeleteClick = function (item) { self.koItems.remove(item); }; - self.onClearClick = function (item) { self.koItems.removeAll(); }; - self.onAddClick = function () { self.AddItem(); }; +export class SurveyPropertyItemsEditor extends SurveyPropertyModalEditor { + public koItems: any; + public onDeleteClick: any; + public onAddClick: any; + public onClearClick: any; + constructor() { + super(); + this.koItems = ko.observableArray(); + this.value = []; + var self = this; + self.onDeleteClick = function (item) { self.koItems.remove(item); }; + self.onClearClick = function (item) { self.koItems.removeAll(); }; + self.onAddClick = function () { self.AddItem(); }; + + } + public getValueText(value: any): string { + var len = value ? value.length : 0; + return editorLocalization.getString("pe.items")["format"](len); + } + protected getCorrectedValue(value: any): any { + if (value == null || !Array.isArray(value)) value = []; + return value; + } + protected AddItem() { + this.koItems.push(this.createNewEditorItem()); + } + protected onValueChanged() { + this.koItems(this.getItemsFromValue()); + } + protected getItemsFromValue(): Array { + var items = []; + var value = this.value; + for (var i = 0; i < value.length; i++) { + items.push(this.createEditorItem(value[i])); } - public getValueText(value: any): string { - var len = value ? value.length : 0; - return editorLocalization.getString("pe.items")["format"](len); - } - protected getCorrectedValue(value: any): any { - if (value == null || !Array.isArray(value)) value = []; - return value; - } - protected AddItem() { - this.koItems.push(this.createNewEditorItem()); - } - protected onValueChanged() { - this.koItems(this.getItemsFromValue()); - } - protected getItemsFromValue(): Array { - var items = []; - var value = this.value; - for (var i = 0; i < value.length; i++) { - items.push(this.createEditorItem(value[i])); - } - return items; - } - protected onBeforeApply() { - var items = []; - var internalItems = this.koItems(); - for (var i = 0; i < internalItems.length; i++) { - items.push(this.createItemFromEditorItem(internalItems[i])); - } - this.setValueCore(items); + return items; + } + protected onBeforeApply() { + var items = []; + var internalItems = this.koItems(); + for (var i = 0; i < internalItems.length; i++) { + items.push(this.createItemFromEditorItem(internalItems[i])); } - protected createNewEditorItem(): any { throw "Override 'createNewEditorItem' method"; } - protected createEditorItem(item: any) { return item; } - protected createItemFromEditorItem(editorItem: any) { return editorItem; } + this.setValueCore(items); } + protected createNewEditorItem(): any { throw "Override 'createNewEditorItem' method"; } + protected createEditorItem(item: any) { return item; } + protected createItemFromEditorItem(editorItem: any) { return editorItem; } } \ No newline at end of file diff --git a/src/propertyEditors/propertyMatrixDropdownColumnsEditor.ts b/src/propertyEditors/propertyMatrixDropdownColumnsEditor.ts index ca3518ed90..78fda883a5 100644 --- a/src/propertyEditors/propertyMatrixDropdownColumnsEditor.ts +++ b/src/propertyEditors/propertyMatrixDropdownColumnsEditor.ts @@ -1,83 +1,83 @@ -/// -/// -/// -/// -module SurveyEditor { - export class SurveyPropertyDropdownColumnsEditor extends SurveyPropertyItemsEditor { - constructor() { - super(); - } - public get editorType(): string { return "matrixdropdowncolumns"; } - public hasError(): boolean { - var result = false; - for (var i = 0; i < this.koItems().length; i++) { - result = result || this.koItems()[i].hasError(); - } - return result; - } - protected createNewEditorItem(): any { return new SurveyPropertyMatrixDropdownColumnsItem(new Survey.MatrixDropdownColumn("", this.options)); } - protected createEditorItem(item: any) { return new SurveyPropertyMatrixDropdownColumnsItem(item, this.options); } - protected createItemFromEditorItem(editorItem: any) { - var columItem = editorItem; - columItem.apply(); - return columItem.column; +import {SurveyPropertyItemsEditor} from "./propertyItemsEditor"; +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; +import {SurveyPropertyItemValuesEditor} from "./propertyItemValuesEditor"; +import * as Survey from "survey-knockout-bootstrap"; + +export class SurveyPropertyDropdownColumnsEditor extends SurveyPropertyItemsEditor { + constructor() { + super(); + } + public get editorType(): string { return "matrixdropdowncolumns"; } + public hasError(): boolean { + var result = false; + for (var i = 0; i < this.koItems().length; i++) { + result = result || this.koItems()[i].hasError(); } + return result; + } + protected createNewEditorItem(): any { return new SurveyPropertyMatrixDropdownColumnsItem(new Survey.MatrixDropdownColumn("", this.options)); } + protected createEditorItem(item: any) { return new SurveyPropertyMatrixDropdownColumnsItem(item, this.options); } + protected createItemFromEditorItem(editorItem: any) { + var columItem = editorItem; + columItem.apply(); + return columItem.column; } - export class SurveyPropertyMatrixDropdownColumnsItem { - private koChoices: any; - public choicesEditor: SurveyPropertyItemValuesEditor; - koName: any; koTitle: any; koCellType: any; koShowChoices: any; - koHasError: any; koColCount: any; koIsRequired: any; koHasOther: any; - koHasChoices: any; koHasColCount: any; - public onShowChoicesClick: any; - public cellTypeChoices: Array; - public colCountChoices: Array; - constructor(public column: Survey.MatrixDropdownColumn, public options = null) { - this.cellTypeChoices = this.getPropertyChoices("cellType"); - this.colCountChoices = this.getPropertyChoices("colCount"); - this.koName = ko.observable(column.name); - this.koCellType = ko.observable(column.cellType); - this.koColCount = ko.observable(column.colCount); - this.koIsRequired = ko.observable(column.isRequired ? true : false); - this.koHasOther = ko.observable(column.hasOther ? true : false); - this.koTitle = ko.observable(column.name === column.title ? "" : column.title); - this.koShowChoices = ko.observable(false); - this.koChoices = ko.observableArray(column.choices); - this.koHasError = ko.observable(false); +} - this.choicesEditor = new SurveyPropertyItemValuesEditor(); - this.choicesEditor.object = this.column; - this.choicesEditor.value = this.koChoices(); - this.choicesEditor.options = this.options; +export class SurveyPropertyMatrixDropdownColumnsItem { + private koChoices: any; + public choicesEditor: SurveyPropertyItemValuesEditor; + koName: any; koTitle: any; koCellType: any; koShowChoices: any; + koHasError: any; koColCount: any; koIsRequired: any; koHasOther: any; + koHasChoices: any; koHasColCount: any; + public onShowChoicesClick: any; + public cellTypeChoices: Array; + public colCountChoices: Array; + constructor(public column: Survey.MatrixDropdownColumn, public options = null) { + this.cellTypeChoices = this.getPropertyChoices("cellType"); + this.colCountChoices = this.getPropertyChoices("colCount"); + this.koName = ko.observable(column.name); + this.koCellType = ko.observable(column.cellType); + this.koColCount = ko.observable(column.colCount); + this.koIsRequired = ko.observable(column.isRequired ? true : false); + this.koHasOther = ko.observable(column.hasOther ? true : false); + this.koTitle = ko.observable(column.name === column.title ? "" : column.title); + this.koShowChoices = ko.observable(false); + this.koChoices = ko.observableArray(column.choices); + this.koHasError = ko.observable(false); - var self = this; - this.onShowChoicesClick = function () { self.koShowChoices(!self.koShowChoices()); } - this.koHasChoices = ko.computed(function () { return self.koCellType() == "dropdown" || self.koCellType() == "checkbox" || self.koCellType() == "radiogroup"; }); - this.koHasColCount = ko.computed(function () { return self.koCellType() == "checkbox" || self.koCellType() == "radiogroup"; }); - } - public hasError(): boolean { - this.koHasError(!this.koName()); - return this.koHasError() || this.choicesEditor.hasError(); - } - public apply() { - this.column.name = this.koName(); - this.column.title = this.koTitle(); - this.column.cellType = this.koCellType(); - this.column.colCount = this.koColCount(); - this.column.isRequired = this.koIsRequired(); - this.column.hasOther = this.koHasOther(); + this.choicesEditor = new SurveyPropertyItemValuesEditor(); + this.choicesEditor.object = this.column; + this.choicesEditor.value = this.koChoices(); + this.choicesEditor.options = this.options; - this.choicesEditor.onApplyClick(); - this.column.choices = this.choicesEditor.value; - } - private getPropertyChoices(propetyName: string): Array { - var properties = Survey.JsonObject.metaData.getProperties("matrixdropdowncolumn"); - for (var i = 0; i < properties.length; i++) { - if (properties[i].name == propetyName) return properties[i].choices; - } - return []; + var self = this; + this.onShowChoicesClick = function () { self.koShowChoices(!self.koShowChoices()); } + this.koHasChoices = ko.computed(function () { return self.koCellType() == "dropdown" || self.koCellType() == "checkbox" || self.koCellType() == "radiogroup"; }); + this.koHasColCount = ko.computed(function () { return self.koCellType() == "checkbox" || self.koCellType() == "radiogroup"; }); + } + public hasError(): boolean { + this.koHasError(!this.koName()); + return this.koHasError() || this.choicesEditor.hasError(); + } + public apply() { + this.column.name = this.koName(); + this.column.title = this.koTitle(); + this.column.cellType = this.koCellType(); + this.column.colCount = this.koColCount(); + this.column.isRequired = this.koIsRequired(); + this.column.hasOther = this.koHasOther(); + + this.choicesEditor.onApplyClick(); + this.column.choices = this.choicesEditor.value; + } + private getPropertyChoices(propetyName: string): Array { + var properties = Survey.JsonObject.metaData.getProperties("matrixdropdowncolumn"); + for (var i = 0; i < properties.length; i++) { + if (properties[i].name == propetyName) return properties[i].choices; } + return []; } +} - SurveyPropertyEditorBase.registerEditor("matrixdropdowncolumns", function (): SurveyPropertyEditorBase { return new SurveyPropertyDropdownColumnsEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("matrixdropdowncolumns", function (): SurveyPropertyEditorBase { return new SurveyPropertyDropdownColumnsEditor(); }); \ No newline at end of file diff --git a/src/propertyEditors/propertyModalEditor.ts b/src/propertyEditors/propertyModalEditor.ts index d49773ae40..bf0a53c93e 100644 --- a/src/propertyEditors/propertyModalEditor.ts +++ b/src/propertyEditors/propertyModalEditor.ts @@ -1,64 +1,65 @@ -/// -module SurveyEditor { - export class SurveyPropertyModalEditor extends SurveyPropertyEditorBase { - public object: any; - public title: any; - public onApplyClick: any; - public onResetClick: any; - constructor() { - super() - this.title = ko.observable(); - var self = this; - self.onApplyClick = function () { self.apply(); }; - self.onResetClick = function () { self.reset(); }; - } - public setTitle(value: string) { this.title(value); } - public hasError(): boolean { return false; } - protected onBeforeApply() { } - private reset() { - this.value = this.value; - } - public setObject(value: any) { this.object = value; } - public get isEditable(): boolean { return false; } - private apply() { - if (this.hasError()) return - this.onBeforeApply(); - if (this.onChanged) { - this.onChanged(this.value); - } +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; + +export class SurveyPropertyModalEditor extends SurveyPropertyEditorBase { + public object: any; + public title: any; + public onApplyClick: any; + public onResetClick: any; + constructor() { + super(); + this.title = ko.observable(); + var self = this; + self.onApplyClick = function () { self.apply(); }; + self.onResetClick = function () { self.reset(); }; + } + public setTitle(value: string) { this.title(value); } + public hasError(): boolean { return false; } + protected onBeforeApply() { } + private reset() { + this.value = this.value; + } + public setObject(value: any) { this.object = value; } + public get isEditable(): boolean { return false; } + private apply() { + if (this.hasError()) return; + this.onBeforeApply(); + if (this.onChanged) { + this.onChanged(this.value); } } - export class SurveyPropertyTextEditor extends SurveyPropertyModalEditor { - public koValue: any; +} - constructor() { - super(); - this.koValue = ko.observable(); - } - public get editorType(): string { return "text"; } - public get isEditable(): boolean { return true; } - public getValueText(value: any): string { - if (!value) return null; - var str = value; - if (str.length > 20) { - str = str.substr(0, 20) + "..."; - } - return str; - } - protected onValueChanged() { - this.koValue(this.value); - } - protected onBeforeApply() { - this.setValueCore(this.koValue()); - } +export class SurveyPropertyTextEditor extends SurveyPropertyModalEditor { + public koValue: any; + + constructor() { + super(); + this.koValue = ko.observable(); } - export class SurveyPropertyHtmlEditor extends SurveyPropertyTextEditor { - constructor() { - super(); + public get editorType(): string { return "text"; } + public get isEditable(): boolean { return true; } + public getValueText(value: any): string { + if (!value) return null; + var str = value; + if (str.length > 20) { + str = str.substr(0, 20) + "..."; } - public get editorType(): string { return "html"; } + return str; + } + protected onValueChanged() { + this.koValue(this.value); + } + protected onBeforeApply() { + this.setValueCore(this.koValue()); } - SurveyPropertyEditorBase.registerEditor("text", function (): SurveyPropertyEditorBase { return new SurveyPropertyTextEditor(); }); - SurveyPropertyEditorBase.registerEditor("html", function (): SurveyPropertyEditorBase { return new SurveyPropertyHtmlEditor(); }); - } + +export class SurveyPropertyHtmlEditor extends SurveyPropertyTextEditor { + constructor() { + super(); + } + public get editorType(): string { return "html"; } +} + +SurveyPropertyEditorBase.registerEditor("text", function (): SurveyPropertyEditorBase { return new SurveyPropertyTextEditor(); }); +SurveyPropertyEditorBase.registerEditor("html", function (): SurveyPropertyEditorBase { return new SurveyPropertyHtmlEditor(); }); diff --git a/src/propertyEditors/propertyRestfullEditor.ts b/src/propertyEditors/propertyRestfullEditor.ts index 5db9ecfc40..d7f8483b00 100644 --- a/src/propertyEditors/propertyRestfullEditor.ts +++ b/src/propertyEditors/propertyRestfullEditor.ts @@ -1,64 +1,65 @@ -/// +import {SurveyPropertyModalEditor} from "./propertyModalEditor"; +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; +import {editorLocalization} from "../editorLocalization"; +import * as Survey from "survey-knockout-bootstrap"; -module SurveyEditor { - export class SurveyPropertyResultfullEditor extends SurveyPropertyModalEditor { - koUrl: any; koPath: any; koValueName: any; koTitleName: any; - public survey: Survey.Survey; - public question: Survey.QuestionDropdown; +export class SurveyPropertyResultfullEditor extends SurveyPropertyModalEditor { + koUrl: any; koPath: any; koValueName: any; koTitleName: any; + public survey: Survey.Survey; + public question: Survey.QuestionDropdown; - constructor() { - super(); - this.koUrl = ko.observable(); - this.koPath = ko.observable(); - this.koValueName = ko.observable(); - this.koTitleName = ko.observable(); - this.createSurvey(); - var self = this; - this.koUrl.subscribe(function (newValue) { self.question.choicesByUrl.url = newValue; self.run(); }); - this.koPath.subscribe(function (newValue) { self.question.choicesByUrl.path = newValue; self.run(); }); - this.koValueName.subscribe(function (newValue) { self.question.choicesByUrl.valueName = newValue; self.run(); }); - this.koTitleName.subscribe(function (newValue) { self.question.choicesByUrl.titleName = newValue; self.run(); }); - } - public get editorType(): string { return "restfull"; } - public get restfullValue() { return this.value; } - public getValueText(value: any): string { - if (!value || !value.url) return editorLocalization.getString("pe.empty"); - var str = value.url; - if (str.length > 20) { - str = str.substr(0, 20) + "..."; - } - return str; - } - protected onValueChanged() { - var val = this.restfullValue; - this.koUrl(val ? val.url : ""); - this.koPath(val ? val.path : ""); - this.koValueName(val ? val.valueName : ""); - this.koTitleName(val ? val.titleName : ""); - this.survey.render("restfullSurvey"); - } - protected onBeforeApply() { - var val = new Survey.ChoicesRestfull(); - val.url = this.koUrl(); - val.path = this.koPath(); - val.valueName = this.koValueName(); - val.titleName = this.koTitleName(); - this.setValueCore(val); - } - private run() { - this.question.choicesByUrl.run(); - } - private createSurvey() { - this.survey = new Survey.Survey(); - this.survey.showNavigationButtons = false; - this.survey.showQuestionNumbers = "off"; - var page = this.survey.addNewPage("page1"); - this.question = page.addNewQuestion("dropdown", "q1"); - this.question.title = editorLocalization.getString("pe.testService") - this.question.choices = []; - this.survey.render("restfullSurvey"); + constructor() { + super(); + this.koUrl = ko.observable(); + this.koPath = ko.observable(); + this.koValueName = ko.observable(); + this.koTitleName = ko.observable(); + this.createSurvey(); + var self = this; + this.koUrl.subscribe(function (newValue) { self.question.choicesByUrl.url = newValue; self.run(); }); + this.koPath.subscribe(function (newValue) { self.question.choicesByUrl.path = newValue; self.run(); }); + this.koValueName.subscribe(function (newValue) { self.question.choicesByUrl.valueName = newValue; self.run(); }); + this.koTitleName.subscribe(function (newValue) { self.question.choicesByUrl.titleName = newValue; self.run(); }); + } + public get editorType(): string { return "restfull"; } + public get restfullValue() { return this.value; } + public getValueText(value: any): string { + if (!value || !value.url) return editorLocalization.getString("pe.empty"); + var str = value.url; + if (str.length > 20) { + str = str.substr(0, 20) + "..."; } + return str; + } + protected onValueChanged() { + var val = this.restfullValue; + this.koUrl(val ? val.url : ""); + this.koPath(val ? val.path : ""); + this.koValueName(val ? val.valueName : ""); + this.koTitleName(val ? val.titleName : ""); + this.survey.render("restfullSurvey"); + } + protected onBeforeApply() { + var val = new Survey.ChoicesRestfull(); + val.url = this.koUrl(); + val.path = this.koPath(); + val.valueName = this.koValueName(); + val.titleName = this.koTitleName(); + this.setValueCore(val); + } + private run() { + this.question.choicesByUrl.run(); + } + private createSurvey() { + this.survey = new Survey.Survey(); + this.survey.showNavigationButtons = false; + this.survey.showQuestionNumbers = "off"; + var page = this.survey.addNewPage("page1"); + this.question = page.addNewQuestion("dropdown", "q1"); + this.question.title = editorLocalization.getString("pe.testService") + this.question.choices = []; + this.survey.render("restfullSurvey"); } +} - SurveyPropertyEditorBase.registerEditor("restfull", function (): SurveyPropertyEditorBase { return new SurveyPropertyResultfullEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("restfull", function (): SurveyPropertyEditorBase { return new SurveyPropertyResultfullEditor(); }); \ No newline at end of file diff --git a/src/propertyEditors/propertyTextItemsEditor.ts b/src/propertyEditors/propertyTextItemsEditor.ts index 91ae6ba475..9c5e6572a0 100644 --- a/src/propertyEditors/propertyTextItemsEditor.ts +++ b/src/propertyEditors/propertyTextItemsEditor.ts @@ -1,48 +1,50 @@ -/// -/// -/// -module SurveyEditor { - export class SurveyPropertyTextItemsEditor extends SurveyPropertyItemsEditor { - constructor() { - super(); - } - public get editorType(): string { return "textitems"; } - protected createNewEditorItem(): any { - var objs = []; - var items = this.koItems(); - for (var i = 0; i < items.length; i++) { - objs.push({ name: items[i].koName() }); - } - var editItem = { koName: ko.observable(SurveyHelper.getNewName(objs, "text")), koTitle: ko.observable() }; - this.createValidatorsEditor(editItem, []); - return editItem; - } - protected createEditorItem(item: any) { - var editItem = { koName: ko.observable(item.name), koTitle: ko.observable(item.title) }; - this.createValidatorsEditor(editItem, item.validators); - return editItem; - } - protected createItemFromEditorItem(editorItem: any) { - var itemText = new Survey.MultipleTextItem(editorItem.koName(), editorItem.koTitle()); - itemText.validators = editorItem.validators; - return itemText; - } - private createValidatorsEditor(item: any, validators: Array) { - item.validators = validators.slice(); - var self = this; - var onItemChanged = function (newValue: any) { item.validators = newValue; item.koText(self.getText(newValue.length)); }; - var propertyEditor = new SurveyPropertyValidatorsEditor(); - item.editor = propertyEditor; - propertyEditor.onChanged = (newValue: any) => { onItemChanged(newValue); }; - propertyEditor.object = item; - propertyEditor.title(editorLocalization.getString("pe.editProperty")["format"]("Validators")); - propertyEditor.value = item.validators; - item.koText = ko.observable(this.getText(validators.length)); - } - private getText(length: number): string { - return editorLocalization.getString("pe.items")["format"](length); +import {SurveyPropertyItemsEditor} from "./propertyItemsEditor"; +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; +import {SurveyHelper} from "../surveyHelper"; +import {editorLocalization} from "../editorLocalization"; +import {SurveyPropertyValidatorsEditor} from "./propertyValidatorsEditor"; +import * as Survey from "survey-knockout-bootstrap"; + +export class SurveyPropertyTextItemsEditor extends SurveyPropertyItemsEditor { + constructor() { + super(); + } + public get editorType(): string { return "textitems"; } + protected createNewEditorItem(): any { + var objs = []; + var items = this.koItems(); + for (var i = 0; i < items.length; i++) { + objs.push({ name: items[i].koName() }); } + var editItem = { koName: ko.observable(SurveyHelper.getNewName(objs, "text")), koTitle: ko.observable() }; + this.createValidatorsEditor(editItem, []); + return editItem; + } + protected createEditorItem(item: any) { + var editItem = { koName: ko.observable(item.name), koTitle: ko.observable(item.title) }; + this.createValidatorsEditor(editItem, item.validators); + return editItem; + } + protected createItemFromEditorItem(editorItem: any) { + var itemText = new Survey.MultipleTextItem(editorItem.koName(), editorItem.koTitle()); + itemText.validators = editorItem.validators; + return itemText; + } + private createValidatorsEditor(item: any, validators: Array) { + item.validators = validators.slice(); + var self = this; + var onItemChanged = function (newValue: any) { item.validators = newValue; item.koText(self.getText(newValue.length)); }; + var propertyEditor = new SurveyPropertyValidatorsEditor(); + item.editor = propertyEditor; + propertyEditor.onChanged = (newValue: any) => { onItemChanged(newValue); }; + propertyEditor.object = item; + propertyEditor.title(editorLocalization.getString("pe.editProperty")["format"]("Validators")); + propertyEditor.value = item.validators; + item.koText = ko.observable(this.getText(validators.length)); + } + private getText(length: number): string { + return editorLocalization.getString("pe.items")["format"](length); } +} - SurveyPropertyEditorBase.registerEditor("textitems", function (): SurveyPropertyEditorBase { return new SurveyPropertyTextItemsEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("textitems", function (): SurveyPropertyEditorBase { return new SurveyPropertyTextItemsEditor(); }); \ No newline at end of file diff --git a/src/propertyEditors/propertyTriggersEditor.ts b/src/propertyEditors/propertyTriggersEditor.ts index 560335e3b3..14b6cd7e4c 100644 --- a/src/propertyEditors/propertyTriggersEditor.ts +++ b/src/propertyEditors/propertyTriggersEditor.ts @@ -1,200 +1,200 @@ -/// -/// -/// -module SurveyEditor { - export class SurveyPropertyTriggersEditor extends SurveyPropertyItemsEditor { - koQuestions: any; koPages: any; - public koSelected: any; - public availableTriggers: Array = []; - private triggerClasses: Array = []; - constructor() { - super(); - var self = this; - this.onDeleteClick = function () { self.koItems.remove(self.koSelected()); } - this.onAddClick = function (triggerType) { self.addItem(triggerType); } - this.koSelected = ko.observable(null); - this.koPages = ko.observableArray(); - this.koQuestions = ko.observableArray(); - this.triggerClasses = Survey.JsonObject.metaData.getChildrenClasses("surveytrigger", true); - this.availableTriggers = this.getAvailableTriggers(); - } - public get editorType(): string { return "triggers"; } - protected onValueChanged() { - super.onValueChanged(); - if (this.object) { - this.koPages(this.getNames((this.object).pages)); - this.koQuestions(this.getNames((this.object).getAllQuestions())); - } - if (this.koSelected) { - this.koSelected(this.koItems().length > 0 ? this.koItems()[0] : null); - } - } +import {SurveyPropertyItemsEditor} from "./propertyItemsEditor"; +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; +import {editorLocalization} from "../editorLocalization"; +import * as Survey from "survey-knockout-bootstrap"; - private addItem(triggerType: string) { - var trigger = Survey.JsonObject.metaData.createClass(triggerType); - var triggerItem = this.createPropertyTrigger(trigger); - this.koItems.push(triggerItem); - this.koSelected(triggerItem); - } - protected createEditorItem(item: any) { - var jsonObj = new Survey.JsonObject(); - var trigger = Survey.JsonObject.metaData.createClass(item.getType()); - jsonObj.toObject(item, trigger); - return this.createPropertyTrigger(trigger); - } - protected createItemFromEditorItem(editorItem: any) { - var editorTrigger = editorItem; - return editorTrigger.createTrigger(); - } - private getAvailableTriggers(): Array { - var result = []; - for (var i = 0; i < this.triggerClasses.length; i++) { - result.push(this.triggerClasses[i].name); - } - return result; - } - private getNames(items: Array): Array { - var names = []; - for (var i = 0; i < items.length; i++) { - var item = items[i]; - if (item["name"]) { - names.push(item["name"]); - } - } - return names; +export class SurveyPropertyTriggersEditor extends SurveyPropertyItemsEditor { + koQuestions: any; koPages: any; + public koSelected: any; + public availableTriggers: Array = []; + private triggerClasses: Array = []; + constructor() { + super(); + var self = this; + this.onDeleteClick = function () { self.koItems.remove(self.koSelected()); }; + this.onAddClick = function (triggerType) { self.addItem(triggerType); }; + this.koSelected = ko.observable(null); + this.koPages = ko.observableArray(); + this.koQuestions = ko.observableArray(); + this.triggerClasses = Survey.JsonObject.metaData.getChildrenClasses("surveytrigger", true); + this.availableTriggers = this.getAvailableTriggers(); + } + public get editorType(): string { return "triggers"; } + protected onValueChanged() { + super.onValueChanged(); + if (this.object) { + this.koPages(this.getNames((this.object).pages)); + this.koQuestions(this.getNames((this.object).getAllQuestions())); } - private createPropertyTrigger(trigger: Survey.SurveyTrigger): SurveyPropertyTrigger { - var triggerItem = null; - if (trigger.getType() == "visibletrigger") { - triggerItem = new SurveyPropertyVisibleTrigger(trigger, this.koPages, this.koQuestions); - } - if (trigger.getType() == "setvaluetrigger") { - triggerItem = new SurveyPropertySetValueTrigger(trigger, this.koQuestions); - } - if (!triggerItem) { - triggerItem = new SurveyPropertyTrigger(trigger); - } - return triggerItem; + if (this.koSelected) { + this.koSelected(this.koItems().length > 0 ? this.koItems()[0] : null); } } - export class SurveyPropertyTrigger { - private operators = ["empty", "notempty", "equal", "notequal", "contains", "notcontains", "greater", "less", "greaterorequal", "lessorequal"]; - private triggerType: string; - availableOperators = []; - koName: any; koOperator: any; koValue: any; koType: any; - koText: any; koIsValid: any; koRequireValue: any; - constructor(public trigger: Survey.SurveyTrigger) { - this.createOperators(); - this.triggerType = trigger.getType(); - this.koType = ko.observable(this.triggerType); - this.koName = ko.observable(trigger.name); - this.koOperator = ko.observable(trigger.operator); - this.koValue = ko.observable(trigger.value); - var self = this; - this.koRequireValue = ko.computed(() => { return self.koOperator() != "empty" && self.koOperator() != "notempty"; }); - this.koIsValid = ko.computed(() => { if (self.koName() && (!self.koRequireValue() || self.koValue())) return true; return false; }); - this.koText = ko.computed(() => { self.koName(); self.koOperator(); self.koValue(); return self.getText(); }); - } - public createTrigger(): Survey.SurveyTrigger { - var trigger = Survey.JsonObject.metaData.createClass(this.triggerType); - trigger.name = this.koName(); - trigger.operator = this.koOperator(); - trigger.value = this.koValue(); - return trigger; + private addItem(triggerType: string) { + var trigger = Survey.JsonObject.metaData.createClass(triggerType); + var triggerItem = this.createPropertyTrigger(trigger); + this.koItems.push(triggerItem); + this.koSelected(triggerItem); + } + protected createEditorItem(item: any) { + var jsonObj = new Survey.JsonObject(); + var trigger = Survey.JsonObject.metaData.createClass(item.getType()); + jsonObj.toObject(item, trigger); + return this.createPropertyTrigger(trigger); + } + protected createItemFromEditorItem(editorItem: any) { + var editorTrigger = editorItem; + return editorTrigger.createTrigger(); + } + private getAvailableTriggers(): Array { + var result = []; + for (var i = 0; i < this.triggerClasses.length; i++) { + result.push(this.triggerClasses[i].name); } - private createOperators() { - for (var i = 0; i < this.operators.length; i++) { - var name = this.operators[i]; - this.availableOperators.push({ name: name, text: editorLocalization.getString("op." + name) }); + return result; + } + private getNames(items: Array): Array { + var names = []; + for (var i = 0; i < items.length; i++) { + var item = items[i]; + if (item["name"]) { + names.push(item["name"]); } } - private getText(): string { - if (!this.koIsValid()) return editorLocalization.getString("pe.triggerNotSet"); - return editorLocalization.getString("pe.triggerRunIf") + " '" + this.koName() + "' " + this.getOperatorText() + this.getValueText(); + return names; + } + private createPropertyTrigger(trigger: Survey.SurveyTrigger): SurveyPropertyTrigger { + var triggerItem = null; + if (trigger.getType() == "visibletrigger") { + triggerItem = new SurveyPropertyVisibleTrigger(trigger, this.koPages, this.koQuestions); } - private getOperatorText(): string { - var op = this.koOperator(); - for (var i = 0; i < this.availableOperators.length; i++) { - if (this.availableOperators[i].name == op) return this.availableOperators[i].text; - } - return op; + if (trigger.getType() == "setvaluetrigger") { + triggerItem = new SurveyPropertySetValueTrigger(trigger, this.koQuestions); } - private getValueText(): string { - if (!this.koRequireValue()) return ""; - return " " + this.koValue(); + if (!triggerItem) { + triggerItem = new SurveyPropertyTrigger(trigger); } + return triggerItem; } +} +export class SurveyPropertyTrigger { + private operators = ["empty", "notempty", "equal", "notequal", "contains", "notcontains", "greater", "less", "greaterorequal", "lessorequal"]; + private triggerType: string; + availableOperators = []; + koName: any; koOperator: any; koValue: any; koType: any; + koText: any; koIsValid: any; koRequireValue: any; - export class SurveyPropertyVisibleTrigger extends SurveyPropertyTrigger { - public pages: SurveyPropertyTriggerObjects; - public questions: SurveyPropertyTriggerObjects; - constructor(public trigger: Survey.SurveyTriggerVisible, koPages: any, koQuestions: any) { - super(trigger); - this.pages = new SurveyPropertyTriggerObjects(editorLocalization.getString("pe.triggerMakePagesVisible"), koPages(), trigger.pages); - this.questions = new SurveyPropertyTriggerObjects(editorLocalization.getString("pe.triggerMakeQuestionsVisible"), koQuestions(), trigger.questions); + constructor(public trigger: Survey.SurveyTrigger) { + this.createOperators(); + this.triggerType = trigger.getType(); + this.koType = ko.observable(this.triggerType); + this.koName = ko.observable(trigger.name); + this.koOperator = ko.observable(trigger.operator); + this.koValue = ko.observable(trigger.value); + var self = this; + this.koRequireValue = ko.computed(() => { return self.koOperator() != "empty" && self.koOperator() != "notempty"; }); + this.koIsValid = ko.computed(() => { if (self.koName() && (!self.koRequireValue() || self.koValue())) return true; return false; }); + this.koText = ko.computed(() => { self.koName(); self.koOperator(); self.koValue(); return self.getText(); }); + } + public createTrigger(): Survey.SurveyTrigger { + var trigger = Survey.JsonObject.metaData.createClass(this.triggerType); + trigger.name = this.koName(); + trigger.operator = this.koOperator(); + trigger.value = this.koValue(); + return trigger; + } + private createOperators() { + for (var i = 0; i < this.operators.length; i++) { + var name = this.operators[i]; + this.availableOperators.push({ name: name, text: editorLocalization.getString("op." + name) }); } - public createTrigger(): Survey.SurveyTrigger { - var trigger = super.createTrigger(); - trigger.pages = this.pages.koChoosen(); - trigger.questions = this.questions.koChoosen(); - return trigger; + } + private getText(): string { + if (!this.koIsValid()) return editorLocalization.getString("pe.triggerNotSet"); + return editorLocalization.getString("pe.triggerRunIf") + " '" + this.koName() + "' " + this.getOperatorText() + this.getValueText(); + } + private getOperatorText(): string { + var op = this.koOperator(); + for (var i = 0; i < this.availableOperators.length; i++) { + if (this.availableOperators[i].name == op) return this.availableOperators[i].text; } + return op; + } + private getValueText(): string { + if (!this.koRequireValue()) return ""; + return " " + this.koValue(); } +} - export class SurveyPropertySetValueTrigger extends SurveyPropertyTrigger { - koQuestions: any; kosetToName: any; kosetValue: any; koisVariable: any; - constructor(public trigger: Survey.SurveyTriggerSetValue, koQuestions: any) { - super(trigger); - this.koQuestions = koQuestions; - this.kosetToName = ko.observable(trigger.setToName); - this.kosetValue = ko.observable(trigger.setValue); - this.koisVariable = ko.observable(trigger.isVariable); - } - public createTrigger(): Survey.SurveyTrigger { - var trigger = super.createTrigger(); - trigger.setToName = this.kosetToName(); - trigger.setValue = this.kosetValue(); - trigger.isVariable = this.koisVariable(); - return trigger; - } +export class SurveyPropertyVisibleTrigger extends SurveyPropertyTrigger { + public pages: SurveyPropertyTriggerObjects; + public questions: SurveyPropertyTriggerObjects; + constructor(public trigger: Survey.SurveyTriggerVisible, koPages: any, koQuestions: any) { + super(trigger); + this.pages = new SurveyPropertyTriggerObjects(editorLocalization.getString("pe.triggerMakePagesVisible"), koPages(), trigger.pages); + this.questions = new SurveyPropertyTriggerObjects(editorLocalization.getString("pe.triggerMakeQuestionsVisible"), koQuestions(), trigger.questions); + } + public createTrigger(): Survey.SurveyTrigger { + var trigger = super.createTrigger(); + trigger.pages = this.pages.koChoosen(); + trigger.questions = this.questions.koChoosen(); + return trigger; } - export class SurveyPropertyTriggerObjects { - koObjects: any; - koChoosen: any; - koSelected: any; - koChoosenSelected: any; - public onDeleteClick: any; - public onAddClick: any; - constructor(public title: string, allObjects: Array, choosenObjects: Array) { - this.koChoosen = ko.observableArray(choosenObjects); - var array = []; - for (var i = 0; i < allObjects.length; i++) { - var item = allObjects[i]; - if (choosenObjects.indexOf(item) < 0) { - array.push(item); - } +} + +export class SurveyPropertySetValueTrigger extends SurveyPropertyTrigger { + koQuestions: any; kosetToName: any; kosetValue: any; koisVariable: any; + constructor(public trigger: Survey.SurveyTriggerSetValue, koQuestions: any) { + super(trigger); + this.koQuestions = koQuestions; + this.kosetToName = ko.observable(trigger.setToName); + this.kosetValue = ko.observable(trigger.setValue); + this.koisVariable = ko.observable(trigger.isVariable); + } + public createTrigger(): Survey.SurveyTrigger { + var trigger = super.createTrigger(); + trigger.setToName = this.kosetToName(); + trigger.setValue = this.kosetValue(); + trigger.isVariable = this.koisVariable(); + return trigger; + } +} +export class SurveyPropertyTriggerObjects { + koObjects: any; + koChoosen: any; + koSelected: any; + koChoosenSelected: any; + public onDeleteClick: any; + public onAddClick: any; + constructor(public title: string, allObjects: Array, choosenObjects: Array) { + this.koChoosen = ko.observableArray(choosenObjects); + var array = []; + for (var i = 0; i < allObjects.length; i++) { + var item = allObjects[i]; + if (choosenObjects.indexOf(item) < 0) { + array.push(item); } - this.koObjects = ko.observableArray(array); - this.koSelected = ko.observable(); - this.koChoosenSelected = ko.observable(); - var self = this; - this.onDeleteClick = function () { self.deleteItem(); } - this.onAddClick = function () { self.addItem(); } - } - private deleteItem() { - this.changeItems(this.koChoosenSelected(), this.koChoosen, this.koObjects); - } - private addItem() { - this.changeItems(this.koSelected(), this.koObjects, this.koChoosen); - } - private changeItems(item: string, removedFrom: any, addTo: any) { - removedFrom.remove(item); - addTo.push(item); - removedFrom.sort(); - addTo.sort(); } + this.koObjects = ko.observableArray(array); + this.koSelected = ko.observable(); + this.koChoosenSelected = ko.observable(); + var self = this; + this.onDeleteClick = function () { self.deleteItem(); }; + this.onAddClick = function () { self.addItem(); } + } + private deleteItem() { + this.changeItems(this.koChoosenSelected(), this.koChoosen, this.koObjects); + } + private addItem() { + this.changeItems(this.koSelected(), this.koObjects, this.koChoosen); + } + private changeItems(item: string, removedFrom: any, addTo: any) { + removedFrom.remove(item); + addTo.push(item); + removedFrom.sort(); + addTo.sort(); } +} - SurveyPropertyEditorBase.registerEditor("triggers", function (): SurveyPropertyEditorBase { return new SurveyPropertyTriggersEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("triggers", function (): SurveyPropertyEditorBase { return new SurveyPropertyTriggersEditor(); }); \ No newline at end of file diff --git a/src/propertyEditors/propertyValidatorsEditor.ts b/src/propertyEditors/propertyValidatorsEditor.ts index 274759d191..74cd7d86f3 100644 --- a/src/propertyEditors/propertyValidatorsEditor.ts +++ b/src/propertyEditors/propertyValidatorsEditor.ts @@ -1,68 +1,68 @@ -/// -/// -/// -module SurveyEditor { - export class SurveyPropertyValidatorsEditor extends SurveyPropertyItemsEditor { - private selectedObjectEditor: SurveyObjectEditor; - public koSelected: any; - public availableValidators: Array = []; - private validatorClasses: Array = []; - constructor() { - super(); - var self = this; - this.selectedObjectEditor = new SurveyObjectEditor(); - this.selectedObjectEditor.onPropertyValueChanged.add((sender, options) => { - self.onPropertyValueChanged(options.property, options.object, options.newValue); - }); - this.koSelected = ko.observable(null); - this.koSelected.subscribe(function (newValue) { self.selectedObjectEditor.selectedObject = newValue != null ? newValue.validator : null; }); - this.validatorClasses = Survey.JsonObject.metaData.getChildrenClasses("surveyvalidator", true); - this.availableValidators = this.getAvailableValidators(); - this.onDeleteClick = function () { self.koItems.remove(self.koSelected()); } - this.onAddClick = function (validatorType) { self.addItem(validatorType); } - } - public get editorType(): string { return "validators"; } - protected onValueChanged() { - super.onValueChanged(); - if (this.koSelected) { - this.koSelected(this.koItems().length > 0 ? this.koItems()[0] : null); - } - } - protected createEditorItem(item: any) { - var jsonObj = new Survey.JsonObject(); - var validator = Survey.JsonObject.metaData.createClass(item.getType()); - jsonObj.toObject(item, validator); - return new SurveyPropertyValidatorItem(validator); - } - protected createItemFromEditorItem(editorItem: any) { - var item = editorItem; - return item.validator; - } - private addItem(validatorType: string) { - var newValidator = new SurveyPropertyValidatorItem(Survey.JsonObject.metaData.createClass(validatorType)); - this.koItems.push(newValidator); - this.koSelected(newValidator); - } - private getAvailableValidators(): Array { - var result = []; - for (var i = 0; i < this.validatorClasses.length; i++) { - result.push(this.validatorClasses[i].name); - } - return result; +import {SurveyPropertyItemsEditor} from "./propertyItemsEditor"; +import {SurveyPropertyEditorBase} from "./propertyEditorBase"; +import {SurveyObjectEditor} from "../objectEditor"; +import * as Survey from "survey-knockout-bootstrap"; + +export class SurveyPropertyValidatorsEditor extends SurveyPropertyItemsEditor { + private selectedObjectEditor: SurveyObjectEditor; + public koSelected: any; + public availableValidators: Array = []; + private validatorClasses: Array = []; + constructor() { + super(); + var self = this; + this.selectedObjectEditor = new SurveyObjectEditor(); + this.selectedObjectEditor.onPropertyValueChanged.add((sender, options) => { + self.onPropertyValueChanged(options.property, options.object, options.newValue); + }); + this.koSelected = ko.observable(null); + this.koSelected.subscribe(function (newValue) { self.selectedObjectEditor.selectedObject = newValue != null ? newValue.validator : null; }); + this.validatorClasses = Survey.JsonObject.metaData.getChildrenClasses("surveyvalidator", true); + this.availableValidators = this.getAvailableValidators(); + this.onDeleteClick = function () { self.koItems.remove(self.koSelected()); }; + this.onAddClick = function (validatorType) { self.addItem(validatorType); }; + } + public get editorType(): string { return "validators"; } + protected onValueChanged() { + super.onValueChanged(); + if (this.koSelected) { + this.koSelected(this.koItems().length > 0 ? this.koItems()[0] : null); } - private onPropertyValueChanged(property: Survey.JsonObjectProperty, obj: any, newValue: any) { - if (this.koSelected() == null) return; - this.koSelected().validator[property.name] = newValue; + } + protected createEditorItem(item: any) { + var jsonObj = new Survey.JsonObject(); + var validator = Survey.JsonObject.metaData.createClass(item.getType()); + jsonObj.toObject(item, validator); + return new SurveyPropertyValidatorItem(validator); + } + protected createItemFromEditorItem(editorItem: any) { + var item = editorItem; + return item.validator; + } + private addItem(validatorType: string) { + var newValidator = new SurveyPropertyValidatorItem(Survey.JsonObject.metaData.createClass(validatorType)); + this.koItems.push(newValidator); + this.koSelected(newValidator); + } + private getAvailableValidators(): Array { + var result = []; + for (var i = 0; i < this.validatorClasses.length; i++) { + result.push(this.validatorClasses[i].name); } + return result; + } + private onPropertyValueChanged(property: Survey.JsonObjectProperty, obj: any, newValue: any) { + if (this.koSelected() == null) return; + this.koSelected().validator[property.name] = newValue; } +} - export class SurveyPropertyValidatorItem { - public text: string; - constructor(public validator: Survey.SurveyValidator) { - this.text = validator.getType(); - } +export class SurveyPropertyValidatorItem { + public text: string; + constructor(public validator: Survey.SurveyValidator) { + this.text = validator.getType(); } +} - SurveyPropertyEditorBase.registerEditor("validators", function (): SurveyPropertyEditorBase { return new SurveyPropertyValidatorsEditor(); }); -} \ No newline at end of file +SurveyPropertyEditorBase.registerEditor("validators", function (): SurveyPropertyEditorBase { return new SurveyPropertyValidatorsEditor(); }); \ No newline at end of file diff --git a/src/surveyEmbedingWindow.ts b/src/surveyEmbedingWindow.ts index bf5d8710f7..a135007b50 100644 --- a/src/surveyEmbedingWindow.ts +++ b/src/surveyEmbedingWindow.ts @@ -1,112 +1,112 @@ -module SurveyEditor { - export class SurveyEmbedingWindow { - private jsonValue: any; - private surveyEmbedingHead: AceAjax.Editor; - private surveyEmbedingJava: AceAjax.Editor; - public surveyId: string = null; - public surveyPostId: string = null; - public generateValidJSON: boolean = false; - koShowAsWindow: any; - koScriptUsing: any; - koHasIds: any; - koLoadSurvey: any; - koLibraryVersion: any; - koVisibleHtml: any; - constructor() { - var self = this; - this.koLibraryVersion = ko.observable("knockout"); - this.koShowAsWindow = ko.observable("page"); - this.koScriptUsing = ko.observable("bootstrap"); - this.koHasIds = ko.observable(false); - this.koLoadSurvey = ko.observable(false); - this.koVisibleHtml = ko.computed(function() { return self.koLibraryVersion() == "react" || self.koShowAsWindow() =="page"; }); - this.koLibraryVersion.subscribe(function (newValue) { self.setHeadText(); self.surveyEmbedingJava.setValue(self.getJavaText()); }); - this.koShowAsWindow.subscribe(function (newValue) { self.surveyEmbedingJava.setValue(self.getJavaText()); }); - this.koScriptUsing.subscribe(function (newValue) { self.setHeadText(); self.surveyEmbedingJava.setValue(self.getJavaText()); }); - this.koLoadSurvey.subscribe(function (newValue) { self.surveyEmbedingJava.setValue(self.getJavaText()); }); - this.surveyEmbedingHead = null; - } - public get json(): any { return this.jsonValue; } - public set json(value: any) { this.jsonValue = value; } - public show() { - if (this.surveyEmbedingHead == null) { - this.surveyEmbedingHead = this.createEditor("surveyEmbedingHead"); - this.setHeadText(); - var bodyEditor = this.createEditor("surveyEmbedingBody"); - bodyEditor.setValue("
"); - this.surveyEmbedingJava = this.createEditor("surveyEmbedingJava"); - } - this.koHasIds(this.surveyId && this.surveyPostId); - this.surveyEmbedingJava.setValue(this.getJavaText()); - } - private setHeadText() { - var str = ""; - if (this.koLibraryVersion() == "knockout") { - str = "\n"; - } else { - str = "\n\n\n"; - str += ""; - } - if (this.koScriptUsing() != "bootstrap") { - str += "\n"; - } - this.surveyEmbedingHead.setValue(str); +import {SurveyJSON5} from "./json5"; + +export class SurveyEmbedingWindow { + private jsonValue: any; + private surveyEmbedingHead: AceAjax.Editor; + private surveyEmbedingJava: AceAjax.Editor; + public surveyId: string = null; + public surveyPostId: string = null; + public generateValidJSON: boolean = false; + koShowAsWindow: any; + koScriptUsing: any; + koHasIds: any; + koLoadSurvey: any; + koLibraryVersion: any; + koVisibleHtml: any; + constructor() { + var self = this; + this.koLibraryVersion = ko.observable("knockout"); + this.koShowAsWindow = ko.observable("page"); + this.koScriptUsing = ko.observable("bootstrap"); + this.koHasIds = ko.observable(false); + this.koLoadSurvey = ko.observable(false); + this.koVisibleHtml = ko.computed(function() { return self.koLibraryVersion() == "react" || self.koShowAsWindow() =="page"; }); + this.koLibraryVersion.subscribe(function (newValue) { self.setHeadText(); self.surveyEmbedingJava.setValue(self.getJavaText()); }); + this.koShowAsWindow.subscribe(function (newValue) { self.surveyEmbedingJava.setValue(self.getJavaText()); }); + this.koScriptUsing.subscribe(function (newValue) { self.setHeadText(); self.surveyEmbedingJava.setValue(self.getJavaText()); }); + this.koLoadSurvey.subscribe(function (newValue) { self.surveyEmbedingJava.setValue(self.getJavaText()); }); + this.surveyEmbedingHead = null; + } + public get json(): any { return this.jsonValue; } + public set json(value: any) { this.jsonValue = value; } + public show() { + if (this.surveyEmbedingHead == null) { + this.surveyEmbedingHead = this.createEditor("surveyEmbedingHead"); + this.setHeadText(); + var bodyEditor = this.createEditor("surveyEmbedingBody"); + bodyEditor.setValue("
"); + this.surveyEmbedingJava = this.createEditor("surveyEmbedingJava"); } - private createEditor(elementName: string): AceAjax.Editor { - var editor = ace.edit(elementName); - editor.setTheme("ace/theme/monokai"); - editor.session.setMode("ace/mode/json"); - editor.setShowPrintMargin(false); - editor.renderer.setShowGutter(false); - editor.setReadOnly(true); - return editor; + this.koHasIds(this.surveyId && this.surveyPostId); + this.surveyEmbedingJava.setValue(this.getJavaText()); + } + private setHeadText() { + var str = ""; + if (this.koLibraryVersion() == "knockout") { + str = "\n"; + } else { + str = "\n\n\n"; + str += ""; } - private getJavaText(): string { - var isOnPage = this.koShowAsWindow() == "page"; - var str = this.koLibraryVersion() == "knockout" ? this.getKnockoutJavaText(isOnPage) : this.getReactJavaText(isOnPage); - return this.getSetCss() + str; + if (this.koScriptUsing() != "bootstrap") { + str += "\n"; } - private getSetCss(): string { - if (this.koScriptUsing() != "bootstrap") return ""; - return "Survey.Survey.cssType = \"bootstrap\";\n"; + this.surveyEmbedingHead.setValue(str); + } + private createEditor(elementName: string): AceAjax.Editor { + var editor = ace.edit(elementName); + editor.setTheme("ace/theme/monokai"); + editor.session.setMode("ace/mode/json"); + editor.setShowPrintMargin(false); + editor.renderer.setShowGutter(false); + editor.setReadOnly(true); + return editor; + } + private getJavaText(): string { + var isOnPage = this.koShowAsWindow() == "page"; + var str = this.koLibraryVersion() == "knockout" ? this.getKnockoutJavaText(isOnPage) : this.getReactJavaText(isOnPage); + return this.getSetCss() + str; + } + private getSetCss(): string { + if (this.koScriptUsing() != "bootstrap") return ""; + return "Survey.Survey.cssType = \"bootstrap\";\n"; + } + private getKnockoutJavaText(isOnPage: boolean): string { + var text = isOnPage ? "var survey = new Survey.Survey(\n" : "var surveyWindow = new Survey.SurveyWindow(\n"; + text += this.getJsonText(); + text += ");\n"; + if (!isOnPage) { + text += "surveyWindow."; } - private getKnockoutJavaText(isOnPage: boolean): string { - var text = isOnPage ? "var survey = new Survey.Survey(\n" : "var surveyWindow = new Survey.SurveyWindow(\n"; - text += this.getJsonText(); - text += ");\n"; - if (!isOnPage) { - text += "surveyWindow."; - } - var saveFunc = this.getSaveFuncCode(); - text += "survey.onComplete.add(function (s) {\n" + saveFunc + "\n });\n"; - if (isOnPage) { - text += "survey.render(\"mySurveyJSName\");"; - } else { - text += "//By default Survey.title is used.\n" - text += "//surveyWindow.title = \"My Survey Window Title.\";\n"; - text += "surveyWindow.show();"; + var saveFunc = this.getSaveFuncCode(); + text += "survey.onComplete.add(function (s) {\n" + saveFunc + "\n });\n"; + if (isOnPage) { + text += "survey.render(\"mySurveyJSName\");"; + } else { + text += "//By default Survey.title is used.\n" + text += "//surveyWindow.title = \"My Survey Window Title.\";\n"; + text += "surveyWindow.show();"; - } - return text; - } - private getReactJavaText(isOnPage: boolean): string { - var saveFunc = this.getSaveFuncCode(); - var sendResultText = "var surveySendResult = function (s) {\n" + saveFunc + "\n });\n"; - var name = isOnPage ? "ReactSurvey" : "ReactSurveyWindow"; - var jsonText = "var surveyJson = " + this.getJsonText() + "\n\n"; - var text = jsonText + sendResultText + "ReactDOM.render(\n<" + name + " json={surveyJson} onComplete={surveySendResult} />, \n document.getElementById(\"mySurveyJSName\"));"; - return text; - } - private getSaveFuncCode() { - if (this.koHasIds()) return "survey.sendResult('" + this.surveyPostId + "');"; - return "alert(\"The results are:\" + JSON.stringify(s.data));"; } - private getJsonText(): string { - if (this.koHasIds() && this.koLoadSurvey()) { - return "{ surveyId: '" + this.surveyId + "'}"; - } - if (this.generateValidJSON) return JSON.stringify(this.json); - return new SurveyJSON5().stringify(this.json); + return text; + } + private getReactJavaText(isOnPage: boolean): string { + var saveFunc = this.getSaveFuncCode(); + var sendResultText = "var surveySendResult = function (s) {\n" + saveFunc + "\n });\n"; + var name = isOnPage ? "ReactSurvey" : "ReactSurveyWindow"; + var jsonText = "var surveyJson = " + this.getJsonText() + "\n\n"; + var text = jsonText + sendResultText + "ReactDOM.render(\n<" + name + " json={surveyJson} onComplete={surveySendResult} />, \n document.getElementById(\"mySurveyJSName\"));"; + return text; + } + private getSaveFuncCode() { + if (this.koHasIds()) return "survey.sendResult('" + this.surveyPostId + "');"; + return "alert(\"The results are:\" + JSON.stringify(s.data));"; + } + private getJsonText(): string { + if (this.koHasIds() && this.koLoadSurvey()) { + return "{ surveyId: '" + this.surveyId + "'}"; } + if (this.generateValidJSON) return JSON.stringify(this.json); + return new SurveyJSON5().stringify(this.json); } } \ No newline at end of file diff --git a/src/surveyHelper.ts b/src/surveyHelper.ts index c40f7d56fa..a33100a85e 100644 --- a/src/surveyHelper.ts +++ b/src/surveyHelper.ts @@ -1,38 +1,39 @@ -module SurveyEditor { - export enum ObjType { Unknown, Survey, Page, Question } - export class SurveyHelper { - public static getNewPageName(objs: Array) { - return SurveyHelper.getNewName(objs, editorLocalization.getString("ed.newPageName")); - } - public static getNewQuestionName(objs: Array) { - return SurveyHelper.getNewName(objs, editorLocalization.getString("ed.newQuestionName")); - } - public static getNewName(objs: Array, baseName: string): string { - var hash = {}; - for (var i = 0; i < objs.length; i++) { - hash[objs[i].name] = true; - } - var num = 1; - while (true) { - if (!hash[baseName + num.toString()]) break; - num++; - } - return baseName + num.toString(); - } - public static getObjectType(obj: any): ObjType { - if (!obj || !obj["getType"]) return ObjType.Unknown; - if (obj.getType() == "page") return ObjType.Page; - if (obj.getType() == "survey") return ObjType.Survey; - if (obj["name"]) return ObjType.Question; - return ObjType.Unknown; +import {editorLocalization} from "./editorLocalization"; +import * as Survey from "survey-knockout-bootstrap"; + +export enum ObjType { Unknown, Survey, Page, Question } +export class SurveyHelper { + public static getNewPageName(objs: Array) { + return SurveyHelper.getNewName(objs, editorLocalization.getString("ed.newPageName")); + } + public static getNewQuestionName(objs: Array) { + return SurveyHelper.getNewName(objs, editorLocalization.getString("ed.newQuestionName")); + } + public static getNewName(objs: Array, baseName: string): string { + var hash = {}; + for (var i = 0; i < objs.length; i++) { + hash[objs[i].name] = true; } - public static getObjectName(obj: any): string { - if (obj["name"]) return obj["name"]; - var objType = SurveyHelper.getObjectType(obj); - if (objType != ObjType.Page) return ""; - var data = (obj).data; - var index = data.pages.indexOf(obj); - return "[Page " + (index + 1) + "]"; + var num = 1; + while (true) { + if (!hash[baseName + num.toString()]) break; + num++; } + return baseName + num.toString(); + } + public static getObjectType(obj: any): ObjType { + if (!obj || !obj["getType"]) return ObjType.Unknown; + if (obj.getType() == "page") return ObjType.Page; + if (obj.getType() == "survey") return ObjType.Survey; + if (obj["name"]) return ObjType.Question; + return ObjType.Unknown; + } + public static getObjectName(obj: any): string { + if (obj["name"]) return obj["name"]; + var objType = SurveyHelper.getObjectType(obj); + if (objType != ObjType.Page) return ""; + var data = (obj).data; + var index = data.pages.indexOf(obj); + return "[Page " + (index + 1) + "]"; } } \ No newline at end of file diff --git a/src/surveyObjects.ts b/src/surveyObjects.ts index ad8b450b4b..1d742d081e 100644 --- a/src/surveyObjects.ts +++ b/src/surveyObjects.ts @@ -1,147 +1,147 @@ -module SurveyEditor { +import {SurveyHelper, ObjType} from "./surveyHelper"; +import * as Survey from "survey-knockout-bootstrap"; - export class SurveyObjectItem { - public value: Survey.Base; - public text: any; - } +export class SurveyObjectItem { + public value: Survey.Base; + public text: any; +} - export class SurveyObjects { - public static intend: string = "..."; - surveyValue: Survey.Survey; +export class SurveyObjects { + public static intend: string = "..."; + surveyValue: Survey.Survey; - constructor(public koObjects: any, public koSelected: any) { - } - public get survey(): Survey.Survey { return this.surveyValue; } - public set survey(value: Survey.Survey) { - if (this.survey == value) return; - this.surveyValue = value; - this.rebuild(); - } - public addPage(page: Survey.Page) { - var pageItem = this.createPage(page); - var index = this.survey.pages.indexOf(page); - if (index > 0) { - var prevPage = this.survey.pages[index - 1]; - index = this.getItemIndex(prevPage) + 1; - index += prevPage.questions.length; - } else { - index = 1; //0 - Survey - } - this.addItem(pageItem, index); - index++; - for (var i = 0; i < page.questions.length; i++) { - var item = this.createQuestion(page.questions[i]); - this.addItem(item, index + i); - } - this.koSelected(pageItem); - } - public addQuestion(page: Survey.Page, question: Survey.QuestionBase) { - var index = this.getItemIndex(page); - if (index < 0) return; - var questionIndex = page.questions.indexOf(question) + 1; - index += questionIndex; - var item = this.createQuestion(question); - this.addItem(item, index); - this.koSelected(item); - } - public selectObject(obj: Survey.Base) { - var objs = this.koObjects(); - for (var i = 0; i < objs.length; i++) { - if (objs[i].value == obj) { - this.koSelected(objs[i]); - return; - } - } - } - public removeObject(obj: Survey.Base) { - var index = this.getItemIndex(obj); - if (index < 0) return; - var countToRemove = 1; - if (SurveyHelper.getObjectType(obj) == ObjType.Page) { - var page: Survey.Page = obj; - countToRemove += page.questions.length; + constructor(public koObjects: any, public koSelected: any) { + } + public get survey(): Survey.Survey { return this.surveyValue; } + public set survey(value: Survey.Survey) { + if (this.survey == value) return; + this.surveyValue = value; + this.rebuild(); + } + public addPage(page: Survey.Page) { + var pageItem = this.createPage(page); + var index = this.survey.pages.indexOf(page); + if (index > 0) { + var prevPage = this.survey.pages[index - 1]; + index = this.getItemIndex(prevPage) + 1; + index += prevPage.questions.length; + } else { + index = 1; //0 - Survey + } + this.addItem(pageItem, index); + index++; + for (var i = 0; i < page.questions.length; i++) { + var item = this.createQuestion(page.questions[i]); + this.addItem(item, index + i); + } + this.koSelected(pageItem); + } + public addQuestion(page: Survey.Page, question: Survey.QuestionBase) { + var index = this.getItemIndex(page); + if (index < 0) return; + var questionIndex = page.questions.indexOf(question) + 1; + index += questionIndex; + var item = this.createQuestion(question); + this.addItem(item, index); + this.koSelected(item); + } + public selectObject(obj: Survey.Base) { + var objs = this.koObjects(); + for (var i = 0; i < objs.length; i++) { + if (objs[i].value == obj) { + this.koSelected(objs[i]); + return; } - this.koObjects.splice(index, countToRemove); - } - public nameChanged(obj: Survey.Base) { - var index = this.getItemIndex(obj); - if (index < 0) return; - this.koObjects()[index].text(this.getText(obj)); } - public selectNextQuestion(isUp: boolean) { - var question = this.getSelectedQuestion(); - var itemIndex = this.getItemIndex(question); - if (itemIndex < 0) return question; - var objs = this.koObjects(); - var newItemIndex = itemIndex + (isUp ? -1 : 1); - if (newItemIndex < objs.length && SurveyHelper.getObjectType(objs[newItemIndex].value) == ObjType.Question) { + } + public removeObject(obj: Survey.Base) { + var index = this.getItemIndex(obj); + if (index < 0) return; + var countToRemove = 1; + if (SurveyHelper.getObjectType(obj) == ObjType.Page) { + var page: Survey.Page = obj; + countToRemove += page.questions.length; + } + this.koObjects.splice(index, countToRemove); + } + public nameChanged(obj: Survey.Base) { + var index = this.getItemIndex(obj); + if (index < 0) return; + this.koObjects()[index].text(this.getText(obj)); + } + public selectNextQuestion(isUp: boolean) { + var question = this.getSelectedQuestion(); + var itemIndex = this.getItemIndex(question); + if (itemIndex < 0) return question; + var objs = this.koObjects(); + var newItemIndex = itemIndex + (isUp ? -1 : 1); + if (newItemIndex < objs.length && SurveyHelper.getObjectType(objs[newItemIndex].value) == ObjType.Question) { + itemIndex = newItemIndex; + } else { + newItemIndex = itemIndex; + while (newItemIndex < objs.length && SurveyHelper.getObjectType(objs[newItemIndex].value) == ObjType.Question) { itemIndex = newItemIndex; - } else { - newItemIndex = itemIndex; - while (newItemIndex < objs.length && SurveyHelper.getObjectType(objs[newItemIndex].value) == ObjType.Question) { - itemIndex = newItemIndex; - newItemIndex += (isUp ? 1 : -1); - } - } - this.koSelected(objs[itemIndex]); + newItemIndex += (isUp ? 1 : -1); + } } - private getSelectedQuestion(): Survey.QuestionBase { - if (!this.koSelected()) return null; - var obj = this.koSelected().value; - if (!obj) return null; - return SurveyHelper.getObjectType(obj) == ObjType.Question ? (obj) : null; + this.koSelected(objs[itemIndex]); + } + private getSelectedQuestion(): Survey.QuestionBase { + if (!this.koSelected()) return null; + var obj = this.koSelected().value; + if (!obj) return null; + return SurveyHelper.getObjectType(obj) == ObjType.Question ? (obj) : null; + } + private addItem(item: SurveyObjectItem, index: number) { + if (index > this.koObjects().length) { + this.koObjects.push(item); + } else { + this.koObjects.splice(index, 0, item); } - private addItem(item: SurveyObjectItem, index: number) { - if (index > this.koObjects().length) { - this.koObjects.push(item); - } else { - this.koObjects.splice(index, 0, item); - } - } - private rebuild() { - var objs = []; - if (this.survey == null) { - this.koObjects(objs); - this.koSelected(null); - return; - } - objs.push(this.createItem(this.survey, "Survey")); - for (var i = 0; i < this.survey.pages.length; i++) { - var page = this.survey.pages[i]; - objs.push(this.createPage(page)); - for (var j = 0; j < page.questions.length; j++) { - objs.push(this.createQuestion(page.questions[j])); - } - } + } + private rebuild() { + var objs = []; + if (this.survey == null) { this.koObjects(objs); - this.koSelected(this.survey); - } - private createPage(page: Survey.Page) { - return this.createItem(page, this.getText(page)); - } - private createQuestion(question: Survey.QuestionBase) { - return this.createItem(question, this.getText(question)); - } - private createItem(value: Survey.Base, text: string) { - var item = new SurveyObjectItem(); - item.value = value; - item.text = ko.observable(text); - return item; - } - private getItemIndex(value: Survey.Base): number { - var objs = this.koObjects(); - for (var i = 0; i < objs.length; i++) { - if (objs[i].value == value) return i; + this.koSelected(null); + return; + } + objs.push(this.createItem(this.survey, "Survey")); + for (var i = 0; i < this.survey.pages.length; i++) { + var page = this.survey.pages[i]; + objs.push(this.createPage(page)); + for (var j = 0; j < page.questions.length; j++) { + objs.push(this.createQuestion(page.questions[j])); } - return -1; } - private getText(obj: Survey.Base): string { - var intend = SurveyObjects.intend; - if (SurveyHelper.getObjectType(obj) != ObjType.Page) { - intend += SurveyObjects.intend; - } - return intend + SurveyHelper.getObjectName(obj); + this.koObjects(objs); + this.koSelected(this.survey); + } + private createPage(page: Survey.Page) { + return this.createItem(page, this.getText(page)); + } + private createQuestion(question: Survey.QuestionBase) { + return this.createItem(question, this.getText(question)); + } + private createItem(value: Survey.Base, text: string) { + var item = new SurveyObjectItem(); + item.value = value; + item.text = ko.observable(text); + return item; + } + private getItemIndex(value: Survey.Base): number { + var objs = this.koObjects(); + for (var i = 0; i < objs.length; i++) { + if (objs[i].value == value) return i; + } + return -1; + } + private getText(obj: Survey.Base): string { + var intend = SurveyObjects.intend; + if (SurveyHelper.getObjectType(obj) != ObjType.Page) { + intend += SurveyObjects.intend; } + return intend + SurveyHelper.getObjectName(obj); } } \ No newline at end of file diff --git a/src/textWorker.ts b/src/textWorker.ts index b0bdee8884..6fa2c42e4d 100644 --- a/src/textWorker.ts +++ b/src/textWorker.ts @@ -1,128 +1,129 @@ -module SurveyEditor { - class TextParserPropery { - isFound: boolean; - propertiesCount: number; - start: number; - end: number; - valueStart: number; - valueEnd: number; - } +import {SurveyJSON5} from "./json5"; +import * as Survey from "survey-knockout-bootstrap"; - export class SurveyTextWorker { - public static newLineChar: string; - public errors: Array; - private surveyValue: Survey.Survey; - private jsonValue: any; - private surveyObjects: Array; - private isSurveyAsPage: boolean; +class TextParserPropery { + isFound: boolean; + propertiesCount: number; + start: number; + end: number; + valueStart: number; + valueEnd: number; +} - constructor(public text: string) { - if (!this.text || this.text.trim() == "") { - this.text = "{}"; - } - this.errors = []; - this.process(); +export class SurveyTextWorker { + public static newLineChar: string; + public errors: Array; + private surveyValue: Survey.Survey; + private jsonValue: any; + private surveyObjects: Array; + private isSurveyAsPage: boolean; + + constructor(public text: string) { + if (!this.text || this.text.trim() == "") { + this.text = "{}"; } - public get survey(): Survey.Survey { return this.surveyValue; } - public get isJsonCorrect(): boolean { return this.surveyValue != null; } - protected process() { - try { - this.jsonValue = new SurveyJSON5(1).parse(this.text); - } - catch (error) { - this.errors.push({ pos: { start: error.at, end: -1 }, text: error.message }); - } - if (this.jsonValue != null) { - this.updateJsonPositions(this.jsonValue); - this.surveyValue = new Survey.Survey(this.jsonValue); - if (this.surveyValue.jsonErrors != null) { - for (var i = 0; i < this.surveyValue.jsonErrors.length; i++) { - var error = this.surveyValue.jsonErrors[i]; - this.errors.push({ pos: { start: error.at, end: -1 }, text: error.getFullDescription() }); - } + this.errors = []; + this.process(); + } + public get survey(): Survey.Survey { return this.surveyValue; } + public get isJsonCorrect(): boolean { return this.surveyValue != null; } + protected process() { + try { + this.jsonValue = new SurveyJSON5(1).parse(this.text); + } + catch (error) { + this.errors.push({ pos: { start: error.at, end: -1 }, text: error.message }); + } + if (this.jsonValue != null) { + this.updateJsonPositions(this.jsonValue); + this.surveyValue = new Survey.Survey(this.jsonValue); + if (this.surveyValue.jsonErrors != null) { + for (var i = 0; i < this.surveyValue.jsonErrors.length; i++) { + var error = this.surveyValue.jsonErrors[i]; + this.errors.push({ pos: { start: error.at, end: -1 }, text: error.getFullDescription() }); } } - this.surveyObjects = this.createSurveyObjects(); - this.setEditorPositionByChartAt(this.surveyObjects); - this.setEditorPositionByChartAt(this.errors); } - private updateJsonPositions(jsonObj: any) { - jsonObj["pos"]["self"] = jsonObj; - for (var key in jsonObj) { - var obj = jsonObj[key]; - if (obj && obj["pos"]) { - jsonObj["pos"][key] = obj["pos"]; - this.updateJsonPositions(obj); - } + this.surveyObjects = this.createSurveyObjects(); + this.setEditorPositionByChartAt(this.surveyObjects); + this.setEditorPositionByChartAt(this.errors); + } + private updateJsonPositions(jsonObj: any) { + jsonObj["pos"]["self"] = jsonObj; + for (var key in jsonObj) { + var obj = jsonObj[key]; + if (obj && obj["pos"]) { + jsonObj["pos"][key] = obj["pos"]; + this.updateJsonPositions(obj); } } - private createSurveyObjects(): Array { - var result = []; - if (this.surveyValue == null) return result; - this.isSurveyAsPage = false; - for (var i = 0; i < this.surveyValue.pages.length; i++) { - var page = this.surveyValue.pages[i]; - if (i == 0 && !page["pos"]) { - page["pos"] = this.surveyValue["pos"]; - this.isSurveyAsPage = true; - } - result.push(page); - for (var j = 0; j < page.questions.length; j++) { - result.push(page.questions[j]); - } + } + private createSurveyObjects(): Array { + var result = []; + if (this.surveyValue == null) return result; + this.isSurveyAsPage = false; + for (var i = 0; i < this.surveyValue.pages.length; i++) { + var page = this.surveyValue.pages[i]; + if (i == 0 && !page["pos"]) { + page["pos"] = this.surveyValue["pos"]; + this.isSurveyAsPage = true; + } + result.push(page); + for (var j = 0; j < page.questions.length; j++) { + result.push(page.questions[j]); } - return result; } - private setEditorPositionByChartAt(objects: any[]) { - if (objects == null || objects.length == 0) return; - var position = { row: 0, column: 0 }; - var atObjectsArray = this.getAtArray(objects); - var startAt: number = 0; - for (var i = 0; i < atObjectsArray.length; i++) { - var at = atObjectsArray[i].at; - position = this.getPostionByChartAt(position, startAt, at); - var obj = atObjectsArray[i].obj; - if (!obj.position) obj.position = {}; - if (at == obj.pos.start) { - obj.position.start = position; - } else { - if (at == obj.pos.end) { - obj.position.end = position; - } + return result; + } + private setEditorPositionByChartAt(objects: any[]) { + if (objects == null || objects.length == 0) return; + var position = { row: 0, column: 0 }; + var atObjectsArray = this.getAtArray(objects); + var startAt: number = 0; + for (var i = 0; i < atObjectsArray.length; i++) { + var at = atObjectsArray[i].at; + position = this.getPostionByChartAt(position, startAt, at); + var obj = atObjectsArray[i].obj; + if (!obj.position) obj.position = {}; + if (at == obj.pos.start) { + obj.position.start = position; + } else { + if (at == obj.pos.end) { + obj.position.end = position; } - startAt = at; } + startAt = at; } - private getPostionByChartAt(startPosition: AceAjax.Position, startAt: number, at: number): any { - var result = { row: startPosition.row, column: startPosition.column }; - var curChar = startAt; - while (curChar < at) { - if (this.text.charAt(curChar) == SurveyTextWorker.newLineChar) { - result.row++; - result.column = 0; - } else { - result.column++; - } - curChar++; + } + private getPostionByChartAt(startPosition: AceAjax.Position, startAt: number, at: number): any { + var result = { row: startPosition.row, column: startPosition.column }; + var curChar = startAt; + while (curChar < at) { + if (this.text.charAt(curChar) == SurveyTextWorker.newLineChar) { + result.row++; + result.column = 0; + } else { + result.column++; } - return result; + curChar++; } - private getAtArray(objects: any[]): any[] { - var result = []; - for (var i = 0; i < objects.length; i++) { - var obj = objects[i]; - var pos = obj.pos; - if (!pos) continue; - result.push({ at: pos.start, obj: obj }); - if (pos.end > 0) { - result.push({ at: pos.end, obj: obj }); - } + return result; + } + private getAtArray(objects: any[]): any[] { + var result = []; + for (var i = 0; i < objects.length; i++) { + var obj = objects[i]; + var pos = obj.pos; + if (!pos) continue; + result.push({ at: pos.start, obj: obj }); + if (pos.end > 0) { + result.push({ at: pos.end, obj: obj }); } - return result.sort((el1, el2) => { - if (el1.at > el2.at) return 1; - if (el1.at < el2.at) return -1; - return 0; - }); } + return result.sort((el1, el2) => { + if (el1.at > el2.at) return 1; + if (el1.at < el2.at) return -1; + return 0; + }); } } \ No newline at end of file diff --git a/src/undoredo.ts b/src/undoredo.ts index 0fa5100a79..a40595442f 100644 --- a/src/undoredo.ts +++ b/src/undoredo.ts @@ -1,61 +1,62 @@ -module SurveyEditor { - export class SurveyUndoRedo { - private items: Array; - private index: number = -1; - public koCanUndo: any; koCanRedo: any; - public maximumCount: number = 10; - constructor() { - this.items = []; - this.koCanUndo = ko.observable(false); - this.koCanRedo = ko.observable(false); - } - public clear() { - this.items = []; - this.koCanUndo(false); - this.koCanRedo(false); - } - public setCurrent(survey: Survey.Survey, selectedObjName: string) { - var item = new UndoRedoItem(); - item.surveyJSON = new Survey.JsonObject().toJsonObject(survey); - item.selectedObjName = selectedObjName; - if (this.index < this.items.length - 1) { - this.items.splice(this.index + 1); - } - this.items.push(item); - this.removeOldData(); - this.index = this.items.length - 1; - this.updateCanUndoRedo(); - } - public undo(): UndoRedoItem { - if (!this.canUndo) return null; - return this.doUndoRedo(-1); - } - public redo(): UndoRedoItem { - if (!this.canRedo) return null; - return this.doUndoRedo(1); - } - private updateCanUndoRedo() { - this.koCanUndo(this.canUndo); - this.koCanRedo(this.canRedo); - } - private doUndoRedo(dIndex: number): UndoRedoItem { - this.index += dIndex; - this.updateCanUndoRedo(); - return this.index >= 0 && this.index < this.items.length ? this.items[this.index] : null; - } - protected get canUndo(): boolean { - return this.index >= 1 && this.index < this.items.length; - } - protected get canRedo(): boolean { - return this.items.length > 1 && this.index < this.items.length - 1; - } - private removeOldData() { - if (this.items.length - 1 < this.maximumCount) return; - this.items.splice(0, this.items.length - this.maximumCount - 1); - } +import * as Survey from "survey-knockout-bootstrap"; + +export class SurveyUndoRedo { + private items: Array; + private index: number = -1; + public koCanUndo: any; koCanRedo: any; + public maximumCount: number = 10; + constructor() { + this.items = []; + this.koCanUndo = ko.observable(false); + this.koCanRedo = ko.observable(false); + } + public clear() { + this.items = []; + this.koCanUndo(false); + this.koCanRedo(false); + } + public setCurrent(survey: Survey.Survey, selectedObjName: string) { + var item = new UndoRedoItem(); + item.surveyJSON = new Survey.JsonObject().toJsonObject(survey); + item.selectedObjName = selectedObjName; + if (this.index < this.items.length - 1) { + this.items.splice(this.index + 1); + } + this.items.push(item); + this.removeOldData(); + this.index = this.items.length - 1; + this.updateCanUndoRedo(); + } + public undo(): UndoRedoItem { + if (!this.canUndo) return null; + return this.doUndoRedo(-1); + } + public redo(): UndoRedoItem { + if (!this.canRedo) return null; + return this.doUndoRedo(1); + } + private updateCanUndoRedo() { + this.koCanUndo(this.canUndo); + this.koCanRedo(this.canRedo); + } + private doUndoRedo(dIndex: number): UndoRedoItem { + this.index += dIndex; + this.updateCanUndoRedo(); + return this.index >= 0 && this.index < this.items.length ? this.items[this.index] : null; + } + protected get canUndo(): boolean { + return this.index >= 1 && this.index < this.items.length; + } + protected get canRedo(): boolean { + return this.items.length > 1 && this.index < this.items.length - 1; } - export class UndoRedoItem { - surveyJSON: any; - selectedObjName: string; + private removeOldData() { + if (this.items.length - 1 < this.maximumCount) return; + this.items.splice(0, this.items.length - this.maximumCount - 1); } +} + +export class UndoRedoItem { + surveyJSON: any; + selectedObjName: string; } \ No newline at end of file diff --git a/tests/ObjectEditorTestedClasses.ts b/tests/ObjectEditorTestedClasses.ts index c4ce065ab3..4715b74c42 100644 --- a/tests/ObjectEditorTestedClasses.ts +++ b/tests/ObjectEditorTestedClasses.ts @@ -1,48 +1,50 @@ -module SurveyObjectEditorTests.Tests { - export class Car { - public name: string; - public getType(): string { return "car"; } - } - export class FastCar extends Car { - public getType(): string { return "fast"; } - } - export class BigCar extends Car { - public getType(): string { return "big"; } - } - export class SportCar extends FastCar { - public maxSpeed: number; - public getType(): string { return "sport"; } - } - export class Truck extends BigCar { - public maxWeight: number; - public getType(): string { return "truck"; } +import * as Survey from "survey-knockout-bootstrap"; + +export class Car { + public name: string; + public getType(): string { return "car"; } +} +export class FastCar extends Car { + public getType(): string { return "fast"; } +} +export class BigCar extends Car { + public getType(): string { return "big"; } +} +export class SportCar extends FastCar { + public maxSpeed: number; + public getType(): string { return "sport"; } +} +export class Truck extends BigCar { + public maxWeight: number; + public getType(): string { return "truck"; } +} +export class TruckDefaultValue extends Truck { + private titleValue: string; + public isNew: boolean; + public getType(): string { return "truckDefault"; } + public get title(): string { + return "!" + this.titleValue + "!"; } - export class TruckDefaultValue extends Truck { - private titleValue: string; - public isNew: boolean; - public getType(): string { return "truckDefault"; } - public get title(): string { - return "!" + this.titleValue + "!"; - } - public set title(value: string) { - this.titleValue = value; - } + public set title(value: string) { + this.titleValue = value; } +} + +Survey.JsonObject.metaData.addClass("fast", [], function () { return new FastCar(); }, "car"); +Survey.JsonObject.metaData.addClass("big", [], null, "car"); +Survey.JsonObject.metaData.addClass("car", ["name"]); +Survey.JsonObject.metaData.addClass("truck", ["maxWeight:number"], function () { return new Truck(); }, "big"); +Survey.JsonObject.metaData.addClass("sport", ["!maxSpeed:number"], function () { return new SportCar(); }, "fast"); +Survey.JsonObject.metaData.addClass("truckDefault", ["isNew:boolean", "title:string"], function () { return new TruckDefaultValue(); }, "truck"); + +//TODO add onGetValue into the line above. +var properties = Survey.JsonObject.metaData.getProperties("truckDefault"); - Survey.JsonObject.metaData.addClass("fast", [], function () { return new FastCar(); }, "car"); - Survey.JsonObject.metaData.addClass("big", [], null, "car"); - Survey.JsonObject.metaData.addClass("car", ["name"]); - Survey.JsonObject.metaData.addClass("truck", ["maxWeight:number"], function () { return new Truck(); }, "big"); - Survey.JsonObject.metaData.addClass("sport", ["!maxSpeed:number"], function () { return new SportCar(); }, "fast"); - Survey.JsonObject.metaData.addClass("truckDefault", ["isNew:boolean", "title:string"], function () { return new TruckDefaultValue(); }, "truck"); - //TODO add onGetValue into the line above. - var properties = Survey.JsonObject.metaData.getProperties("truckDefault"); - for (var i = 0; i < properties.length; i++) { - if (properties[i].name == "title") { - properties[i].onGetValue = function (obj: any) { return obj.titleValue; } - break; - } +for (var i = 0; i < properties.length; i++) { + if (properties[i].name == "title") { + properties[i].onGetValue = function (obj: any) { return obj.titleValue; }; + break; } - //Survey.JsonObject.metaData.setPropertyValues("truckDefault", "title", null, null, function (obj: any) { return obj.titleValue; }); +} -} \ No newline at end of file +//Survey.JsonObject.metaData.setPropertyValues("truckDefault", "title", null, null, function (obj: any) { return obj.titleValue; }); \ No newline at end of file diff --git a/tests/ObjectEditorTests.ts b/tests/ObjectEditorTests.ts index ab2dccf04c..f3c92965bd 100644 --- a/tests/ObjectEditorTests.ts +++ b/tests/ObjectEditorTests.ts @@ -1,68 +1,66 @@ -/// -/// +import {SurveyObjectEditor} from "../src/objectEditor"; +import {BigCar, Truck, TruckDefaultValue} from "./ObjectEditorTestedClasses"; -module SurveyObjectEditorTests.Tests { - QUnit.module("objectEditorTests"); +QUnit.module("objectEditorTests"); - QUnit.test("Created properties on set selected Object", function (assert) { - var editor = new SurveyEditor.SurveyObjectEditor(); - assert.equal(editor.koProperties().length, 0, "No properties for null object"); +QUnit.test("Created properties on set selected Object", function (assert) { + var editor = new SurveyObjectEditor(); + assert.equal(editor.koProperties().length, 0, "No properties for null object"); - editor.selectedObject = new BigCar(); - assert.equal(editor.koProperties().length, 1, "One property object"); - assert.equal(editor.koProperties()[0].name, "name", "name property"); - assert.equal(editor.koProperties()[0].editorType, "string", "It is a text editor"); + editor.selectedObject = new BigCar(); + assert.equal(editor.koProperties().length, 1, "One property object"); + assert.equal(editor.koProperties()[0].name, "name", "name property"); + assert.equal(editor.koProperties()[0].editorType, "string", "It is a text editor"); - editor.selectedObject = new Truck(); - assert.equal(editor.koProperties().length, 2, "Two property object"); - assert.equal(editor.koProperties()[0].name, "maxWeight", "maxWeight property"); - assert.equal(editor.koProperties()[1].name, "name", "name property"); - }); - QUnit.test("Get Property Value", function (assert) { - var editor = new SurveyEditor.SurveyObjectEditor(); - var car = new Truck(); - car.name = "truckCar"; - car.maxWeight = 20000; - editor.selectedObject = car; - assert.equal(editor.koProperties()[1].koValue(), "truckCar", "get name property"); - assert.equal(editor.koProperties()[0].koValue(), 20000, "get maxWeight property"); - }); - QUnit.test("isDefault property value", function (assert) { - var editor = new SurveyEditor.SurveyObjectEditor(); - var car = new TruckDefaultValue(); - editor.selectedObject = car; - var property = editor.getPropertyEditor("isNew"); - assert.equal(property.koIsDefault(), true, "the value is default"); - assert.equal(property.editorType, "boolean", "It is a boolean editor"); - car.isNew = true; - editor.ObjectChanged(); - assert.equal(property.koIsDefault(), false, "the value is not default"); - }); - QUnit.test("Active property", function (assert) { - var editor = new SurveyEditor.SurveyObjectEditor(); - assert.equal(editor.koActiveProperty(), null, "no properties"); - editor.selectedObject = new TruckDefaultValue(); - assert.equal(editor.koActiveProperty().name, "name", "name property is active by default"); - }); - QUnit.test("On property changed", function (assert) { - var editor = new SurveyEditor.SurveyObjectEditor(); - var car = new TruckDefaultValue(); - car.name = "myName"; - var callCounter = 0; - editor.onPropertyValueChanged.add((sender, options) => { car.name = options.newValue; callCounter++; }); - editor.selectedObject = car; - editor.koActiveProperty().koValue("newName"); - assert.equal(car.name, "newName", "on property changed event is working"); - assert.equal(callCounter, 1, "It should be called only one time"); - }); - QUnit.test("Use metadata getPropertyValue function", function (assert) { - var editor = new SurveyEditor.SurveyObjectEditor(); - var car = new TruckDefaultValue(); - car.title = "test"; - editor.selectedObject = car; - var property = editor.getPropertyEditor("title"); - - editor.koActiveProperty().koValue("newName"); - assert.equal(property.koText(), "test", "use the real value to get value"); - }); -} \ No newline at end of file + editor.selectedObject = new Truck(); + assert.equal(editor.koProperties().length, 2, "Two property object"); + assert.equal(editor.koProperties()[0].name, "maxWeight", "maxWeight property"); + assert.equal(editor.koProperties()[1].name, "name", "name property"); +}); +QUnit.test("Get Property Value", function (assert) { + var editor = new SurveyObjectEditor(); + var car = new Truck(); + car.name = "truckCar"; + car.maxWeight = 20000; + editor.selectedObject = car; + assert.equal(editor.koProperties()[1].koValue(), "truckCar", "get name property"); + assert.equal(editor.koProperties()[0].koValue(), 20000, "get maxWeight property"); +}); +QUnit.test("isDefault property value", function (assert) { + var editor = new SurveyObjectEditor(); + var car = new TruckDefaultValue(); + editor.selectedObject = car; + var property = editor.getPropertyEditor("isNew"); + assert.equal(property.koIsDefault(), true, "the value is default"); + assert.equal(property.editorType, "boolean", "It is a boolean editor"); + car.isNew = true; + editor.ObjectChanged(); + assert.equal(property.koIsDefault(), false, "the value is not default"); +}); +QUnit.test("Active property", function (assert) { + var editor = new SurveyObjectEditor(); + assert.equal(editor.koActiveProperty(), null, "no properties"); + editor.selectedObject = new TruckDefaultValue(); + assert.equal(editor.koActiveProperty().name, "name", "name property is active by default"); +}); +QUnit.test("On property changed", function (assert) { + var editor = new SurveyObjectEditor(); + var car = new TruckDefaultValue(); + car.name = "myName"; + var callCounter = 0; + editor.onPropertyValueChanged.add((sender, options) => { car.name = options.newValue; callCounter++; }); + editor.selectedObject = car; + editor.koActiveProperty().koValue("newName"); + assert.equal(car.name, "newName", "on property changed event is working"); + assert.equal(callCounter, 1, "It should be called only one time"); +}); +QUnit.test("Use metadata getPropertyValue function", function (assert) { + var editor = new SurveyObjectEditor(); + var car = new TruckDefaultValue(); + car.title = "test"; + editor.selectedObject = car; + var property = editor.getPropertyEditor("title"); + + editor.koActiveProperty().koValue("newName"); + assert.equal(property.koText(), "test", "use the real value to get value"); +}); \ No newline at end of file diff --git a/tests/SurveyEditorTests.ts b/tests/SurveyEditorTests.ts index 0ca0c2684d..23c88a3d95 100644 --- a/tests/SurveyEditorTests.ts +++ b/tests/SurveyEditorTests.ts @@ -1,87 +1,88 @@ -/// -module SurveyObjectEditorTests.Tests { - QUnit.module("surveyEditorTests"); +import {SurveyEditor} from "../src/editor"; +import * as Survey from "survey-knockout-bootstrap"; - QUnit.test("Set Text property", function (assert) { - var editor = new SurveyEditor.SurveyEditor(); - var json = { - questions: [ - { - type: "checkbox", name: "car", title: "What car are you driving?", isRequired: true, - colCount: 4, choices: ["None", "Ford", "Vauxhall", "Volkswagen", "Nissan", "Audi", "Mercedes-Benz", "BMW", "Peugeot", "Toyota", "Citroen"] - } - ] - }; - var jsonText = JSON.stringify(json); - editor.text = jsonText; - assert.equal(editor.koIsShowDesigner(), true); - assert.equal(editor.survey.getAllQuestions().length, 1, "There is one question"); - assert.equal(editor.survey.getAllQuestions()[0].name, "car", "The question converted successufull"); - jsonText = jsonText.substr(5); - editor.text = jsonText; - assert.equal(editor.koIsShowDesigner(), false); - }); - QUnit.test("Copy Question", function (assert) { - var editor = new SurveyEditor.SurveyEditor(); - editor.text = JSON.stringify(getSurveyJson()); +QUnit.module("surveyEditorTests"); - assert.equal(editor.koCopiedQuestions().length, 0, "There is no copied question yet."); - editor.copyQuestion(editor.survey.getAllQuestions()[0]); - assert.equal(editor.koCopiedQuestions().length, 1, "There is one copied question now."); - assert.equal(editor.koCopiedQuestions()[0].name, "question1", "The copied question is 'question1'"); - editor.copyQuestion(editor.survey.getAllQuestions()[0]); - assert.equal(editor.koCopiedQuestions().length, 1, "There is still one copied question now."); - assert.equal(editor.koCopiedQuestions()[0].name, "question1", "The copied question is 'question1'"); - }); - QUnit.test("options.questionTypes", function (assert) { - var allTypes = Survey.QuestionFactory.Instance.getAllTypes(); - var editor = new SurveyEditor.SurveyEditor(null, null); - assert.equal(editor.questionTypes.length, allTypes.length, "All types are accepted"); - editor = new SurveyEditor.SurveyEditor(null, { questionTypes: ["text", "dropdown", "unknown"]}); - assert.equal(editor.questionTypes.length, 2, "Only two types from three are accepted"); - }); - QUnit.test("Editor state property", function (assert) { - var editor = new SurveyEditor.SurveyEditor(); - editor.saveSurveyFunc = function (no: number, doSaveCallback: (no: number, isSuccess: boolean) => void) { - doSaveCallback(no, true); - }; - editor.text = JSON.stringify(getSurveyJson()); - assert.equal(editor.state, ""); - editor.addPage(); - assert.equal(editor.state, "modified"); - editor.saveButtonClick(); - assert.equal(editor.state, "saved"); - /* - editor.addPage(); - assert.equal(editor.state, "modified"); - editor.doUndoClick(); - assert.equal(editor.state, "saved"); - editor.doRedoClick(); - assert.equal(editor.state, "modified"); - */ - }); - QUnit.test("Do not reload surey on 'Designer' tab click", function (assert) { - var editor = new SurveyEditor.SurveyEditor(); - editor.text = JSON.stringify(getSurveyJson()); - var pageCount = editor.survey.PageCount; - editor.addPage(); - assert.equal(editor.survey.PageCount, pageCount + 1, "new Page is added"); - editor.selectDesignerClick(); - assert.equal(editor.survey.PageCount, pageCount + 1, "new Page is stil there"); - editor.selectTestClick(); - assert.equal(editor.survey.PageCount, pageCount + 1, "new Page is stil there"); - }); - function getSurveyJson(): any { - return { - pages: [{ - name: 'page1', questions: [{ type: 'text', name: 'question1' }, - { name: "question2", choices: ["one", { value: "two", text: "second value" }, { value: 3, text: "third value" }], type: "checkbox" }] - }, - { name: 'page2', questions: [{ name: "question3", type: "comment" }] }, - { - name: 'page3', questions: [{ name: "question4", columns: ["Column 1", "Column 2", "Column 3"], rows: ["Row 1", "Row 2"], type: "matrix" }, - { name: "question5", type: "rating" }] - }] - }; - } +QUnit.test("Set Text property", function (assert) { + var editor = new SurveyEditor(); + var json = { + questions: [ + { + type: "checkbox", name: "car", title: "What car are you driving?", isRequired: true, + colCount: 4, choices: ["None", "Ford", "Vauxhall", "Volkswagen", "Nissan", "Audi", "Mercedes-Benz", "BMW", "Peugeot", "Toyota", "Citroen"] + } + ] + }; + var jsonText = JSON.stringify(json); + editor.text = jsonText; + assert.equal(editor.koIsShowDesigner(), true); + assert.equal(editor.survey.getAllQuestions().length, 1, "There is one question"); + assert.equal(editor.survey.getAllQuestions()[0].name, "car", "The question converted successufull"); + jsonText = jsonText.substr(5); + editor.text = jsonText; + assert.equal(editor.koIsShowDesigner(), false); +}); +QUnit.test("Copy Question", function (assert) { + var editor = new SurveyEditor(); + editor.text = JSON.stringify(getSurveyJson()); + + assert.equal(editor.koCopiedQuestions().length, 0, "There is no copied question yet."); + editor.copyQuestion(editor.survey.getAllQuestions()[0]); + assert.equal(editor.koCopiedQuestions().length, 1, "There is one copied question now."); + assert.equal(editor.koCopiedQuestions()[0].name, "question1", "The copied question is 'question1'"); + editor.copyQuestion(editor.survey.getAllQuestions()[0]); + assert.equal(editor.koCopiedQuestions().length, 1, "There is still one copied question now."); + assert.equal(editor.koCopiedQuestions()[0].name, "question1", "The copied question is 'question1'"); +}); +QUnit.test("options.questionTypes", function (assert) { + var allTypes = Survey.QuestionFactory.Instance.getAllTypes(); + var editor = new SurveyEditor(null, null); + assert.equal(editor.questionTypes.length, allTypes.length, "All types are accepted"); + editor = new SurveyEditor(null, { questionTypes: ["text", "dropdown", "unknown"]}); + assert.equal(editor.questionTypes.length, 2, "Only two types from three are accepted"); +}); +QUnit.test("Editor state property", function (assert) { + var editor = new SurveyEditor(); + editor.saveSurveyFunc = function (no: number, doSaveCallback: (no: number, isSuccess: boolean) => void) { + doSaveCallback(no, true); + }; + editor.text = JSON.stringify(getSurveyJson()); + assert.equal(editor.state, ""); + editor.addPage(); + assert.equal(editor.state, "modified"); + editor.saveButtonClick(); + assert.equal(editor.state, "saved"); + /* + editor.addPage(); + assert.equal(editor.state, "modified"); + editor.doUndoClick(); + assert.equal(editor.state, "saved"); + editor.doRedoClick(); + assert.equal(editor.state, "modified"); + */ +}); +QUnit.test("Do not reload surey on 'Designer' tab click", function (assert) { + var editor = new SurveyEditor(); + editor.text = JSON.stringify(getSurveyJson()); + var pageCount = editor.survey.PageCount; + editor.addPage(); + assert.equal(editor.survey.PageCount, pageCount + 1, "new Page is added"); + editor.selectDesignerClick(); + assert.equal(editor.survey.PageCount, pageCount + 1, "new Page is stil there"); + editor.selectTestClick(); + assert.equal(editor.survey.PageCount, pageCount + 1, "new Page is stil there"); +}); + +function getSurveyJson(): any { + return { + pages: [{ + name: 'page1', questions: [{ type: 'text', name: 'question1' }, + { name: "question2", choices: ["one", { value: "two", text: "second value" }, { value: 3, text: "third value" }], type: "checkbox" }] + }, + { name: 'page2', questions: [{ name: "question3", type: "comment" }] }, + { + name: 'page3', questions: [{ name: "question4", columns: ["Column 1", "Column 2", "Column 3"], rows: ["Row 1", "Row 2"], type: "matrix" }, + { name: "question5", type: "rating" }] + }] + }; } \ No newline at end of file diff --git a/tests/entries/index.ts b/tests/entries/index.ts new file mode 100644 index 0000000000..d9f8c439cd --- /dev/null +++ b/tests/entries/index.ts @@ -0,0 +1,7 @@ +export * from "../json5tests"; +export * from "../localizationTests"; +export * from "../ObjectEditorTests"; +export * from "../propertyEditorsTests"; +export * from "../SurveyEditorTests"; +export * from "../surveyObjectsTests"; +export * from "../undoredoTests"; \ No newline at end of file diff --git a/tests/json5tests.ts b/tests/json5tests.ts index 9fc65e13cb..346f3e55d3 100644 --- a/tests/json5tests.ts +++ b/tests/json5tests.ts @@ -1,68 +1,68 @@ -/// + +import {SurveyJSON5} from "../src/json5"; -module SurveyObjectEditorTests.Tests { - QUnit.module("JSON5Tests"); - QUnit.test("Simple test", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(1); - var obj = json5.parse("{ questions: [{ type: 'text', name: 'temp', size: 20 }]}"); - assert.equal(obj.questions.length, 1, "parsed correctly"); - assert.equal(obj["pos"].start, 0, "add 'pos' property"); - }); - QUnit.test("parse only part of the string", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(1); - var obj = json5.parse("0123456789{ questions: [{ type: 'text', name: 'temp', size: 20 }]}0123456789", null, 10, 66); - assert.equal(obj.questions.length, 1, "parsed correctly"); - assert.equal(obj["pos"].start, 10, "add 'pos' property"); - }); - QUnit.test("Full information about positions", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(2); - var obj = json5.parse("{ questions: [{ type: 'text', name: 'temp', size: 20 }]}"); - var qPos = obj["pos"]["questions"]; - assert.equal(qPos.start, 2, "start question property"); - assert.equal(qPos.valueStart, 12, "start question property value"); - assert.equal(qPos.end, 54, "end question property"); - }); +QUnit.module("JSON5Tests"); - QUnit.test("Full information about positions - several properties", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(2); - var obj = json5.parse("{ type: 'text', name: 'temp', size: 20 }"); - var pos = obj["pos"]["type"]; - assert.equal(pos.start, 2, "start question property for 'type'"); - assert.equal(pos.valueStart, 7, "start question property value for 'type'"); - assert.equal(pos.valueEnd, 13, "end question property value for 'type'"); - assert.equal(pos.end, 14, "end question property for 'type'"); +QUnit.test("Simple test", function (assert) { + var json5 = new SurveyJSON5(1); + var obj = json5.parse("{ questions: [{ type: 'text', name: 'temp', size: 20 }]}"); + assert.equal(obj.questions.length, 1, "parsed correctly"); + assert.equal(obj["pos"].start, 0, "add 'pos' property"); +}); +QUnit.test("parse only part of the string", function (assert) { + var json5 = new SurveyJSON5(1); + var obj = json5.parse("0123456789{ questions: [{ type: 'text', name: 'temp', size: 20 }]}0123456789", null, 10, 66); + assert.equal(obj.questions.length, 1, "parsed correctly"); + assert.equal(obj["pos"].start, 10, "add 'pos' property"); +}); +QUnit.test("Full information about positions", function (assert) { + var json5 = new SurveyJSON5(2); + var obj = json5.parse("{ questions: [{ type: 'text', name: 'temp', size: 20 }]}"); + var qPos = obj["pos"]["questions"]; + assert.equal(qPos.start, 2, "start question property"); + assert.equal(qPos.valueStart, 12, "start question property value"); + assert.equal(qPos.end, 54, "end question property"); +}); - pos = obj["pos"]["name"]; - assert.equal(pos.start, 14, "start question property for 'name'"); - assert.equal(pos.valueStart, 21, "start question property value for 'name'"); - assert.equal(pos.valueEnd, 27, "end question property value for 'name'"); - assert.equal(pos.end, 27, "end question property for 'name'"); +QUnit.test("Full information about positions - several properties", function (assert) { + var json5 = new SurveyJSON5(2); + var obj = json5.parse("{ type: 'text', name: 'temp', size: 20 }"); + var pos = obj["pos"]["type"]; + assert.equal(pos.start, 2, "start question property for 'type'"); + assert.equal(pos.valueStart, 7, "start question property value for 'type'"); + assert.equal(pos.valueEnd, 13, "end question property value for 'type'"); + assert.equal(pos.end, 14, "end question property for 'type'"); - pos = obj["pos"]["size"]; - assert.equal(pos.start, 28, "start question property for 'size'"); - assert.equal(pos.valueStart, 35, "start question property value for 'size'"); - assert.equal(pos.valueEnd, 37, "end question property value for 'size'"); - assert.equal(pos.end, 37, "end question property for 'size'"); + pos = obj["pos"]["name"]; + assert.equal(pos.start, 14, "start question property for 'name'"); + assert.equal(pos.valueStart, 21, "start question property value for 'name'"); + assert.equal(pos.valueEnd, 27, "end question property value for 'name'"); + assert.equal(pos.end, 27, "end question property for 'name'"); - }); - QUnit.test("Full information about positions - array", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(2); - var obj = json5.parse("{ choices:[0, 1]}"); - var pos = obj["pos"]["choices"]; - assert.equal(pos.start, 2, "start question property"); - assert.equal(pos.valueStart, 10, "start question property value"); - assert.equal(pos.end, 15, "end question property for"); - }); - QUnit.test("Empty Json test", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(1); - var obj = json5.parse("{ } "); - assert.equal(obj["pos"].start, 0, "start 'pos' position"); - assert.equal(obj["pos"].end, 2, "end 'pos' position"); - }); - QUnit.test("One property Json test", function (assert) { - var json5 = new SurveyEditor.SurveyJSON5(1); - var obj = json5.parse("{ v:1 } "); - assert.equal(obj["pos"].start, 0, "start 'pos' position"); - assert.equal(obj["pos"].end, 6, "end 'pos' position"); - }); -} \ No newline at end of file + pos = obj["pos"]["size"]; + assert.equal(pos.start, 28, "start question property for 'size'"); + assert.equal(pos.valueStart, 35, "start question property value for 'size'"); + assert.equal(pos.valueEnd, 37, "end question property value for 'size'"); + assert.equal(pos.end, 37, "end question property for 'size'"); + +}); +QUnit.test("Full information about positions - array", function (assert) { + var json5 = new SurveyJSON5(2); + var obj = json5.parse("{ choices:[0, 1]}"); + var pos = obj["pos"]["choices"]; + assert.equal(pos.start, 2, "start question property"); + assert.equal(pos.valueStart, 10, "start question property value"); + assert.equal(pos.end, 15, "end question property for"); +}); +QUnit.test("Empty Json test", function (assert) { + var json5 = new SurveyJSON5(1); + var obj = json5.parse("{ } "); + assert.equal(obj["pos"].start, 0, "start 'pos' position"); + assert.equal(obj["pos"].end, 2, "end 'pos' position"); +}); +QUnit.test("One property Json test", function (assert) { + var json5 = new SurveyJSON5(1); + var obj = json5.parse("{ v:1 } "); + assert.equal(obj["pos"].start, 0, "start 'pos' position"); + assert.equal(obj["pos"].end, 6, "end 'pos' position"); +}); \ No newline at end of file diff --git a/tests/localizationTests.ts b/tests/localizationTests.ts index 70415f215d..5c3f6927fc 100644 --- a/tests/localizationTests.ts +++ b/tests/localizationTests.ts @@ -1,16 +1,15 @@ -/// -module SurveyEditorTests.Tests { - QUnit.module("LocalizationTests"); +import {editorLocalization, defaultStrings} from "../src/editorLocalization"; - QUnit.test("Get nested property", function (assert) { - assert.equal(SurveyEditor.editorLocalization.getString("qt.text"), "Text", "find the nested property"); - assert.equal(SurveyEditor.editorLocalization.getString("qt.text1"), "text1", "the nested property doesn't exist"); - assert.equal(SurveyEditor.editorLocalization.getString("qt1.text"), "qt1", "the root property doesn't exist"); - }); - QUnit.test("Get property name and title", function (assert) { - assert.equal(SurveyEditor.editorLocalization.getPropertyName("text_name"), SurveyEditor.defaultStrings.p.name, "find the Name property"); - assert.equal(SurveyEditor.editorLocalization.getPropertyTitle("text_name"), "", "there is not title for it"); - assert.equal(SurveyEditor.editorLocalization.getPropertyName("text_title"), SurveyEditor.defaultStrings.p.title.name, "find the Title property"); - assert.equal(SurveyEditor.editorLocalization.getPropertyTitle("text_title"), SurveyEditor.defaultStrings.p.title.title, "find the title for Title property"); - }); -}; \ No newline at end of file +QUnit.module("LocalizationTests"); + +QUnit.test("Get nested property", function (assert) { + assert.equal(editorLocalization.getString("qt.text"), "Text", "find the nested property"); + assert.equal(editorLocalization.getString("qt.text1"), "text1", "the nested property doesn't exist"); + assert.equal(editorLocalization.getString("qt1.text"), "qt1", "the root property doesn't exist"); +}); +QUnit.test("Get property name and title", function (assert) { + assert.equal(editorLocalization.getPropertyName("text_name"), defaultStrings.p.name, "find the Name property"); + assert.equal(editorLocalization.getPropertyTitle("text_name"), "", "there is not title for it"); + assert.equal(editorLocalization.getPropertyName("text_title"), defaultStrings.p.title.name, "find the Title property"); + assert.equal(editorLocalization.getPropertyTitle("text_title"), defaultStrings.p.title.title, "find the title for Title property"); +}); \ No newline at end of file diff --git a/tests/propertyEditorsTests.ts b/tests/propertyEditorsTests.ts index 1941d3a732..22659630c2 100644 --- a/tests/propertyEditorsTests.ts +++ b/tests/propertyEditorsTests.ts @@ -1,131 +1,133 @@ -/// -/// -/// -/// -module SurveyEditorTests.Tests { - QUnit.module("PropertyEditorsTests"); +import {SurveyPropertyEditorBase} from "../src/propertyEditors/propertyEditorBase"; +import {SurveyPropertyItemValuesEditor} from "../src/propertyEditors/propertyItemValuesEditor"; +import {SurveyPropertyDropdownColumnsEditor} from "../src/propertyEditors/propertyMatrixDropdownColumnsEditor"; +import {SurveyObjectProperty} from "../src/objectProperty"; +import {SurveyPropertyTextEditor} from "../src/propertyEditors/propertyModalEditor"; +import {SurveyPropertyResultfullEditor} from "../src/propertyEditors/propertyRestfullEditor"; +import * as Survey from "survey-knockout-bootstrap"; +import "../src/propertyEditors/propertyTextItemsEditor"; - QUnit.test("Create correct property editor", function (assert) { - var propertyEditor = SurveyEditor.SurveyPropertyEditorBase.createEditor("unknown", null); - assert.equal(propertyEditor.editorType, "string", "The default property editor is 'string'"); +QUnit.module("PropertyEditorsTests"); - var propertyTypes = ["string", "boolean", "number", "dropdown", "text", "html", "itemvalues", - "matrixdropdowncolumns", "textitems", "triggers", "validators", "restfull"]; - for (var i = 0; i < propertyTypes.length; i++) { - var propType = propertyTypes[i]; - propertyEditor = SurveyEditor.SurveyPropertyEditorBase.createEditor(propType, null); - assert.equal(propertyEditor.editorType, propType, "Create '" + propType + "' property editor"); - } - }); - QUnit.test("SurveyPropertyItemValue", function (assert) { - var choices = [{ value: 1, text: "item1" }, { value: 2, text: "item2" }, { value: 3, text: "item3" }]; - var itemValueProperty = new SurveyEditor.SurveyPropertyItemValuesEditor(); - itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; - itemValueProperty.value = choices; - assert.equal(itemValueProperty.koItems().length, 3, "there are three elements"); - assert.equal(itemValueProperty.koItems()[1].koValue(), 2, "check value of the second element"); - assert.equal(itemValueProperty.koItems()[1].koText(), "item2", "check text of the second element"); +QUnit.test("Create correct property editor", function (assert) { + var propertyEditor = SurveyPropertyEditorBase.createEditor("unknown", null); + assert.equal(propertyEditor.editorType, "string", "The default property editor is 'string'"); - itemValueProperty.onDeleteClick(itemValueProperty.koItems()[1]); - assert.equal(itemValueProperty.koItems().length, 2, "there are two elements after deleting"); - assert.equal(itemValueProperty.koItems()[1].koValue(), 3, "check value of the second element"); - assert.equal(itemValueProperty.koItems()[1].koText(), "item3", "check text of the second element"); + var propertyTypes = ["string", "boolean", "number", "dropdown", "text", "html", "itemvalues", + "matrixdropdowncolumns", "textitems", "triggers", "validators", "restfull"]; + for (var i = 0; i < propertyTypes.length; i++) { + var propType = propertyTypes[i]; + propertyEditor = SurveyPropertyEditorBase.createEditor(propType, null); + assert.equal(propertyEditor.editorType, propType, "Create '" + propType + "' property editor"); + } +}); +QUnit.test("SurveyPropertyItemValue", function (assert) { + var choices = [{ value: 1, text: "item1" }, { value: 2, text: "item2" }, { value: 3, text: "item3" }]; + var itemValueProperty = new SurveyPropertyItemValuesEditor(); + itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; + itemValueProperty.value = choices; + assert.equal(itemValueProperty.koItems().length, 3, "there are three elements"); + assert.equal(itemValueProperty.koItems()[1].koValue(), 2, "check value of the second element"); + assert.equal(itemValueProperty.koItems()[1].koText(), "item2", "check text of the second element"); - itemValueProperty.onAddClick(); - assert.equal(itemValueProperty.koItems().length, 3, "there are three elements after adding"); - itemValueProperty.koItems()[2].koValue(4); - itemValueProperty.koItems()[2].koText("item4") - assert.equal(itemValueProperty.koItems()[2].koValue(), 4, "check value of the last element"); - assert.equal(itemValueProperty.koItems()[2].koText(), "item4", "check text of the last element"); + itemValueProperty.onDeleteClick(itemValueProperty.koItems()[1]); + assert.equal(itemValueProperty.koItems().length, 2, "there are two elements after deleting"); + assert.equal(itemValueProperty.koItems()[1].koValue(), 3, "check value of the second element"); + assert.equal(itemValueProperty.koItems()[1].koText(), "item3", "check text of the second element"); - itemValueProperty.onApplyClick(); - assert.equal(choices.length, 3, "there are three elements after adding"); - assert.equal(choices[2].value, 4, "check value of the last element"); - assert.equal(choices[2].text, "item4", "check text of the last element"); + itemValueProperty.onAddClick(); + assert.equal(itemValueProperty.koItems().length, 3, "there are three elements after adding"); + itemValueProperty.koItems()[2].koValue(4); + itemValueProperty.koItems()[2].koText("item4") + assert.equal(itemValueProperty.koItems()[2].koValue(), 4, "check value of the last element"); + assert.equal(itemValueProperty.koItems()[2].koText(), "item4", "check text of the last element"); - itemValueProperty.onAddClick(); - itemValueProperty.onAddClick(); - itemValueProperty.onResetClick(); - assert.equal(itemValueProperty.koItems().length, 3, "there are three elements"); - }); - QUnit.test("SurveyPropertyItemValue: Value and Text are same", function (assert) { - var choices = [{ value: 1, text: "1" }, { value: "item 2", text: "item 2" }]; - var itemValueProperty = new SurveyEditor.SurveyPropertyItemValuesEditor(); - itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; - itemValueProperty.value = choices; - assert.equal(itemValueProperty.koItems().length, 2, "there are three elements"); - itemValueProperty.onApplyClick(); - assert.equal(choices.length, 2, "there are two items"); - assert.equal(choices[0].value, 1, "the first value is 1"); - assert.equal(choices[0].text, null, "the first text is null"); - assert.equal(choices[1].value, "item 2", "the second value is 'item 2'"); - assert.equal(choices[1].text, null, "the second text is null"); - }); - QUnit.test("SurveyPropertyItemValue: Value and Text are same and editor.alwaySaveTextInPropertyEditors = true", function (assert) { - var choices = [{ value: 1, text: "1" }, { value: "item 2", text: "item 2" }]; - var itemValueProperty = new SurveyEditor.SurveyPropertyItemValuesEditor(); - itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; - itemValueProperty.value = choices; - itemValueProperty.options = { alwaySaveTextInPropertyEditors: true }; - assert.equal(itemValueProperty.koItems().length, 2, "there are three elements"); - itemValueProperty.onApplyClick(); - assert.equal(choices.length, 2, "there are two items"); - assert.equal(choices[0].value, 1, "the first value is 1"); - assert.equal(choices[0].text, "1", "the first text is '1'"); - assert.equal(choices[1].value, "item 2", "the second value is 'item 2'"); - assert.equal(choices[1].text, "item 2", "the second text is 'item 2'"); - }); + itemValueProperty.onApplyClick(); + assert.equal(choices.length, 3, "there are three elements after adding"); + assert.equal(choices[2].value, 4, "check value of the last element"); + assert.equal(choices[2].text, "item4", "check text of the last element"); - QUnit.test("SurveyPropertyItemValue_PureValue", function (assert) { - var choices = [1, "item2", { value: 3, text: "item3" }]; - var itemValueProperty = new SurveyEditor.SurveyPropertyItemValuesEditor(); - itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; - itemValueProperty.value = choices; - assert.equal(itemValueProperty.koItems().length, 3, "there are three elements"); - assert.equal(itemValueProperty.koItems()[0].koValue(), 1, "check value of the first element"); - assert.equal(itemValueProperty.koItems()[1].koValue(), "item2", "check value of the second element"); - assert.equal(itemValueProperty.koItems()[2].koValue(), 3, "check value of the third element"); - assert.equal(itemValueProperty.koItems()[2].koText(), "item3", "check text of the third element"); - }); - QUnit.test("SurveyPropertyMatrixDropdownColumns set properties", function (assert) { - var columns: Array = []; - columns.push(new Survey.MatrixDropdownColumn("column 1")); - columns.push(new Survey.MatrixDropdownColumn("column 2")); - columns[0].choices = [1, 2, "three"]; - var itemValueProperty = new SurveyEditor.SurveyPropertyDropdownColumnsEditor(); - itemValueProperty.onChanged = (newValue: Array) => { columns = newValue; }; - itemValueProperty.value = columns; - assert.equal(itemValueProperty.koItems().length, 2, "there are two elements"); - assert.equal(itemValueProperty.koItems()[0].koName(), "column 1", "the first column name"); - assert.equal(itemValueProperty.koItems()[0].koChoices().length, 3, "there are two elements"); - itemValueProperty.onAddClick(); - itemValueProperty.koItems()[2].koCellType("checkbox"); - itemValueProperty.koItems()[2].koName("column 3"); - assert.equal(itemValueProperty.koItems().length, 3, "There are 3 columns un editor"); - itemValueProperty.onApplyClick(); - assert.equal(columns.length, 3, "There are 3 columns"); - assert.equal(columns[2]["cellType"], "checkbox", "the last column has checkbox cells"); - }); - QUnit.test("Text property test - two way binding", function (assert) { - var property = new Survey.JsonObjectProperty("text"); - property.type = "text"; - var propertyEditor = new SurveyEditor.SurveyObjectProperty(property); - var editor = (propertyEditor.editor); - editor.koValue("1"); - editor.onApplyClick(); - assert.equal(propertyEditor.koValue(), "1", "the value is set correctly from the editor"); - propertyEditor.koValue("2"); - assert.equal(editor.koValue(), "2", "the value is set correctly from text input"); - }); - QUnit.test("SurveyPropertyResultfullEditor test", function (assert) { - var editor = new SurveyEditor.SurveyPropertyResultfullEditor(); - editor.value = new Survey.ChoicesRestfull(); - editor.koPath("path1"); - editor.koValueName("name2"); - editor.koTitleName("title3"); - assert.equal(editor.question.choicesByUrl.path, "path1", "test path is set"); - assert.equal(editor.question.choicesByUrl.valueName, "name2", "test name is set"); - assert.equal(editor.question.choicesByUrl.titleName, "title3", "test title is set"); - }); - -}; \ No newline at end of file + itemValueProperty.onAddClick(); + itemValueProperty.onAddClick(); + itemValueProperty.onResetClick(); + assert.equal(itemValueProperty.koItems().length, 3, "there are three elements"); +}); +QUnit.test("SurveyPropertyItemValue: Value and Text are same", function (assert) { + var choices = [{ value: 1, text: "1" }, { value: "item 2", text: "item 2" }]; + var itemValueProperty = new SurveyPropertyItemValuesEditor(); + itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; + itemValueProperty.value = choices; + assert.equal(itemValueProperty.koItems().length, 2, "there are three elements"); + itemValueProperty.onApplyClick(); + assert.equal(choices.length, 2, "there are two items"); + assert.equal(choices[0].value, 1, "the first value is 1"); + assert.equal(choices[0].text, null, "the first text is null"); + assert.equal(choices[1].value, "item 2", "the second value is 'item 2'"); + assert.equal(choices[1].text, null, "the second text is null"); +}); +QUnit.test("SurveyPropertyItemValue: Value and Text are same and editor.alwaySaveTextInPropertyEditors = true", function (assert) { + var choices = [{ value: 1, text: "1" }, { value: "item 2", text: "item 2" }]; + var itemValueProperty = new SurveyPropertyItemValuesEditor(); + itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; + itemValueProperty.value = choices; + itemValueProperty.options = { alwaySaveTextInPropertyEditors: true }; + assert.equal(itemValueProperty.koItems().length, 2, "there are three elements"); + itemValueProperty.onApplyClick(); + assert.equal(choices.length, 2, "there are two items"); + assert.equal(choices[0].value, 1, "the first value is 1"); + assert.equal(choices[0].text, "1", "the first text is '1'"); + assert.equal(choices[1].value, "item 2", "the second value is 'item 2'"); + assert.equal(choices[1].text, "item 2", "the second text is 'item 2'"); +}); + +QUnit.test("SurveyPropertyItemValue_PureValue", function (assert) { + var choices = [1, "item2", { value: 3, text: "item3" }]; + var itemValueProperty = new SurveyPropertyItemValuesEditor(); + itemValueProperty.onChanged = (newValue: Array) => { choices = newValue; }; + itemValueProperty.value = choices; + assert.equal(itemValueProperty.koItems().length, 3, "there are three elements"); + assert.equal(itemValueProperty.koItems()[0].koValue(), 1, "check value of the first element"); + assert.equal(itemValueProperty.koItems()[1].koValue(), "item2", "check value of the second element"); + assert.equal(itemValueProperty.koItems()[2].koValue(), 3, "check value of the third element"); + assert.equal(itemValueProperty.koItems()[2].koText(), "item3", "check text of the third element"); +}); +QUnit.test("SurveyPropertyMatrixDropdownColumns set properties", function (assert) { + var columns: Array = []; + columns.push(new Survey.MatrixDropdownColumn("column 1")); + columns.push(new Survey.MatrixDropdownColumn("column 2")); + columns[0].choices = [1, 2, "three"]; + var itemValueProperty = new SurveyPropertyDropdownColumnsEditor(); + itemValueProperty.onChanged = (newValue: Array) => { columns = newValue; }; + itemValueProperty.value = columns; + assert.equal(itemValueProperty.koItems().length, 2, "there are two elements"); + assert.equal(itemValueProperty.koItems()[0].koName(), "column 1", "the first column name"); + assert.equal(itemValueProperty.koItems()[0].koChoices().length, 3, "there are two elements"); + itemValueProperty.onAddClick(); + itemValueProperty.koItems()[2].koCellType("checkbox"); + itemValueProperty.koItems()[2].koName("column 3"); + assert.equal(itemValueProperty.koItems().length, 3, "There are 3 columns un editor"); + itemValueProperty.onApplyClick(); + assert.equal(columns.length, 3, "There are 3 columns"); + assert.equal(columns[2]["cellType"], "checkbox", "the last column has checkbox cells"); +}); +QUnit.test("Text property test - two way binding", function (assert) { + var property = new Survey.JsonObjectProperty("text"); + property.type = "text"; + var propertyEditor = new SurveyObjectProperty(property); + var editor = (propertyEditor.editor); + editor.koValue("1"); + editor.onApplyClick(); + assert.equal(propertyEditor.koValue(), "1", "the value is set correctly from the editor"); + propertyEditor.koValue("2"); + assert.equal(editor.koValue(), "2", "the value is set correctly from text input"); +}); +QUnit.test("SurveyPropertyResultfullEditor test", function (assert) { + var editor = new SurveyPropertyResultfullEditor(); + editor.value = new Survey.ChoicesRestfull(); + editor.koPath("path1"); + editor.koValueName("name2"); + editor.koTitleName("title3"); + assert.equal(editor.question.choicesByUrl.path, "path1", "test path is set"); + assert.equal(editor.question.choicesByUrl.valueName, "name2", "test name is set"); + assert.equal(editor.question.choicesByUrl.titleName, "title3", "test title is set"); +}); \ No newline at end of file diff --git a/tests/surveyObjectsTests.ts b/tests/surveyObjectsTests.ts index dea9f856f6..6c241d6f57 100644 --- a/tests/surveyObjectsTests.ts +++ b/tests/surveyObjectsTests.ts @@ -1,251 +1,257 @@ -/// -/// -/// -/// -module SurveyObjectEditorTests.Tests { - QUnit.module("surveyObjects"); - - QUnit.test("Initial objects building", function (assert) { - var intend = SurveyEditor.SurveyObjects.intend; - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - assert.equal(objects.koObjects().length, 1 + 3 + 2 + 1 + 2, "survey + 3 pages + 5 questions."); - assert.equal(objects.koSelected(), survey, "The selected object is survey."); - - assert.equal(objects.koObjects()[0].text(), "Survey", "The first item is Survey"); - assert.equal(objects.koObjects()[4].text(), intend + "page2", "The second page"); - assert.equal(objects.koObjects()[5].text(), intend + intend + "question3", "The third question"); - }); - QUnit.test("No name pages", function (assert) { - var intend = SurveyEditor.SurveyObjects.intend; - var survey = createSurvey(); - survey.pages[0].name = ""; - survey.pages[1].name = ""; - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - assert.equal(objects.koObjects()[1].text(), intend + "[Page 1]", "The first item is Survey"); - assert.equal(objects.koObjects()[4].text(), intend + "[Page 2]", "The second page"); - }); - QUnit.test("selectObject method", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - objects.selectObject(survey.pages[1]); - assert.equal(objects.koSelected().value, survey.pages[1], "the second page is selected"); - objects.selectObject(survey.pages[1].questions[0]); - assert.equal(objects.koSelected().value, survey.pages[1].questions[0], "the third question is selected"); - objects.selectObject(survey); - assert.equal(objects.koSelected().value, survey, "survey is selected"); - }); - QUnit.test("addPage method", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - var page = survey.addNewPage("newPage"); - objects.addPage(page); - assert.equal(objects.koObjects()[objects.koObjects().length - 1].value, page, "new object is added"); - assert.equal(objects.koSelected().value, page, "new page is selected"); - }); - QUnit.test("addPage method - insert", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - var page = survey.pages[2]; - survey.pages.splice(2, 1); - objects.removeObject(page); - survey.pages.splice(1, 0, page); - objects.addPage(page); - var pageIndex = survey.pages[0].questions.length + 1 + 1; - assert.equal(objects.koObjects()[pageIndex].value, page, "the page is inserted correctly"); - assert.equal(objects.koObjects()[pageIndex + 1].value, page.questions[0], "the first question is inserted correctly"); - assert.equal(objects.koObjects()[pageIndex + 2].value, page.questions[1], "the second question is inserted correctly"); - assert.equal(objects.koObjects()[pageIndex + 3].value, survey.pages[2], "the last page has the correct index"); - }); +import {SurveyObjects} from "../src/surveyObjects"; +import { + SurveyPropertyTriggersEditor, + SurveyPropertyVisibleTrigger +} from "../src/propertyEditors/propertyTriggersEditor"; +import { + SurveyPropertyValidatorsEditor, + SurveyPropertyValidatorItem +} from "../src/propertyEditors/propertyValidatorsEditor"; +import {SurveyVerbChangeTypeItem, SurveyVerbChangePageItem} from "../src/objectVerbs"; +import * as Survey from "survey-knockout-bootstrap"; - QUnit.test("addQuestion method", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - var page = survey.pages[survey.pages.length - 1]; - var question = page.addNewQuestion("text", "newQuestion"); - objects.addQuestion(page, question); - assert.equal(objects.koObjects()[objects.koObjects().length - 1].value, question, "new object is added"); - assert.equal(objects.koSelected().value, question, "new question is selected"); - }); - QUnit.test("addQuestion to the first page", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - var page = survey.pages[0]; - var question = page.addNewQuestion("text", "newQuestion"); - objects.addQuestion(page, question); - assert.equal(objects.koObjects()[1 + page.questions.length].value, question, "new object is added"); - assert.equal(objects.koSelected().value, question, "new question is selected"); - }); - QUnit.test("removeObject method - remove Question", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - var elementsCount = objects.koObjects().length; - objects.removeObject(survey.pages[1].questions[0]); - assert.equal(objects.koObjects().length, elementsCount - 1, "one element is removed"); - }); - QUnit.test("removeObject method - remove Page", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - var elementsCount = objects.koObjects().length; - objects.removeObject(survey.pages[0]); - assert.equal(objects.koObjects().length, elementsCount - 1 - 2, "page and two it's questions are removed"); - }); - QUnit.test("selectNextQuestion method", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - objects.selectObject(survey.pages[0].questions[0]); - objects.selectNextQuestion(false); - assert.equal(objects.koSelected().value, survey.pages[0].questions[1]); - - objects.selectNextQuestion(true); - assert.equal(objects.koSelected().value, survey.pages[0].questions[0]); - - objects.selectNextQuestion(true); - assert.equal(objects.koSelected().value, survey.pages[0].questions[survey.pages[0].questions.length - 1]); - - objects.selectNextQuestion(false); - assert.equal(objects.koSelected().value, survey.pages[0].questions[0]); - }); - QUnit.test("object changed name", function (assert) { - var survey = createSurvey(); - var objects = new SurveyEditor.SurveyObjects(ko.observableArray(), ko.observable()); - objects.survey = survey; - survey.pages[0].name = "newname"; - objects.nameChanged(survey.pages[0]); - assert.equal(objects.koObjects()[1].text(), SurveyEditor.SurveyObjects.intend + "newname", "new name should be 'newname'"); - }); - QUnit.test("Triggers property editor", function (assert) { - var survey = createSurvey(); - var trigger = new Survey.SurveyTriggerVisible(); - trigger.name = "question1"; - trigger.value = "val1"; - trigger.operator = "notequal"; - trigger.questions.push("question2"); - survey.triggers.push(trigger); - var result = []; - var propEditor = new SurveyEditor.SurveyPropertyTriggersEditor(); - propEditor.onChanged = (newValue: any) => { result = newValue }; - propEditor.object = survey; - propEditor.value = survey.triggers; - assert.equal(propEditor.koItems().length, 1, "There are one trigger initially"); - var koTrigger = propEditor.koSelected(); - assert.equal(koTrigger.koName(), "question1", "Name set correctly"); - assert.equal(koTrigger.koOperator(), "notequal", "operator set correctly"); - assert.equal(koTrigger.koValue(), "val1", "value set correctly"); - assert.deepEqual(koTrigger.questions.koChoosen(), ["question2"], "questions set correctly"); - - propEditor.onAddClick("visibletrigger"); - assert.equal(propEditor.koItems().length, 2, "There are two triggers now"); - koTrigger = propEditor.koSelected(); - assert.equal(koTrigger.koOperator(), "equal", "default operator is equal"); - assert.equal(koTrigger.koIsValid(), false, "the trigger is not valid"); - koTrigger.koName("question2"); - assert.equal(koTrigger.koIsValid(), false, "the trigger is still not valid"); - assert.equal(koTrigger.koRequireValue(), true, "value should be set"); - koTrigger.koOperator("notempty"); - assert.equal(koTrigger.koIsValid(), true, "the trigger is valid"); - assert.equal(koTrigger.koRequireValue(), false, "value should not be set"); - assert.equal(koTrigger.koText(), "Run if 'question2' is not empty", "text for valid trigger"); - - koTrigger.pages.koChoosen.push("page2"); - koTrigger.questions.koChoosen.push("question3"); - koTrigger.koValue(1); - trigger = koTrigger.createTrigger(); - assert.equal(trigger.name, "question2", "create trigger correctly: name"); - assert.equal(trigger.operator, "notempty", "create trigger correctly: operator"); - assert.equal(trigger.value, 1, "create trigger correctly: value"); - assert.deepEqual(trigger.pages, ["page2"], "create trigger correctly: pages"); - assert.deepEqual(trigger.questions, ["question3"], "create trigger correctly: questions"); - - propEditor.onAddClick("visibletrigger"); - assert.equal(propEditor.koItems().length, 3, "There are three triggers now"); - propEditor.onDeleteClick(); - assert.equal(propEditor.koItems().length, 2, "There are again two triggers"); - - propEditor.onApplyClick(); - assert.equal(result.length, 2, "Two triggers are saved"); - - propEditor.onAddClick("completetrigger"); - koTrigger = propEditor.koSelected(); - koTrigger.koName("question2"); - koTrigger.koOperator("notempty"); - propEditor.onApplyClick(); - assert.equal(result.length, 3, "There are 3 triggers"); - assert.equal(result[2].getType(), "completetrigger", "Complete trigger is created"); - }); - QUnit.test("Validators property editor", function (assert) { - var survey = createSurvey(); - var validator = new Survey.NumericValidator(10, 100); - validator.text = "validatortext"; - var question = survey.getQuestionByName("question1"); - question.validators.push(validator); - var result = []; - var propEditor = new SurveyEditor.SurveyPropertyValidatorsEditor(); - propEditor.onChanged = (newValue: any) => { result = newValue }; - propEditor.object = question; - propEditor.value = question.validators; - assert.equal(propEditor.koItems().length, 1, "There are one validator initially"); - var koValidator = propEditor.koSelected(); - assert.equal(koValidator.validator.text, "validatortext", "Validator Text is set correctly"); - assert.equal((koValidator.validator).minValue, 10, "Validator 'minValue' is set correctly"); - assert.equal((koValidator.validator).maxValue, 100, "Validator 'maxValue' is set correctly"); - - propEditor.onAddClick("textvalidator"); - assert.equal(propEditor.koItems().length, 2, "There are two validators now"); - var koValidator = propEditor.koSelected(); - assert.equal(koValidator.text, "textvalidator", "Created with corrected value"); - (koValidator.validator).minLength = 20; - koValidator.validator.text = "text is short."; - - propEditor.onAddClick("textvalidator"); - assert.equal(propEditor.koItems().length, 3, "There are three validators now"); - propEditor.onDeleteClick(); - assert.equal(propEditor.koItems().length, 2, "There are two validators again"); - - propEditor.onApplyClick(); - assert.equal(result.length, 2, "Two validators are saved"); - assert.equal(result[1].minLength, 20, "The properties are saved too"); - }); - QUnit.test("SurveyVerbChangeTypeItem test", function (assert) { - var survey = createSurvey(); - var verb = new SurveyEditor.SurveyVerbChangeTypeItem(survey, survey.pages[0].questions[1], null); - assert.equal(verb.koSelectedItem(), "checkbox", "The default value is checkbox"); - verb.koSelectedItem("dropdown"); - var newQuestion = survey.pages[0].questions[1]; - assert.equal(newQuestion.getType(), "dropdown", "the question becomes 'dropdown'"); - assert.equal(newQuestion["choices"].length, 3, "properties are copied."); - assert.equal(survey.pages[0].questions.length, 2, "we will still have two questions."); - }); - QUnit.test("SurveyVerbChangePageItem test", function (assert) { - var survey = createSurvey(); - var verb = new SurveyEditor.SurveyVerbChangePageItem(survey, survey.pages[0].questions[1], null); - assert.equal(verb.koSelectedItem(), survey.pages[0], "The default value is first page"); - verb.koSelectedItem(survey.pages[2]); - assert.equal(survey.pages[0].questions.length, 1, "one question left on the first page"); - assert.equal(survey.pages[2].questions.length, 3, "three question now on the third page"); - }); - function createSurvey(): Survey.Survey { - return new Survey.Survey({ - pages: [{ - name: 'page1', questions: [{ type: 'text', name: 'question1' }, - { name: "question2", choices: ["one", { value: "two", text: "second value" }, { value: 3, text: "third value" }], type: "checkbox" }] - }, - { name: 'page2', questions: [{ name: "question3", type: "comment" }] }, - { - name: 'page3', questions: [{ name: "question4", columns: ["Column 1", "Column 2", "Column 3"], rows: ["Row 1", "Row 2"], type: "matrix" }, - { name: "question5", type: "rating" }] - }] - }); - } +QUnit.module("surveyObjects"); +QUnit.test("Initial objects building", function (assert) { + var intend = SurveyObjects.intend; + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + assert.equal(objects.koObjects().length, 1 + 3 + 2 + 1 + 2, "survey + 3 pages + 5 questions."); + assert.equal(objects.koSelected(), survey, "The selected object is survey."); + + assert.equal(objects.koObjects()[0].text(), "Survey", "The first item is Survey"); + assert.equal(objects.koObjects()[4].text(), intend + "page2", "The second page"); + assert.equal(objects.koObjects()[5].text(), intend + intend + "question3", "The third question"); +}); +QUnit.test("No name pages", function (assert) { + var intend = SurveyObjects.intend; + var survey = createSurvey(); + survey.pages[0].name = ""; + survey.pages[1].name = ""; + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + assert.equal(objects.koObjects()[1].text(), intend + "[Page 1]", "The first item is Survey"); + assert.equal(objects.koObjects()[4].text(), intend + "[Page 2]", "The second page"); +}); +QUnit.test("selectObject method", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + objects.selectObject(survey.pages[1]); + assert.equal(objects.koSelected().value, survey.pages[1], "the second page is selected"); + objects.selectObject(survey.pages[1].questions[0]); + assert.equal(objects.koSelected().value, survey.pages[1].questions[0], "the third question is selected"); + objects.selectObject(survey); + assert.equal(objects.koSelected().value, survey, "survey is selected"); +}); +QUnit.test("addPage method", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + var page = survey.addNewPage("newPage"); + objects.addPage(page); + assert.equal(objects.koObjects()[objects.koObjects().length - 1].value, page, "new object is added"); + assert.equal(objects.koSelected().value, page, "new page is selected"); +}); +QUnit.test("addPage method - insert", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + var page = survey.pages[2]; + survey.pages.splice(2, 1); + objects.removeObject(page); + survey.pages.splice(1, 0, page); + objects.addPage(page); + var pageIndex = survey.pages[0].questions.length + 1 + 1; + assert.equal(objects.koObjects()[pageIndex].value, page, "the page is inserted correctly"); + assert.equal(objects.koObjects()[pageIndex + 1].value, page.questions[0], "the first question is inserted correctly"); + assert.equal(objects.koObjects()[pageIndex + 2].value, page.questions[1], "the second question is inserted correctly"); + assert.equal(objects.koObjects()[pageIndex + 3].value, survey.pages[2], "the last page has the correct index"); +}); + +QUnit.test("addQuestion method", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + var page = survey.pages[survey.pages.length - 1]; + var question = page.addNewQuestion("text", "newQuestion"); + objects.addQuestion(page, question); + assert.equal(objects.koObjects()[objects.koObjects().length - 1].value, question, "new object is added"); + assert.equal(objects.koSelected().value, question, "new question is selected"); +}); +QUnit.test("addQuestion to the first page", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + var page = survey.pages[0]; + var question = page.addNewQuestion("text", "newQuestion"); + objects.addQuestion(page, question); + assert.equal(objects.koObjects()[1 + page.questions.length].value, question, "new object is added"); + assert.equal(objects.koSelected().value, question, "new question is selected"); +}); +QUnit.test("removeObject method - remove Question", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + var elementsCount = objects.koObjects().length; + objects.removeObject(survey.pages[1].questions[0]); + assert.equal(objects.koObjects().length, elementsCount - 1, "one element is removed"); +}); +QUnit.test("removeObject method - remove Page", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + var elementsCount = objects.koObjects().length; + objects.removeObject(survey.pages[0]); + assert.equal(objects.koObjects().length, elementsCount - 1 - 2, "page and two it's questions are removed"); +}); +QUnit.test("selectNextQuestion method", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + objects.selectObject(survey.pages[0].questions[0]); + objects.selectNextQuestion(false); + assert.equal(objects.koSelected().value, survey.pages[0].questions[1]); + + objects.selectNextQuestion(true); + assert.equal(objects.koSelected().value, survey.pages[0].questions[0]); + + objects.selectNextQuestion(true); + assert.equal(objects.koSelected().value, survey.pages[0].questions[survey.pages[0].questions.length - 1]); + + objects.selectNextQuestion(false); + assert.equal(objects.koSelected().value, survey.pages[0].questions[0]); +}); +QUnit.test("object changed name", function (assert) { + var survey = createSurvey(); + var objects = new SurveyObjects(ko.observableArray(), ko.observable()); + objects.survey = survey; + survey.pages[0].name = "newname"; + objects.nameChanged(survey.pages[0]); + assert.equal(objects.koObjects()[1].text(), SurveyObjects.intend + "newname", "new name should be 'newname'"); +}); +QUnit.test("Triggers property editor", function (assert) { + var survey = createSurvey(); + var trigger = new Survey.SurveyTriggerVisible(); + trigger.name = "question1"; + trigger.value = "val1"; + trigger.operator = "notequal"; + trigger.questions.push("question2"); + survey.triggers.push(trigger); + var result = []; + var propEditor = new SurveyPropertyTriggersEditor(); + propEditor.onChanged = (newValue: any) => { result = newValue }; + propEditor.object = survey; + propEditor.value = survey.triggers; + assert.equal(propEditor.koItems().length, 1, "There are one trigger initially"); + var koTrigger = propEditor.koSelected(); + assert.equal(koTrigger.koName(), "question1", "Name set correctly"); + assert.equal(koTrigger.koOperator(), "notequal", "operator set correctly"); + assert.equal(koTrigger.koValue(), "val1", "value set correctly"); + assert.deepEqual(koTrigger.questions.koChoosen(), ["question2"], "questions set correctly"); + + propEditor.onAddClick("visibletrigger"); + assert.equal(propEditor.koItems().length, 2, "There are two triggers now"); + koTrigger = propEditor.koSelected(); + assert.equal(koTrigger.koOperator(), "equal", "default operator is equal"); + assert.equal(koTrigger.koIsValid(), false, "the trigger is not valid"); + koTrigger.koName("question2"); + assert.equal(koTrigger.koIsValid(), false, "the trigger is still not valid"); + assert.equal(koTrigger.koRequireValue(), true, "value should be set"); + koTrigger.koOperator("notempty"); + assert.equal(koTrigger.koIsValid(), true, "the trigger is valid"); + assert.equal(koTrigger.koRequireValue(), false, "value should not be set"); + assert.equal(koTrigger.koText(), "Run if 'question2' is not empty", "text for valid trigger"); + + koTrigger.pages.koChoosen.push("page2"); + koTrigger.questions.koChoosen.push("question3"); + koTrigger.koValue(1); + trigger = koTrigger.createTrigger(); + assert.equal(trigger.name, "question2", "create trigger correctly: name"); + assert.equal(trigger.operator, "notempty", "create trigger correctly: operator"); + assert.equal(trigger.value, 1, "create trigger correctly: value"); + assert.deepEqual(trigger.pages, ["page2"], "create trigger correctly: pages"); + assert.deepEqual(trigger.questions, ["question3"], "create trigger correctly: questions"); + + propEditor.onAddClick("visibletrigger"); + assert.equal(propEditor.koItems().length, 3, "There are three triggers now"); + propEditor.onDeleteClick(); + assert.equal(propEditor.koItems().length, 2, "There are again two triggers"); + + propEditor.onApplyClick(); + assert.equal(result.length, 2, "Two triggers are saved"); + + propEditor.onAddClick("completetrigger"); + koTrigger = propEditor.koSelected(); + koTrigger.koName("question2"); + koTrigger.koOperator("notempty"); + propEditor.onApplyClick(); + assert.equal(result.length, 3, "There are 3 triggers"); + assert.equal(result[2].getType(), "completetrigger", "Complete trigger is created"); +}); +QUnit.test("Validators property editor", function (assert) { + var survey = createSurvey(); + var validator = new Survey.NumericValidator(10, 100); + validator.text = "validatortext"; + var question = survey.getQuestionByName("question1"); + question.validators.push(validator); + var result = []; + var propEditor = new SurveyPropertyValidatorsEditor(); + propEditor.onChanged = (newValue: any) => { result = newValue }; + propEditor.object = question; + propEditor.value = question.validators; + assert.equal(propEditor.koItems().length, 1, "There are one validator initially"); + var koValidator = propEditor.koSelected(); + assert.equal(koValidator.validator.text, "validatortext", "Validator Text is set correctly"); + assert.equal((koValidator.validator).minValue, 10, "Validator 'minValue' is set correctly"); + assert.equal((koValidator.validator).maxValue, 100, "Validator 'maxValue' is set correctly"); + + propEditor.onAddClick("textvalidator"); + assert.equal(propEditor.koItems().length, 2, "There are two validators now"); + var koValidator = propEditor.koSelected(); + assert.equal(koValidator.text, "textvalidator", "Created with corrected value"); + (koValidator.validator).minLength = 20; + koValidator.validator.text = "text is short."; + + propEditor.onAddClick("textvalidator"); + assert.equal(propEditor.koItems().length, 3, "There are three validators now"); + propEditor.onDeleteClick(); + assert.equal(propEditor.koItems().length, 2, "There are two validators again"); + + propEditor.onApplyClick(); + assert.equal(result.length, 2, "Two validators are saved"); + assert.equal(result[1].minLength, 20, "The properties are saved too"); +}); +QUnit.test("SurveyVerbChangeTypeItem test", function (assert) { + var survey = createSurvey(); + var verb = new SurveyVerbChangeTypeItem(survey, survey.pages[0].questions[1], null); + assert.equal(verb.koSelectedItem(), "checkbox", "The default value is checkbox"); + verb.koSelectedItem("dropdown"); + var newQuestion = survey.pages[0].questions[1]; + assert.equal(newQuestion.getType(), "dropdown", "the question becomes 'dropdown'"); + assert.equal(newQuestion["choices"].length, 3, "properties are copied."); + assert.equal(survey.pages[0].questions.length, 2, "we will still have two questions."); +}); +QUnit.test("SurveyVerbChangePageItem test", function (assert) { + var survey = createSurvey(); + var verb = new SurveyVerbChangePageItem(survey, survey.pages[0].questions[1], null); + assert.equal(verb.koSelectedItem(), survey.pages[0], "The default value is first page"); + verb.koSelectedItem(survey.pages[2]); + assert.equal(survey.pages[0].questions.length, 1, "one question left on the first page"); + assert.equal(survey.pages[2].questions.length, 3, "three question now on the third page"); +}); + +function createSurvey(): Survey.Survey { + return new Survey.Survey({ + pages: [{ + name: 'page1', questions: [{ type: 'text', name: 'question1' }, + { name: "question2", choices: ["one", { value: "two", text: "second value" }, { value: 3, text: "third value" }], type: "checkbox" }] + }, + { name: 'page2', questions: [{ name: "question3", type: "comment" }] }, + { + name: 'page3', questions: [{ name: "question4", columns: ["Column 1", "Column 2", "Column 3"], rows: ["Row 1", "Row 2"], type: "matrix" }, + { name: "question5", type: "rating" }] + }] + }); } \ No newline at end of file diff --git a/tests/undoredoTests.ts b/tests/undoredoTests.ts index e5ae681e3e..955ffb69b7 100644 --- a/tests/undoredoTests.ts +++ b/tests/undoredoTests.ts @@ -1,92 +1,95 @@ -/// -module SurveyEditorTests.Tests { - QUnit.module("UndoRedoTests"); - QUnit.test("Enabeling undo redo", function (assert) { - var survey = new Survey.Survey(getSurveyJson()); - var undo = new SurveyEditor.SurveyUndoRedo(); - assert.equal(undo.koCanUndo(), false, "CanUndo 1"); - assert.equal(undo.koCanRedo(), false, "CanRedo 1"); +import {SurveyUndoRedo} from "../src/undoredo"; +import {SurveyEditor} from "../src/editor"; +import * as Survey from "survey-knockout-bootstrap"; + +QUnit.module("UndoRedoTests"); + +QUnit.test("Enabeling undo redo", function (assert) { + var survey = new Survey.Survey(getSurveyJson()); + var undo = new SurveyUndoRedo(); + assert.equal(undo.koCanUndo(), false, "CanUndo 1"); + assert.equal(undo.koCanRedo(), false, "CanRedo 1"); + undo.setCurrent(survey, null); + assert.equal(undo.koCanUndo(), false, "CanUndo 2"); + assert.equal(undo.koCanRedo(), false, "CanRedo 2"); + undo.setCurrent(survey, null); + assert.equal(undo.koCanUndo(), true, "CanUndo 3"); + assert.equal(undo.koCanRedo(), false, "CanRedo 3"); + undo.undo(); + assert.equal(undo.koCanUndo(), false, "CanUndo 4"); + assert.equal(undo.koCanRedo(), true, "CanRedo 4"); + undo.redo(); + assert.equal(undo.koCanUndo(), true, "CanUndo 5"); + assert.equal(undo.koCanRedo(), false, "CanRedo 5"); + undo.undo(); + undo.setCurrent(survey, null); + assert.equal(undo.koCanUndo(), true, "CanUndo 6"); + assert.equal(undo.koCanRedo(), false, "CanRedo 6"); + undo.setCurrent(survey, null); + assert.equal(undo.koCanUndo(), true, "CanUndo 7"); + assert.equal(undo.koCanRedo(), false, "CanRedo 7"); + undo.undo(); + assert.equal(undo.koCanUndo(), true, "CanUndo 8"); + assert.equal(undo.koCanRedo(), true, "CanRedo 8"); + undo.undo(); + assert.equal(undo.koCanUndo(), false, "CanUndo 9"); + assert.equal(undo.koCanRedo(), true, "CanRedo 9"); +}); +QUnit.test("Do undo", function (assert) { + var survey = new Survey.Survey(getSurveyJson()); + var undo = new SurveyUndoRedo(); + undo.setCurrent(survey, null); + survey.addNewPage("New Page"); + undo.setCurrent(survey, null); + assert.equal(4, survey.pages.length); + survey = new Survey.Survey(undo.undo().surveyJSON); + assert.equal(3, survey.pages.length); +}); +QUnit.test("Do undo/redo", function (assert) { + var survey = new Survey.Survey(getSurveyJson()); + var undo = new SurveyUndoRedo(); + undo.setCurrent(survey, null); + survey.addNewPage("New Page"); + undo.setCurrent(survey, null); + survey = new Survey.Survey(undo.undo().surveyJSON); + assert.equal(3, survey.pages.length, "3 pages after undo"); + survey = new Survey.Survey(undo.redo().surveyJSON); + assert.equal(4, survey.pages.length, "4 pages after redo"); +}); +QUnit.test("Undo maximum count", function (assert) { + var survey = new Survey.Survey(getSurveyJson()); + var undo = new SurveyUndoRedo(); + undo.maximumCount = 2; + for (var i = 0; i < 10; i++) { undo.setCurrent(survey, null); - assert.equal(undo.koCanUndo(), false, "CanUndo 2"); - assert.equal(undo.koCanRedo(), false, "CanRedo 2"); - undo.setCurrent(survey, null); - assert.equal(undo.koCanUndo(), true, "CanUndo 3"); - assert.equal(undo.koCanRedo(), false, "CanRedo 3"); - undo.undo(); - assert.equal(undo.koCanUndo(), false, "CanUndo 4"); - assert.equal(undo.koCanRedo(), true, "CanRedo 4"); - undo.redo(); - assert.equal(undo.koCanUndo(), true, "CanUndo 5"); - assert.equal(undo.koCanRedo(), false, "CanRedo 5"); - undo.undo(); - undo.setCurrent(survey, null); - assert.equal(undo.koCanUndo(), true, "CanUndo 6"); - assert.equal(undo.koCanRedo(), false, "CanRedo 6"); - undo.setCurrent(survey, null); - assert.equal(undo.koCanUndo(), true, "CanUndo 7"); - assert.equal(undo.koCanRedo(), false, "CanRedo 7"); - undo.undo(); - assert.equal(undo.koCanUndo(), true, "CanUndo 8"); - assert.equal(undo.koCanRedo(), true, "CanRedo 8"); - undo.undo(); - assert.equal(undo.koCanUndo(), false, "CanUndo 9"); - assert.equal(undo.koCanRedo(), true, "CanRedo 9"); - }); - QUnit.test("Do undo", function (assert) { - var survey = new Survey.Survey(getSurveyJson()); - var undo = new SurveyEditor.SurveyUndoRedo(); - undo.setCurrent(survey, null); - survey.addNewPage("New Page"); - undo.setCurrent(survey, null); - assert.equal(4, survey.pages.length); - survey = new Survey.Survey(undo.undo().surveyJSON); - assert.equal(3, survey.pages.length); - }); - QUnit.test("Do undo/redo", function (assert) { - var survey = new Survey.Survey(getSurveyJson()); - var undo = new SurveyEditor.SurveyUndoRedo(); - undo.setCurrent(survey, null); - survey.addNewPage("New Page"); - undo.setCurrent(survey, null); - survey = new Survey.Survey(undo.undo().surveyJSON); - assert.equal(3, survey.pages.length, "3 pages after undo"); - survey = new Survey.Survey(undo.redo().surveyJSON); - assert.equal(4, survey.pages.length, "4 pages after redo"); - }); - QUnit.test("Undo maximum count", function (assert) { - var survey = new Survey.Survey(getSurveyJson()); - var undo = new SurveyEditor.SurveyUndoRedo(); - undo.maximumCount = 2; - for (var i = 0; i < 10; i++) { - undo.setCurrent(survey, null); - } - assert.equal(undo.koCanUndo(), true, "Initial can undo"); - undo.undo(); - undo.undo(); - assert.equal(undo.koCanUndo(), false, "Store only for two undo"); - }); - QUnit.test("Do undo/redo with editor", function (assert) { - var editor = new SurveyEditor.SurveyEditor(); - editor.text = JSON.stringify(getSurveyJson()); - editor.addPage(); - assert.equal(4, editor.survey.pages.length); - editor.doUndoClick(); - assert.equal(3, editor.survey.pages.length); - editor.doRedoClick(); - assert.equal(4, editor.survey.pages.length); - assert.equal(editor.koSelectedObject().value, editor.survey.pages[editor.survey.pages.length - 1], "the last page should be selected"); - }); - function getSurveyJson(): any { - return { - pages: [{ - name: 'page1', questions: [{ type: 'text', name: 'question1' }, - { name: "question2", choices: ["one", { value: "two", text: "second value" }, { value: 3, text: "third value" }], type: "checkbox" }] - }, - { name: 'page2', questions: [{ name: "question3", type: "comment" }] }, - { - name: 'page3', questions: [{ name: "question4", columns: ["Column 1", "Column 2", "Column 3"], rows: ["Row 1", "Row 2"], type: "matrix" }, - { name: "question5", type: "rating" }] - }] - }; } + assert.equal(undo.koCanUndo(), true, "Initial can undo"); + undo.undo(); + undo.undo(); + assert.equal(undo.koCanUndo(), false, "Store only for two undo"); +}); +QUnit.test("Do undo/redo with editor", function (assert) { + var editor = new SurveyEditor(); + editor.text = JSON.stringify(getSurveyJson()); + editor.addPage(); + assert.equal(4, editor.survey.pages.length); + editor.doUndoClick(); + assert.equal(3, editor.survey.pages.length); + editor.doRedoClick(); + assert.equal(4, editor.survey.pages.length); + assert.equal(editor.koSelectedObject().value, editor.survey.pages[editor.survey.pages.length - 1], "the last page should be selected"); +}); + +function getSurveyJson(): any { + return { + pages: [{ + name: 'page1', questions: [{ type: 'text', name: 'question1' }, + { name: "question2", choices: ["one", { value: "two", text: "second value" }, { value: 3, text: "third value" }], type: "checkbox" }] + }, + { name: 'page2', questions: [{ name: "question3", type: "comment" }] }, + { + name: 'page3', questions: [{ name: "question4", columns: ["Column 1", "Column 2", "Column 3"], rows: ["Row 1", "Row 2"], type: "matrix" }, + { name: "question5", type: "rating" }] + }] + }; } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..02d5d7b2b7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "sourceMap": true, + "noImplicitAny": false, + "jsx": "react" + }, + "include": [ + "typings/index.d.ts", + "src/**/*" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts" + ] +} \ No newline at end of file diff --git a/typings.json b/typings.json index df68efe1e4..87506b5274 100644 --- a/typings.json +++ b/typings.json @@ -1,9 +1,11 @@ { "name": "surveyjs.editor", "globalDependencies": { - "surveyjs": "github:andrewtelnov/surveyjs/lib_typings/survey.d.ts", "knockout": "github:DefinitelyTyped/DefinitelyTyped/knockout/knockout.d.ts#73110d92bdab2367e326f297bef3574285cba329", "ace": "github:DefinitelyTyped/DefinitelyTyped/ace/ace.d.ts#73110d92bdab2367e326f297bef3574285cba329", "qunit": "github:DefinitelyTyped/DefinitelyTyped/qunit/qunit.d.ts#73110d92bdab2367e326f297bef3574285cba329" + }, + "dependencies": { + "survey-knockout-bootstrap": "github:andrewtelnov/surveyjs/lib_typings/entries/ko.d.ts" } } diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000000..116a4802db --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,69 @@ +'use strict'; + +var webpack = require('webpack'); +var path = require('path'); + +module.exports = function(options) { + var babelConfig = { + presets: [ + [require.resolve('babel-preset-es2015'), { loose: true }], + require.resolve('babel-preset-react') + ] + }; + + var config = { + resolveLoader: {root: path.join(__dirname, 'node_modules')}, + resolve: { + extensions: ['', '.js', '.ts', '.jsx', '.tsx'] + }, + entry: {}, + output: { + filename: '[name].js', + library: 'SurveyEditor', + libraryTarget: 'umd', + umdNamedDefine: true + }, + externals: { + 'knockout': { + root: 'ko', + commonjs2: 'knockout', + commonjs: 'knockout', + amd: 'knockout' + }, + 'survey-knockout-bootstrap': { + root: 'Survey', + commonjs2: 'survey-knockout-bootstrap', + commonjs: 'survey-knockout-bootstrap', + amd: 'survey-knockout-bootstrap' + } + }, + module: { + preLoaders: [ + { test: /\.(js|jsx)$/, loader: "source-map-loader" } + ], + loaders: [ + { + test: /\.(ts|tsx)$/, + loaders:[ + require.resolve('babel-loader') + '?' + JSON.stringify(babelConfig), // TODO why do we need it + require.resolve('ts-loader') + ] + }, + { + test: /\.(js|jsx)$/, + loader: require.resolve('babel-loader'), + query: babelConfig + } + ] + }, + debug: true, + plugins: [ + new webpack.NoErrorsPlugin() + ], + devtool: 'inline-source-map' + }; + + config.entry[options.bundleName] = path.resolve(__dirname, options.entryPoint); + + return config; +}; \ No newline at end of file