Skip to content

Commit

Permalink
support "completedbefore" state: surveyjs#534
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov committed Aug 2, 2017
1 parent 72cabbc commit cd50e77
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/knockout/kosurvey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ export class Survey extends SurveyModel {
survey.onRendered.fire(self, {});
survey.afterRenderSurvey(element);
}
public loadSurveyFromService(surveyId: string = null, renderedElement: any = null) {
public loadSurveyFromService(surveyId: string = null, clientId: string = null, renderedElement: any = null) {
if (renderedElement) {
this.renderedElement = renderedElement;
}
super.loadSurveyFromService(surveyId);
super.loadSurveyFromService(surveyId, clientId);
}
protected setCompleted() {
super.setCompleted();
Expand Down
3 changes: 3 additions & 0 deletions src/knockout/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ <h3><!-- ko template: { name: 'survey-string', data: locTitle } --><!-- /ko --><
</div>
</div>
<!-- /ko -->
<!-- ko if: koState() == "completedbefore" -->
<div data-bind="html: processedCompletedBeforeHtml"></div>
<!-- /ko -->
<!-- ko if: koState() == "loading" -->
<div data-bind="html: processedLoadingHtml"></div>
<!-- /ko -->
Expand Down
5 changes: 5 additions & 0 deletions src/react/reactSurvey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class Survey extends React.Component<any, any> implements ISurveyCreator
}
render(): JSX.Element {
if (this.survey.state == "completed") return this.renderCompleted();
if (this.survey.state == "completedbefore") return this.renderCompletedBefore();
if (this.survey.state == "loading") return this.renderLoading();
return this.renderSurvey();
}
Expand All @@ -62,6 +63,10 @@ export class Survey extends React.Component<any, any> implements ISurveyCreator
var htmlValue = { __html: this.survey.processedCompletedHtml };
return (<div><div dangerouslySetInnerHTML={htmlValue} />{completedState}</div>);
}
protected renderCompletedBefore(): JSX.Element {
var htmlValue = { __html: this.survey.processedCompletedBeforeHtml };
return (<div dangerouslySetInnerHTML={htmlValue} />);
}
protected renderLoading(): JSX.Element {
var htmlValue = { __html: this.survey.processedLoadingHtml };
return (<div dangerouslySetInnerHTML={htmlValue} />);
Expand Down
83 changes: 65 additions & 18 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm

private locTitleValue : LocalizableString;
private locCompletedHtmlValue : LocalizableString;
private locCompletedBeforeHtmlValue : LocalizableString;
private locLoadingHtmlValue : LocalizableString;
private locPagePrevTextValue : LocalizableString;
private locPageNextTextValue : LocalizableString;
Expand All @@ -136,6 +137,7 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
private questionTitleLocationValue: string = "top";
private localeValue: string = "";
private isCompleted: boolean = false;
private isCompletedBefore: boolean = false;
private isLoading: boolean = false;
private processedTextValues: HashTable<any> = {};
private textPreProcessor: TextPreProcessor;
Expand Down Expand Up @@ -395,6 +397,7 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
this.locTitleValue = new LocalizableString(this, true);
this.locTitleValue.onRenderedHtmlCallback = function(text) { return self.processedTitle; };
this.locCompletedHtmlValue = new LocalizableString(this);
this.locCompletedBeforeHtmlValue = new LocalizableString(this);
this.locLoadingHtmlValue = new LocalizableString(this);
this.locPagePrevTextValue = new LocalizableString(this);
this.locPageNextTextValue = new LocalizableString(this);
Expand All @@ -418,9 +421,12 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
if (typeof jsonObj === 'string' || jsonObj instanceof String) {
jsonObj = JSON.parse(jsonObj as string);
}
if(jsonObj && jsonObj.clientId) {
this.clientId = jsonObj.clientId;
}
this.setJsonObject(jsonObj);
if (this.surveyId) {
this.loadSurveyFromService(this.surveyId);
this.loadSurveyFromService(this.surveyId, this.clientId);
}
}
this.onCreating();
Expand Down Expand Up @@ -463,6 +469,14 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
public get completedHtml(): string { return this.locCompletedHtml.text;}
public set completedHtml(value: string) { this.locCompletedHtml.text = value;}
get locCompletedHtml(): LocalizableString { return this.locCompletedHtmlValue;}
/**
* The html that shows if the end user has already completed the survey.
* @see clientId
* @see locale
*/
public get completedBeforeHtml(): string { return this.locCompletedBeforeHtml.text;}
public set completedBeforeHtml(value: string) { this.locCompletedBeforeHtml.text = value;}
get locCompletedBeforeHtml(): LocalizableString { return this.locCompletedBeforeHtmlValue;}
/**
* The html that shows on loading survey Json from the dxsurvey.com service.
* @see surveyId
Expand Down Expand Up @@ -693,6 +707,7 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
public get state(): string {
if (this.isLoading) return "loading";
if (this.isCompleted) return "completed";
if (this.isCompletedBefore) return "completedbefore";
return (this.currentPage) ? "running" : "empty"
}
public get completedState(): string {return this.completedStateValue; }
Expand Down Expand Up @@ -720,6 +735,8 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
this.variablesHash = {};
}
this.isCompleted = false;
this.isCompletedBefore = false;
this.isLoading = false;
if (gotoFirstPage && this.visiblePageCount > 0) {
this.currentPage = this.visiblePages[0];
}
Expand Down Expand Up @@ -964,6 +981,16 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
}
return "<h3>" + this.getLocString("completingSurvey") + "</h3>";
}
/**
* Returns the html showing that the user has already completed the survey
* @see completedHtml
*/
public get processedCompletedBeforeHtml(): string {
if (this.completedBeforeHtml) {
return this.processHtml(this.completedBeforeHtml);
}
return "<h3>" + this.getLocString("completingSurveyBefore") + "</h3>";
}
/**
* Returns the html that shows on loading the json.
*/
Expand Down Expand Up @@ -1030,10 +1057,13 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
}
return true;
}
protected createSurveyService() : dxSurveyService {
return new dxSurveyService();
}
protected uploadFileCore(name: string, file: File, uploadingCallback: (status: string) => any) {
var self = this;
if (uploadingCallback) uploadingCallback("uploading");
new dxSurveyService().sendFile(this.surveyPostId, file, function (success: boolean, response: any) {
this.createSurveyService().sendFile(this.surveyPostId, file, function (success: boolean, response: any) {
if (uploadingCallback) uploadingCallback(success ? "success" : "error");
if (success) {
self.setValue(name, response);
Expand Down Expand Up @@ -1252,7 +1282,7 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
if(this.surveyShowDataSaving) {
this.setCompletedState("saving", "");
}
new dxSurveyService().sendResult(postId, this.data, function (success: boolean, response: any) {
this.createSurveyService().sendResult(postId, this.data, function (success: boolean, response: any) {
if(self.surveyShowDataSaving) {
if(success) {
self.setCompletedState("success", "");
Expand All @@ -1271,29 +1301,48 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
*/
public getResult(resultId: string, name: string) {
var self = this;
new dxSurveyService().getResult(resultId, name, function (success: boolean, data: any, dataList: any[], response: any) {
this.createSurveyService().getResult(resultId, name, function (success: boolean, data: any, dataList: any[], response: any) {
self.onGetResult.fire(self, { success: success, data: data, dataList: dataList, response: response });
});
}
/**
* Loads the survey Json from the [dxsurvey.com](http://www.dxsurvey.com) service.
* Loads the survey Json from the [dxsurvey.com](http://www.dxsurvey.com) service. If clientId is not null and user has already completed the survey, the survey will go into "completedbefore" state.
* @param surveyId [dxsurvey.com](http://www.dxsurvey.com) service surveyId
* @param clientId indentificator for a user, for example e-mail or unique customer id in your web application.
* @see state
*/
public loadSurveyFromService(surveyId: string = null) {
public loadSurveyFromService(surveyId: string = null, cliendId: string = null) {
if (surveyId) {
this.surveyId = surveyId;
}
if(cliendId) {
this.clientId = cliendId;
}
var self = this;
this.isLoading = true;
this.onLoadingSurveyFromService();
new dxSurveyService().loadSurvey(this.surveyId, function (success: boolean, result: string, response: any) {
self.isLoading = false;
if (success && result) {
self.setJsonObject(result);
self.notifyAllQuestionsOnValueChanged();
self.onLoadSurveyFromService();
}
});
if(cliendId) {
this.createSurveyService().getSurveyJsonAndIsCompleted(this.surveyId, this.clientId, function (success: boolean, json: string, isCompleted: string, response: any) {
self.isLoading = false;
if (success) {
self.isCompletedBefore = isCompleted == "completed";
self.loadSurveyFromServiceJson(json);
}
});
} else {
this.createSurveyService().loadSurvey(this.surveyId, function (success: boolean, result: string, response: any) {
self.isLoading = false;
if (success) {
self.loadSurveyFromServiceJson(result);
}
});
}
}
private loadSurveyFromServiceJson(json: any) {
if(!json) return;
this.setJsonObject(json);
this.notifyAllQuestionsOnValueChanged();
this.onLoadSurveyFromService();
}
protected onLoadingSurveyFromService() {
}
Expand Down Expand Up @@ -1598,12 +1647,10 @@ export class SurveyModel extends Base implements ISurvey, ISurveyData, ISurveyIm
}
}

//Make localizable: completedHtml, pagePrevText, pageNextText, completeText

JsonObject.metaData.addClass("survey", [{ name: "locale", choices: () => { return surveyLocalization.getLocales() } },
{name: "title", serializationProperty: "locTitle"}, { name: "focusFirstQuestionAutomatic:boolean", default: true},
{name: "completedHtml:html", serializationProperty: "locCompletedHtml"}, {name: "loadingHtml:html", serializationProperty: "locLoadingHtml"},
{ name: "pages", className: "page", visible: false },
{name: "completedHtml:html", serializationProperty: "locCompletedHtml"}, {name: "completedBeforeHtml:html", serializationProperty: "locCompletedBeforeHtml"},
{name: "loadingHtml:html", serializationProperty: "locLoadingHtml"}, { name: "pages", className: "page", visible: false },
{ name: "questions", alternativeName: "elements", baseClassName: "question", visible: false, onGetValue: function (obj) { return null; }, onSetValue: function (obj, value, jsonConverter) { var page = obj.addNewPage(""); jsonConverter.toObject({ questions: value }, page); } },
{ name: "triggers:triggers", baseClassName: "surveytrigger", classNamePart: "trigger" },
{name: "surveyId", visible: false}, {name: "surveyPostId", visible: false}, {name: "surveyShowDataSaving", visible: false}, "cookieName", "sendResultOnPageNext:boolean",
Expand Down
1 change: 1 addition & 0 deletions src/surveyStrings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export var surveyStrings = {
progressText: "Page {0} of {1}",
emptySurvey: "There is no visible page or question in the survey.",
completingSurvey: "Thank you for completing the survey!",
completingSurveyBefore: "Our records show that you have already completed this survey.",
loadingSurvey: "Survey is loading...",
optionsCaption: "Choose...",
requiredError: "Please answer the question.",
Expand Down
1 change: 1 addition & 0 deletions src/vue/survey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</div>
</div>
</div>
<div v-if="survey.state === 'completedbefore'" v-html="survey.processedCompletedBeforeHtml"></div>
<div v-if="survey.state === 'loading'" v-html="survey.processedLoadingHtml"></div>
<div v-if="survey.state === 'empty'" :class="css.body">{{survey.emptySurveyText}}</div>
</div>
Expand Down
57 changes: 42 additions & 15 deletions tests/surveytests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {CustomWidgetCollection, QuestionCustomWidget} from "../src/questionCusto
import {QuestionSelectBase} from "../src/question_baseselect";
import {LocalizableString} from "../src/localizablestring";
import {surveyCss} from "../src/defaultCss/cssstandard";
import {dxSurveyService} from "../src/dxSurveyService";

export default QUnit.module("Survey");

Expand Down Expand Up @@ -1516,21 +1517,6 @@ QUnit.test("Use send data to custom server", function (assert) {
onCompleteOptions.showDataSavingSuccess();
assert.equal(survey.completedState, "success", "The complete state is success");
});
function twoPageSimplestSurvey() {
var survey = new SurveyModel();
var page = survey.addNewPage("Page 1");
page.addNewQuestion("text", "question1");
page.addNewQuestion("text", "question2");
page = survey.addNewPage("Page 2");
page.addNewQuestion("text", "question3");
page.addNewQuestion("text", "question4");
return survey;
}
function createPageWithQuestion(name: string) : PageModel {
var page = new PageModel(name);
page.addNewQuestion("text", "q1");
return page;
}

QUnit.test("Pass custom properties to cell question", function (assert) {
JsonObject.metaData.addProperty("matrixdropdowncolumn", {
Expand All @@ -1557,3 +1543,44 @@ QUnit.test("Pass text as survey json", function (assert) {
assert.equal(q1.name, "q1", "The survey created from the string");
});

QUnit.test("surveyId + clientId", function (assert) {
var json = { "questions": [ {"type": "text", "name": "q1"}]};
class dxSurveyServiceTester extends dxSurveyService {
public getSurveyJsonAndIsCompleted(surveyId: string, clientId: string, onLoad: (success: boolean, surveyJson: any, result: string, response: any) => void) {
if(onLoad) {
onLoad(true, json, clientId, "");
}
};
}
class SurveyTester extends SurveyModel {
protected createSurveyService() : dxSurveyService {
return new dxSurveyServiceTester();
}
}
var survey = new SurveyTester({surveyId: "surveyDummyId", clientId: "no"});
assert.equal(survey.state, "running", "The survey is running");
var q1 = survey.getQuestionByName("q1");
assert.equal(q1.name, "q1", "The survey created from the string");

survey = new SurveyTester({surveyId: "surveyDummyId", clientId: "completed"});
assert.equal(survey.state, "completedbefore", "The survey was completed before");
var q1 = survey.getQuestionByName("q1");
assert.equal(q1.name, "q1", "The survey created from the string");
});


function twoPageSimplestSurvey() {
var survey = new SurveyModel();
var page = survey.addNewPage("Page 1");
page.addNewQuestion("text", "question1");
page.addNewQuestion("text", "question2");
page = survey.addNewPage("Page 2");
page.addNewQuestion("text", "question3");
page.addNewQuestion("text", "question4");
return survey;
}
function createPageWithQuestion(name: string) : PageModel {
var page = new PageModel(name);
page.addNewQuestion("text", "q1");
return page;
}

0 comments on commit cd50e77

Please sign in to comment.