-
Notifications
You must be signed in to change notification settings - Fork 3
/
simpleflowchart.jquery.js
156 lines (138 loc) · 4.98 KB
/
simpleflowchart.jquery.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*!
* jQuery simpleflowchart
* Author: @ahmadalfy
* Version: 1.2.0
* Licensed under the MIT license
*/
;(function ( $, window, document, undefined ) {
var pluginName = 'simpleflowchart',
defaults = {
data: [],
wrapperClass: 'chart-wrapper',
startClass: 'node__start',
informativeClass: 'node__informative',
nodeClass: 'node__question',
finishClass: 'node__finish',
startingPoint: 1,
animated: true,
scrollToNewNode: true,
scrollSpeed: 800,
easingSpeed: 300
};
function Plugin( element, options ) {
this.element = element;
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this._name = pluginName;
// Initialize the plugin only when if the data exist
if ($.isArray(this.options.data) && this.options.data.length > 0) {
this.init();
}
}
Plugin.prototype = {
init: function() {
this.createWrapper();
// if animation is set to false, set easingSpeed to 0 instead
this.options.easingSpeed = this.options.animated ? this.options.easingSpeed : 0;
this.createNode({ link: this.options.startingPoint });
},
createWrapper: function() {
this.$wrapper = $('<div class="' + this.options.wrapperClass + '" />');
// It's a good practice to include an alternative version
// for people with JavaScript disabled like an alternative
// static image or a link to the chart in a different format
$(this.element).html(this.$wrapper);
},
triggerCreateNode(ev) {
var data = ev.data;
var that = this;
var $laterNodes = data.$currentNode.closest('.node-wrapper').nextAll();
if($laterNodes.length > 0) {
// Wrapping all next nodes in a single div then animating and removing
// that div to avoid having multiple callbacks if we are animating and
// removing multiple elements.
$laterNodes.wrapAll('<div />').parent().fadeOut(this.options.easingSpeed, function() {
$(this).remove();
that.createNode(data);
});
} else {
this.createNode(data);
}
},
scrollToNode: function($node) {
$('html, body').animate({
scrollTop: $node.offset().top
}, this.options.scrollSpeed);
},
createNode: function(data) {
var node = this.options.data.find(function(node) {
return node.id === data.link;
});
if(node === undefined) {
throw new Error('Error, couldn\'t find a node with the id: ' + data.link);
}
var $node = $('<div class="node-wrapper" style="display: none" />');
this.addNodeClasses(node, $node);
var $nodeText = this.createNodeText(node);
$node.append($nodeText);
if ($.isArray(node.answers) && node.answers.length > 0) {
var $answers = this.createAnswers(node.answers);
$node.append($answers);
}
$node.appendTo(this.$wrapper).fadeIn(this.options.easingSpeed);
if(node.informative && node.link !== undefined) {
this.createNode({ link: node.link });
}
if(!node.informative && this.options.scrollToNewNode) {
this.scrollToNode($node);
}
},
addNodeClasses: function(nodeData, $el) {
if (nodeData['class'] !== undefined) {
$el.addClass(nodeData['class']);
} else if (!nodeData.informative && !nodeData.start && !nodeData.finish) {
$el.addClass(this.options.nodeClass);
}
if (nodeData.informative) {
$el.addClass(this.options.informativeClass);
}
if (nodeData.start) {
$el.addClass(this.options.startClass);
}
if (nodeData.finish) {
$el.addClass(this.options.finishClass);
}
},
createNodeText: function(data) {
return $nodeText = $('<div class="node">' + data.text + '</div>');
},
createAnswers: function(answers) {
var $answersWrapper = $('<ul class="node__answers" />');
var $answer = $('<li class="node__answer" />');
var answersCount = answers.length;
var that = this;
$.each(answers, function(idx, answer) {
var $thisAnswer = $answer.clone();
$thisAnswer.css('width', (100/answersCount) + '%');
if (answer['class'] !== undefined) {
$thisAnswer.addClass(answer['class']);
}
$answerAction = $('<button class="node__action" type="button" />');
$answerAction.bind('click', { link: answer.link, $currentNode: $answerAction }, that.triggerCreateNode.bind(that));
$answerAction.text(answer.text);
$answersWrapper.append($thisAnswer.append($answerAction));
});
return $answersWrapper;
}
};
// Lightweight wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName,
new Plugin( this, options ));
}
});
};
})( jQuery, window, document );