$('.follow.button')
.api({
@@ -316,13 +440,16 @@ type : 'UI Behavior'
return response.success || false;
}
onSuccess: function() {
- // valid response and action succeeded
+ // valid response and response.success = true
},
onFailure: function() {
- // valid response but action failed
+ // valid response but response.success = false
},
onError: function() {
// invalid response
+ },
+ onAbort: function() {
+ // user cancelled request
}
})
;
@@ -374,7 +501,9 @@ type : 'UI Behavior'
$('.follow.button')
- .api('setting', 'on', 'auto')
+ .api({
+ action: 'follow user'
+ })
.state({
text: {
inactive : 'Follow',
@@ -401,6 +530,7 @@ type : 'UI Behavior'
inactive |
Default state |
+ |
active |
@@ -494,35 +624,28 @@ type : 'UI Behavior'
stateContext |
- this (selector/DOM element) |
+ this |
UI state will be applied to this element, defaults to triggering element. |
defaultData |
true |
- Whether to include default data like {value} and {text} |
+ Whether to automatically include default data like {value} and {text} |
serializeForm |
- (true, false) |
+ false |
Whether to serialize closest form and include in request |
- throttle |
+ loadingDuration |
0 |
- If a request is pending, additional requests will be throttled by this duration in ms. (Setting above 0 will allow multiple simultaneous requests) |
+ Minimum duration to show loading indication |
- regExp |
-
-
- regExp : {
- required: /\{\$*[A-z0-9]+\}/g,
- optional: /\{\/\$*[A-z0-9]+\}/g,
- }
-
- |
- Regular expressions used for finding variables in templated urls |
+ errorDuration |
+ 2000 |
+ Duration in milliseconds to show error state after request error. |
@@ -574,20 +697,6 @@ type : 'UI Behavior'
POST/GET Data to Send with Request |
|
-
- filter |
-
-
- .disabled
-
- |
- Selector filter for elements that should not be triggerable |
-
-
- stateContext |
- this (selector/DOM element) |
- UI state will be applied to this element, defaults to triggering element. |
-
@@ -603,19 +712,39 @@ type : 'UI Behavior'
- onOpen |
- active content |
- Callback on element open |
+ beforeSend(settings) |
+ initialized element |
+ Allows modifying settings before request, or cancelling request |
+
+
+ beforeXHR(xhrObject) |
+ |
+ Allows modifying XHR object for request |
+
+
+ onSuccess(response, element) |
+ state context |
+ Callback on response object that passed successTest |
- onClose |
- active content |
- Callback on element close |
+ onFailure(response, element) |
+ state context |
+ Callback on response object that fails successTest |
- onChange |
- active content |
- Callback on element open or close |
+ onError(errorMessage, element) |
+ state context |
+ Callback on server error from returned status code, or XHR failure. |
+
+
+ onAbort(errorMessage, element) |
+ state context |
+ Callback on abort caused by user clicking a link or manually cancelling request |
+
+
+ onComplete(response, element) |
+ state context |
+ Callback on request complete regardless of conditions |
@@ -635,22 +764,32 @@ type : 'UI Behavior'
name |
- Accordion |
+ API |
Name used in log statements |
namespace |
- accordion |
+ api |
Event namespace. Makes sure module teardown does not effect other events attached to an element. |
+
+ regExp |
+
+
+ regExp : {
+ required: /\{\$*[A-z0-9]+\}/g,
+ optional: /\{\/\$*[A-z0-9]+\}/g,
+ }
+
+ |
+ Regular expressions used for template matching |
+
selector |
- selector : {
- accordion : '.accordion',
- title : '.title',
- content : '.content'
+ selector: {
+ form: 'form'
}
|
@@ -660,13 +799,27 @@ type : 'UI Behavior'
className |
- className : {
- active : 'active'
+ className: {
+ loading : 'loading',
+ error : 'error'
}
|
Class names used to determine element state |
+
+ metadata |
+
+
+ metadata: {
+ action : 'action',
+ request : 'request',
+ xhr : 'xhr'
+ }
+
+ |
+ Metadata used to store xhr and response promise |
+
debug |
false |
@@ -686,8 +839,21 @@ type : 'UI Behavior'
errors |
- error : {
- method : 'The method you called is not defined.'
+ // errors
+ error : {
+ beforeSend : 'The before send function has aborted the request',
+ error : 'There was an error with your request',
+ exitConditions : 'API Request Aborted. Exit conditions met',
+ JSONParse : 'JSON could not be parsed during error handling',
+ legacyParameters : 'You are using legacy API success callback names',
+ missingAction : 'API action used but no url was defined',
+ missingSerialize : 'Required dependency jquery-serialize-object missing, using basic serialize',
+ missingURL : 'No URL specified for api event',
+ noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
+ parseError : 'There was an error parsing your request',
+ requiredParameter : 'Missing a required URL parameter: ',
+ statusMessage : 'Server gave an error: ',
+ timeout : 'Your request timed out'
}
|
diff --git a/server/files/javascript/api.js b/server/files/javascript/api.js
index 847d12e5c..8ee73c851 100755
--- a/server/files/javascript/api.js
+++ b/server/files/javascript/api.js
@@ -1,9 +1,10 @@
-/* Define API endpoints once globally */
$.fn.api.settings.debug = true;
+
/* Define API endpoints once globally */
$.fn.api.settings.api = {
'get followers' : '/followers/{id}?results={count}',
+ 'create user' : '/create',
'follow user' : '/follow/{id}',
'search' : '/search/?query={value}'
};
@@ -31,6 +32,11 @@ semantic.api.ready = function() {
server
.respondWith(/\/search\/(.*)/, [responseCode, headers, body])
;
+
+ $('form .ui.dropdown')
+ .dropdown()
+ ;
+
};
diff --git a/server/files/javascript/library/serialize-object.js b/server/files/javascript/library/serialize-object.js
new file mode 100644
index 000000000..c8b36c41b
--- /dev/null
+++ b/server/files/javascript/library/serialize-object.js
@@ -0,0 +1,152 @@
+/**
+ * jQuery serializeObject
+ * @copyright 2014, macek
+ * @link https://github.com/macek/jquery-serialize-object
+ * @license BSD
+ * @version 2.4.3
+ */
+(function(root, factory) {
+
+ // AMD
+ if (typeof define === "function" && define.amd) {
+ define(["exports", "jquery"], function(exports, $) {
+ return factory(exports, $);
+ });
+ }
+
+ // CommonJS
+ else if (typeof exports !== "undefined") {
+ var $ = require("jquery");
+ factory(exports, $);
+ }
+
+ // Browser
+ else {
+ factory(root, (root.jQuery || root.Zepto || root.ender || root.$));
+ }
+
+}(this, function(exports, $) {
+
+ var patterns = {
+ validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i,
+ key: /[a-z0-9_]+|(?=\[\])/gi,
+ push: /^$/,
+ fixed: /^\d+$/,
+ named: /^[a-z0-9_]+$/i
+ };
+
+ function FormSerializer(helper, $form) {
+
+ // private variables
+ var data = {},
+ pushes = {};
+
+ // private API
+ function build(base, key, value) {
+ base[key] = value;
+ return base;
+ }
+
+ function makeObject(root, value) {
+
+ var keys = root.match(patterns.key), k;
+
+ // nest, nest, ..., nest
+ while ((k = keys.pop()) !== undefined) {
+ // foo[]
+ if (patterns.push.test(k)) {
+ var idx = incrementPush(root.replace(/\[\]$/, ''));
+ value = build([], idx, value);
+ }
+
+ // foo[n]
+ else if (patterns.fixed.test(k)) {
+ value = build([], k, value);
+ }
+
+ // foo; foo[bar]
+ else if (patterns.named.test(k)) {
+ value = build({}, k, value);
+ }
+ }
+
+ return value;
+ }
+
+ function incrementPush(key) {
+ if (pushes[key] === undefined) {
+ pushes[key] = 0;
+ }
+ return pushes[key]++;
+ }
+
+ function encode(pair) {
+ switch ($('[name="' + pair.name + '"]', $form).attr("type")) {
+ case "checkbox":
+ return pair.value === "on" ? true : pair.value;
+ default:
+ return pair.value;
+ }
+ }
+
+ function addPair(pair) {
+ if (!patterns.validate.test(pair.name)) return this;
+ var obj = makeObject(pair.name, encode(pair));
+ data = helper.extend(true, data, obj);
+ return this;
+ }
+
+ function addPairs(pairs) {
+ if (!helper.isArray(pairs)) {
+ throw new Error("formSerializer.addPairs expects an Array");
+ }
+ for (var i=0, len=pairs.length; i 1) {
+ return new Error("jquery-serialize-object can only serialize one form at a time");
+ }
+ return new FormSerializer($, this).
+ addPairs(this.serializeArray()).
+ serialize();
+ };
+
+ FormSerializer.serializeJSON = function serializeJSON() {
+ if (this.length > 1) {
+ return new Error("jquery-serialize-object can only serialize one form at a time");
+ }
+ return new FormSerializer($, this).
+ addPairs(this.serializeArray()).
+ serializeJSON();
+ };
+
+ if (typeof $.fn !== "undefined") {
+ $.fn.serializeObject = FormSerializer.serializeObject;
+ $.fn.serializeJSON = FormSerializer.serializeJSON;
+ }
+
+ exports.FormSerializer = FormSerializer;
+
+ return FormSerializer;
+}));
\ No newline at end of file
diff --git a/server/files/stylesheets/semantic.css b/server/files/stylesheets/semantic.css
index ce1f93bc3..91db41ddf 100755
--- a/server/files/stylesheets/semantic.css
+++ b/server/files/stylesheets/semantic.css
@@ -103,15 +103,13 @@ pre.console {
}
code {
background-color: rgba(0, 0, 0, 0.02);
- border-radius: 0.2em;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
- color: rgba(0, 0, 0, 0.75);
- font-weight: bold;
display: inline-block;
font-family: "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;
- font-size: 14px;
- margin: 0;
- padding: 0.1em 0.4em;
+ font-size: 12px;
+ font-weight: bold;
+ margin: 0 2px 0px 0px;
+ padding: 2px 4px;
vertical-align: baseline;
}
.ui.message code {
@@ -122,12 +120,6 @@ pre code {
border: none;
padding: 0px;
}
-table pre,
-table code {
- margin: 0px !important;
- padding: 0px;
- background-color: transparent;
-}
p {
margin: 1em 0em;
}
@@ -724,9 +716,12 @@ body#example.hide {
position: relative;
margin: 5rem 0rem 3rem;
}
+#example .main.container .examples > .rail + h2,
+#example .main.container > .rail + h2,
+#example .main.container > .tab > .rail + h2,
#example .main.container .examples > h2:first-child,
#example .main.container > h2:first-child,
-#example .main.container > .tab > h2:first-child{
+#example .main.container > .tab > h2:first-child {
margin-top: 0em;
}
#example .main.container .examples > h2 + p,