The ic-always-update attribute forces an element to always update the DOM when new content
16 | is downloaded, even if the current content is identical to the downloaded content.
17 |
18 |
This can be useful if you want to clean non-DOM related state (such as checkboxes) after an operation causes
19 | an update.
20 |
21 |
Syntax
22 |
23 |
The value of this attribute can be either true or false
Any content that is returned will be used to replace the content of the current element (or, more commonly, another
2 | element, via the ic-target attribute, see below). An empty
3 | response will be interpreted as a No-Op. See Intercooler Responses for
4 | more info.
5 |
6 |
Since it is common for an action to replace a different element than the one that the action occured
7 | on, you may want to use the ic-target attribute to target
8 | a different element for replacement.
9 |
10 |
What is the Default Action?
11 |
12 |
The default action depends on the type of an HTML element:
The ic-verb attribute tells Intercooler to use a different HTTP verb when issuing
16 | a request than it would otherwise.
17 |
18 |
This can be useful in cases where, for example, you want to reuse a form for both editing and
19 | creating new models, and need to select the appropriate verb.
20 |
21 |
Syntax
22 |
23 |
The value of the ic-verb attribute should be one of:
24 |
25 |
26 |
GET
27 |
POST
28 |
PUT
29 |
DELETE
30 |
31 |
32 |
Dependencies
33 |
34 |
ic-verb attribute has no effect on dependencies.
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/www/js/google-code-prettify/lang-ml.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xa0]+(?:[$_a-z][\w']*|``[^\t\n\r`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])(?:'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\(\*[\S\s]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
2 | ["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^(?:[_a-z][\w']*[!#?]?|``[^\t\n\r`]*(?:``|$))/i],["pun",/^[^\w\t\n\r "'\xa0]+/]]),["fs","ml"]);
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2010-2012 Google, Inc. http://intercoolerjs.org
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/www/release/upgrade-steps-0.3.0.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | nav: dependencies
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
Intercooler 0.2.0 → 0.3.x Upgrade Guide
11 |
12 |
Fresh on the heels of saying that we were adopting Semantic Versioning in 0.2.0, we
13 | promptly violated Semantic Versioning.
14 |
15 |
Last time, promise! ☺
16 |
17 |
Upgrade Steps
18 |
19 |
Here are steps to upgrade from Intercooler 0.2.0 to 0.3.0:
20 |
21 |
22 |
Rename the ic-load-on attribute to ic-trigger-on.
23 |
All intercooler events that were previously named ic.* should be reversed to *.ic - this
24 | is more consistent with jQuery event name spacing.
25 |
All logging related methods, setLogger, log, setLogLevel and
26 | logLevels were removed from the API and should be replaced by jQuery event listeners for the
27 | log.ic event.
28 |
29 |
30 |
Not too bad, but still, sorry about that!
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/www/js/google-code-prettify/lang-n.js:
--------------------------------------------------------------------------------
1 | var a=null;
2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/,
3 | a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/,
4 | a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]);
5 |
--------------------------------------------------------------------------------
/www/js/google-code-prettify/lang-vhdl.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"]],[["str",/^(?:[box]?"(?:[^"]|"")*"|'.')/i],["com",/^--[^\n\r]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i,
2 | null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^'(?:active|ascending|base|delayed|driving|driving_value|event|high|image|instance_name|last_active|last_event|last_value|left|leftof|length|low|path_name|pos|pred|quiet|range|reverse_range|right|rightof|simple_name|stable|succ|transaction|val|value)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w.\\]+#(?:[+-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:e[+-]?\d+(?:_\d+)*)?)/i],
3 | ["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'\xa0-]*/]]),["vhdl","vhd"]);
4 |
--------------------------------------------------------------------------------
/www/js/google-code-prettify/lang-clj.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2011 Google Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | var a=null;
17 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a],
18 | ["typ",/^:[\dA-Za-z-]+/]]),["clj"]);
19 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 |
3 | // Project configuration.
4 | grunt.initConfig({
5 | pkg: grunt.file.readJSON('package.json'),
6 | uglify: {
7 | options: {
8 | banner: '/*! <%= pkg.name %> <%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
9 | },
10 | build: {
11 | src: 'src/intercooler.js',
12 | dest: 'www/release/intercooler-<%= pkg.version %>.min.js'
13 | }
14 | },
15 | "regex-replace": {
16 | "update-test-ref": { //specify a target with any name
17 | src: ['www/release/unit-tests-<%= pkg.version %>.html'],
18 | actions: [
19 | {
20 | name: 'lib ref',
21 | search: "../src/intercooler.js",
22 | replace: './intercooler-<%= pkg.version %>.js',
23 | flags: 'g'
24 | }
25 | ]
26 | }
27 | }
28 | });
29 |
30 | // Load the plugin that provides the "uglify" task.
31 | grunt.loadNpmTasks('grunt-contrib-uglify');
32 | grunt.loadNpmTasks('grunt-regex-replace');
33 |
34 | grunt.registerTask('release', "Releases a new version of the library", function () {
35 | grunt.file.copy("src/intercooler.js", 'www/release/intercooler-' + grunt.config.get('pkg').version + '.js');
36 | grunt.file.copy("test/unit_tests.html", 'www/release/unit-tests-' + grunt.config.get('pkg').version + '.html');
37 | grunt.task.run('uglify');
38 | grunt.task.run('regex-replace');
39 | });
40 |
41 | // Default task(s).
42 | grunt.registerTask('default', ['release']);
43 |
44 | };
45 |
--------------------------------------------------------------------------------
/www/attributes/ic-confirm.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | nav: attributes > ic-confirm
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
11 |
ic-confirm - The Confirm Attribute
12 |
13 |
Summary
14 |
15 |
The ic-confirm attribute tells Intercooler to confirm the action with the user using the
16 | string of the attribute and the javascript confirm() function.
17 |
18 |
This can be useful when you want to confirm destructive operations, such as a delete.
19 |
20 |
Syntax
21 |
22 |
The value of the ic-verb attribute should be a string asking the user to confirm the given action.
23 |
24 |
Dependencies
25 |
26 |
The ic-confirm attribute has no effect on dependencies.
27 |
28 |
Example
29 |
30 |
31 | <button ic-post-to="/target_url" ic-confirm="Are you sure?">Click Me!</button>
32 |
This tutorial will show you how to implement bulk operations on a table using IntercoolerJS.
14 |
15 |
Video
16 |
17 |
18 |
19 |
20 |
21 |
Outline
22 |
23 |
Here are the steps for implementing bulk operations
24 |
25 |
26 |
27 | Extract a partial of the table and wrap it in a form that uses the ic-src attribute to
28 | re-render the table. Give the form a useful ID.
29 |
30 |
31 | Add bulk operation buttons that post to the same URL that the table sources from using the
32 | ic-post-to attribute, and include the
33 | checked rows by using the ic-post-to.
34 |
35 |
36 |
37 |
Git Diff
38 |
39 |
Here is a diff showing what's necessary to implement the bulk operations:
This tutorial will show you how to implement infinite scroll with only a few lines of IntercoolerJS.
14 |
15 |
Video
16 |
17 |
18 |
19 |
20 |
21 |
Outline
22 |
23 |
Here are the steps for implementing infinite scroll
24 |
25 |
26 |
27 | Extract a partial of the row rendering for your table, and add an id to the enclosing tbody so
28 | we can target it for appending.
29 |
30 |
31 | Add an empty span to the last element in the table that uses the
32 | ic-append-from,
33 | ic-target, and
34 | ic-trigger-on
35 | attributes to trigger appending to the table body.
36 |
37 |
38 |
39 |
Git Diff
40 |
41 |
Here is a diff between the will-paginate code and Intercooler code:
27 | The big enhancement in this release (small code change, but big functionality boost!) is the X-IC-Trigger
28 | response header, which finally solves a tricky problem I've been wrestling with: How do you communicate server side state
29 | changes that have client-side UI ramifications that fall outside the usual Intercooler request-and-replace
30 | partial view flow?
31 |
32 |
33 |
This new mechanism allows you to cleanly separate your server side and client-side logic even in cases where the
34 | simple content-swapping approach isn't enough.
35 |
36 |
A great example is if you want to hide a modal if and only if a form in the modal submits valid data to the
37 | server. You can now easily fire an server.accountCreated event (as an example) from the server side
38 | and respond to that on the client side by hiding the modal. Clean, crisp and very little code!
This tutorial will show you how to implement inline server-side field validation in Rails with only a few lines
14 | of IntercoolerJS.
15 |
16 |
Video
17 |
18 |
19 |
20 |
21 |
22 |
Outline
23 |
24 |
Here are the steps for implementing inline validation
25 |
26 |
27 |
28 | Extract a partial of the input div, and wrap it with a new div with an ID so
29 | we can target it for appending.
30 |
31 |
32 | Create an route that will render the partial input and implement non-updating validation
33 | in the controller.
34 |
35 |
36 | Add the ic-post-to annotation to the input and target the wrapping div with an
37 | ic-target annotation. To make the transition look right, use the ic-transition
38 | attribute with the value "none".
39 |
40 |
41 |
42 |
Git Diff
43 |
44 |
Here's a diff between the standard rails form code and the IntercoolerJS inline validation version:
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Intercooler.js
2 |
3 | ## What it is
4 |
5 | Intercooler is a [PVC](http://intercoolerjs.org/why.html) framework that allows
6 | you to add AJAX to your application with declarative HTML5-style bindings and
7 | REST-ful URLs, giving web applications a richer UX with a minimum of code.
8 |
9 | ## What that means
10 |
11 | It makes AJAX simple, you don't even need to write any JavaScript! Here's an
12 | example of a basic `POST` request:
13 |
14 | // When this is clicked, a post request is sent to /example
15 |
18 |
19 | // When a post request is sent to /example, the response goes here
20 |
21 |
22 | ## How to use
23 |
24 | Intercooler depends on JQuery and can be installed like this:
25 |
26 |
27 |
28 |
29 | Or you can [download the latest
30 | version](http://intercoolerjs.org/download.html) and embed it locally.
31 |
32 | ## More examples
33 |
34 | ### Polling
35 |
36 | Send a `GET` request to "/visitors/count" every two seconds and update the
37 | innerHTML to the response:
38 |
39 |
40 | There are currently 42 users online.
41 |
42 |
43 | ### Adding input
44 |
45 | This AJAX includes the value of `#password` in it's request.
46 |
47 | Enter a password:
48 |
49 |
52 |
53 |
The ic-delete-from attribute binds the default action (see below) of HTML element to a
16 | DELETE to the given URL. For example, on a button, when the button is clicked, an
17 | AJAX DELETE will be issued to the given URL.
The value of the attribute should be a valid relative path (e.g. ic-delete-from="/foo/bar").
24 |
25 |
Dependencies
26 |
27 |
ic-delete-from implies a dependency on its path, and Intercooler will issue requests for elements
28 | whenever it detects an action that the path depends on. See Dependencies for
29 | more information.
30 |
31 |
Example
32 |
33 |
Here is a simple example, with a span that depends on the updated URL:
The ic-put-to attribute binds the default action (see below) of HTML element to a
16 | PUT to the given URL. For example, on a button, when the button is clicked, an
17 | AJAX PUT will be issued to the given URL.
The value of the attribute should be a valid relative path (e.g. ic-put-to="/foo/bar").
24 |
25 |
Dependencies
26 |
27 |
ic-put-to implies a dependency on its path, and Intercooler will issue requests for elements
28 | whenever it detects an action that the path depends on. See Dependencies for
29 | more information.
30 |
31 |
Example
32 |
33 |
Here is a simple example, with a span that depends on the updated URL:
The ic-include attribute tells Intercooler to include additional parameters in a request that
16 | it makes to the server, allowing you to pass up additional UI information to the server..
17 |
18 |
Syntax
19 |
20 |
The value of the ic-include attribute is a CSS/JQuery element selector.
21 |
22 |
Dependencies
23 |
24 |
ic-include has no effect on dependencies.
25 |
26 |
Example
27 |
28 |
In this example, the button includes the value of the input when it POSTs to the server.
29 |
30 |
31 | <div ic-src="/update">Please Enter A Name...</div>
32 | <input id="name" name="name"/>
33 | <button ic-post-to="/update" ic-include="#name">Upload Name</button>
34 |
35 |
36 |
Note that the response to the button click is the content to swap in for the div, not the button.
The ic-post-to attribute binds the default action (see below) of HTML element to a
16 | POST to the given URL. For example, on a button, when the button is clicked, an
17 | AJAX POST will be issued to the given URL.
The value of the attribute should be a valid relative path (e.g. ic-post-to="/foo/bar").
24 |
25 |
Dependencies
26 |
27 |
ic-post-to implies a dependency on its path, and Intercooler will issue requests for elements
28 | whenever it detects an action that the path depends on. See Dependencies for
29 | more information.
30 |
31 |
Example
32 |
33 |
Here is a simple example, with a span that depends on the updated URL:
The ic-poll attribute tells Intercooler to poll the URL given by a ic-src
16 | attribute on a given interval, updating the element if it has changed.
17 |
18 |
Note that Intercooler will not replace the element unless its SHA256 fingerprint has changed, to prevent
19 | blinky-blink UIs.
20 |
21 |
Also, you may find the ic-transition attribute useful
22 | if you wish to change how the result is swapped in.
23 |
24 |
Syntax
25 |
26 |
The value of the attribute should a valid integer, followed by the string "s" (for seconds) or "ms" (for
27 | milliseconds). (e.g. ic-poll="100ms" indicates that the server should be polled every 100 milliseconds.)
28 |
29 |
Dependencies
30 |
31 |
ic-poll has no dependency implications.
32 |
33 |
Example
34 |
35 |
Here is a simple example of a poll interval:
36 |
37 |
38 | <div ic-src="/seconds" ic-poll="2s">You have been on this page for 0 seconds...</div>
39 |
The primary advantage of Intercooler is simplicity.
14 |
15 |
Using simple, declarative attributes you can build rich, interactive user
16 | interfaces in your application while avoiding the overhead (and sometimes, overkill) of
17 | MVC frameworks.
18 |
19 |
With intercooler.js, you don't need client-side models, routing, validation, rendering, factories,
20 | dependency injection, etc, eliminating a major source of complexity, inconsistency and
21 | security problems in your application.
22 |
23 |
How Does Intercooler Work?
24 |
25 |
Intercooler is a Partial View Controller framework: it communicates with the
26 | server via AJAX, but rather than using JSON responses, it uses fragments of HTML (i.e. Partial Views),
27 | which are then loaded into the DOM directly.
28 |
29 |
This is in contrast with older, more traditional MVC frameworks such as
30 | Ember.js or Angular.js, which use
31 | JSON and client-side rendering.
32 |
33 |
Here is a diagram showing a PVC request:
34 |
35 |
36 |
37 |
38 |
39 |
The AJAX response content is a partial bit of HTML, and it is swapped into the DOM directly.
40 |
41 |
Examples of some PVC frameworks are Turbolinks and
42 | pjax.
43 |
44 |
Intercooler formalizes this pattern using simple, declarative attributes, making PVC-style programing
45 | easy, flexible and fun.
The ic-get-from attribute binds the default action (see below) of HTML element to a
16 | GET to the given URL. For example, on a button, when the button is clicked, an
17 | AJAX GET will be issued to the given URL.
The value of the attribute should be a valid relative path (e.g. ic-get-from="/foo/bar").
24 |
25 |
Dependencies
26 |
27 |
ic-get-from implies a dependency on its path, and Intercooler will issue requests for elements
28 | whenever it detects an action that the path depends on. See Dependencies for
29 | more information.
30 |
31 |
Example
32 |
33 |
Here is a simple example, with a span that depends on the updated URL:
The ic-style-src attribute binds a given HTML element's style attribute to a URL. It does not cause any
16 | requests to happen by itself, but it can respond to events caused by other attributes.
17 |
18 |
When Intercooler issues a request for an element with an ic-style-src, it will issue a GET
19 | and will replace the current element's style value with resulting text fragment.
20 |
21 |
Syntax
22 |
23 |
The value of the attribute should be a valid style attribute name, followed by a colon, then a valid relative
24 | path
25 | (e.g. ic-style-src="color:/foo/bar").
26 |
27 |
Dependencies
28 |
29 |
ic-style-src implies a mutation to any dependency on its path, and Intercooler will issue
30 | GET requests for elements that depend on that path after the POST completes.
This tutorial will show you how to implement "Click To Load" behavior with only a few lines of IntercoolerJS.
14 | It builds on the previous Infinite Scroll tutorial.
15 |
16 |
Video
17 |
18 |
19 |
20 |
21 |
22 |
Outline
23 |
24 |
Here are the steps for implementing inifinite scroll
25 |
26 |
27 |
28 | Extract a partial of the row rendering for your table, and add an id to the enclosing tbody so
29 | we can target it for appending.
30 |
31 |
32 | Add a hidden input to the last row of the table that is rendered, with the name page and
33 | value of the next page to load
34 |
35 |
36 | Add a button after the table that uses the
37 | ic-append-from,
38 | ic-target, and
39 | ic-trigger-on
40 | attributes to trigger appending to the table body, and that includes the hidden input using the
41 | ic-include tag to include the last hidden
42 | input in the table.
43 |
44 |
45 |
46 |
Git Diff
47 |
48 |
Here is a diff between infinite scroll and click-to-load:
The ic-deps attribute tells Intercooler that an element depends on a given path and should be
16 | updated if a change to that path is detected.
17 |
18 |
Syntax
19 |
20 |
The value of the ic-deps attribute is a comma-separated list of paths that the element depends on.
21 | Note that the special single character "*" indicates that an element depends on all detected
22 | changed.
23 |
24 |
Dependencies
25 |
26 |
ic-deps adds the dependencies it specifies to the element it is on.
27 |
28 |
Example
29 |
30 |
Here is a simple element that depends on any changes:
The ic-attr-src attribute binds a given HTML element's attribute to a URL. It does not cause any
16 | requests to happen by itself, but it can respond to events caused by other attributes.
17 |
18 |
When Intercooler issues a request for an element with an ic-attr-src, it will issue a GET
19 | and will replace the current element attribute value with resulting text fragment.
20 |
21 |
Syntax
22 |
23 |
The value of the attribute should be a valid attribute name, followed by a colon, then a valid relative
24 | path
25 | (e.g. ic-attr-src="style:/foo/bar").
26 |
27 |
Dependencies
28 |
29 |
ic-attr-src implies a dependency on its path, and Intercooler will issue requests for elements
30 | whenever it detects an action that the path depends on. See Dependencies for
31 | more information.
32 |
33 |
Example
34 |
35 |
Here is a simple example, using a poll interval to update:
36 |
37 |
38 | <div ic-style-src="style:/style" ic-poll="1s">Cause you move to a different sound</div>
39 |
The ic-src attribute binds a given HTML element to a URL. It does not cause any requests to happen
16 | by itself, but it can respond to events caused by other attributes, such as
17 | ic-poll or
18 | ic-post-to.
19 |
20 |
When Intercooler issues a request for an element with an ic-src, it will issue a GET
21 | and will replace the current elements content with resulting HTML fragment, if it is different than the
22 | current content.
23 |
24 |
Syntax
25 |
26 |
The value of the attribute should be a valid relative path (e.g. ic-src="/foo/bar").
27 |
28 |
The value of the attribute may also include a fragment identifier (e.g. ic-src="/foo#bar").
29 | In this case, everything on the page except the element whose ID matches the fragment identifier is ignored.
30 |
31 |
Dependencies
32 |
33 |
ic-src implies a dependency on its path, and Intercooler will issue requests for elements
34 | whenever it detects an action that the path depends on. See Dependencies for
35 | more information.
36 |
37 |
Example
38 |
39 |
Here is a simple example, using a poll interval to update:
40 |
41 |
42 | <div ic-src="/seconds" ic-poll="5s">You have been on this page for 0 seconds...</div>
43 |
The ic-append-from attribute binds a given HTML element's children to a URL. It does not
16 | cause any requests to happen by itself, but it can respond to events caused by other attributes.
17 |
18 |
When Intercooler issues a request for an element with an ic-append-from, it will issue a
19 | GET
20 | and will append the resulting HTML fragment as children of the current element. If you wish to limit the total
21 | number of children on of an element, you can use the ic-limit-children
23 | attribute.
24 |
25 |
Note that with these attributes, you will often want to take advantage of the ic-last-refresh parameter
26 | that Intercooler includes in its requests. See Requests & Responses for more information.
27 |
28 |
Syntax
29 |
30 |
The value of the attribute should be a valid relative path (e.g. ic-append-from="/foo/bar").
31 |
32 |
Dependencies
33 |
34 |
ic-append-from implies a dependency on its path, and Intercooler will issue requests for elements
35 | whenever it detects an action that the path depends on. See Dependencies for
36 | more information.
37 |
38 |
39 |
Example
40 |
41 |
Here is a simple example, using a poll interval to update:
The ic-prepend-from attribute binds a given HTML element's children to a URL. It does not
16 | cause any requests to happen by itself, but it can respond to events caused by other attributes.
17 |
18 |
When Intercooler issues a request for an element with an ic-prepend-from, it will issue a
19 | GET
20 | and will prepend the resulting HTML fragment as children of the current element. If you wish to limit the total
21 | number of children on of an element, you can use the ic-limit-children
23 | attribute.
24 |
25 |
Note that with these attributes, you will often want to take advantage of the ic-last-refresh parameter
26 | that Intercooler includes in its requests. See Requests & Responses for more information.
27 |
28 |
Syntax
29 |
30 |
The value of the attribute should be a valid relative path (e.g. ic-prepend-from="/foo/bar").
31 |
32 |
Dependencies
33 |
34 |
ic-prepend-from implies a dependency on its path, and Intercooler will issue requests for elements
35 | whenever it detects an action that the path depends on. See Dependencies for
36 | more information.
37 |
38 |
39 |
Example
40 |
41 |
Here is a simple example, using a poll interval to update:
One of the novel features of Intercooler is its dependency framework. This is how Intercooler figures out
13 | what elements to refresh and when, based on user input, poll intervals, etc.
14 |
15 |
The core concept in Intercooler is to use server paths to encode dependencies. The idea is fairly
16 | straight forward, given a REST-ful understanding of web addressses:
17 |
18 |
If an element reads its value (i.e. issues a GET) from a given server path, and
19 | an action updates that path (i.e. issues a POST to it), then we should refresh the
20 | element after the action occurs.
21 |
22 |
So, as a simple example, consider this button and div:
Here the div depends on the button, because they share a path with one another. When
32 | Intercooler issues a POST to the given path (on a user click), upon completion,
33 | it will issue a GET to the same path, and replace the div with the new content, if it
34 | is different.
35 |
36 |
37 |
What Paths Depend On What?
38 |
39 |
It's all very simple when the POST and GET are to the same path, but what if
40 | they aren't? What if the post is to /jobs/2341/start and the get is from /jobs/2341?
41 | Or vice-versa?
42 |
43 |
Our answer is as follows:
44 |
45 |
Two server paths express a dependency if either path is the starting path of the other.
46 |
47 |
So:
48 |
49 |
50 |
51 |
52 |
Path Updated
53 |
Path Read
54 |
Dependency?
55 |
56 |
57 |
58 |
59 |
/foo
60 |
/bar
61 |
NO
62 |
63 |
64 |
/foo
65 |
/foo
66 |
YES
67 |
68 |
69 |
/foo/bar
70 |
/foo
71 |
YES
72 |
73 |
74 |
/foo
75 |
/foo/bar
76 |
YES
77 |
78 |
79 |
/foo
80 |
/foo#bar
81 |
YES
82 |
83 |
84 |
/foo/doh
85 |
/foo/bar
86 |
NO
87 |
88 |
89 |
/foo#doh
90 |
/foo#bar
91 |
NO
92 |
93 |
94 |
95 |
96 |
Explicit Dependencies
97 |
98 |
The dependencies above are managed implicitly by Intercooler and, with reasonable layout of your restful
99 | URLs, should handle many cases. However, there are inevitably going to be times when you need to
100 | express dependencies explicitly. In Intercooler, you can use the
101 | ic-deps attribute to express additional paths that an
102 | element depends on.
The ic-target attribute tells Intercooler the response from a request should be used to replace
16 | a different element than the current one. This is commonly used with action attributes, for example to make
17 | a button replace a div in the UI.
18 |
19 |
Syntax
20 |
21 |
The value of the ic-target attribute should be a valid CSS/JQuery selector.
22 |
23 |
Dependencies
24 |
25 |
ic-target has no effect on dependencies..
26 |
27 |
Button Example
28 |
29 |
Here is a simple button that updates a div on click:
Note that the response to the button click is the content to swap in for the div, not the button.
37 |
38 |
39 |
51 |
0 Clicks
52 |
53 |
54 |
55 |
Input Example
56 |
57 |
Here is an example of an input that posts its input to the server to validate it, replacing the
58 | enclosing div (using standard Boostrap error classes.)
16 | Add AJAX to your web application using simple, declarative HTML attributes.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | Intercooler v0.4.1 has been released! Join our newsgroup to stay up to date.
53 |
54 |
55 | <-- This button posts to the /example/click
56 | URL when it is clicked -->
57 | <button ic-post-to="/example/click">
58 | Click Me!
59 | </button>
60 |
61 | <-- This span is bound to a URL that returns an updated
62 | version of the span when the button is clicked -->
63 | <span ic-src="/example/click">
64 | You have not yet clicked the button
65 | </span>
66 |
67 |
68 |
69 |
70 |
88 |
89 | You have not yet clicked the button
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
Declarative
103 |
104 |
With Intercooler you can use easy to understand, declarative attributes to bind your HTML elements to
105 | AJAX end points.
106 |
107 |
Intercooler is a pragmatic library, however, so you can drop into javascript when it's necessary.
108 |
109 |
110 |
111 |
Incremental
112 |
113 |
You can use Intercooler for as much or as little of your application as you like.
114 |
115 |
No need to wholesale adopt a new framework to start adding AJAX functionality to your application!
116 |
117 |
118 |
119 |
Plays Well With Others
120 |
121 |
Intercooler is a little library built to play well with other web technologies, like AngularJS, EmberJS and Turbolinks.
122 |
123 |
Use the right tool for the particular job: Intercooler won't get in the way.
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
Dependency Detection
134 |
135 |
Intercooler uses pattern matching in your URLs to detect and refresh dependencies between HTML
136 | elements. Typically it will do the right thing without much work on your part. And, if you need
137 | to add or ignore dependencies, Intercooler allows you to do that as well.
138 |
139 |
140 |
141 |
142 |
Framework Agnostic
143 |
144 |
Although it was inspired by Partials
145 | in Rails, IntercoolerJS works equally well with any back end platform.
146 |
147 |
IntercoolerJS works great with any HTML/CSS framework, but was designed with Bootstrap
148 | in mind, making it easy to create dynamic UIs using the standard, simple Bootstrap techniques.
149 |
150 |
151 |
152 |
153 |
Open
154 |
155 |
IntercoolerJS was designed to be open and extensible so, when push comes to shove, you can customise
156 | pretty much any part of the it you need to.
Intercooler has a few different extension points. You can call a few direct methods on the global
12 | Intercooler object, and you can also listen for intercooler related events.
If the argument is an element, it will issue a new AJAX request. If it is a string path, it will issue
86 | a request for all dependent elements.
87 |
88 |
89 |
90 |
91 |
92 |
Events
93 |
94 |
Intercooler fires the following events on elements:
95 |
96 |
97 |
98 |
99 |
Event
100 |
Description
101 |
102 |
103 |
104 |
105 |
106 | log.ic(evt, msg, level, elt)
107 |
108 |
109 | Event fired when log messages occur internally in intercooler (can be used to debug specific
110 | DOM elements.)
111 |
112 |
113 |
114 |
115 | beforeHeaders.ic(evt, elt, xhr)
116 |
117 |
118 | Triggered before intercooler headers are processed.
119 |
120 |
121 |
122 |
123 | afterHeaders.ic(evt, elt, xhr)
124 |
125 |
126 | Triggered after intercooler headers are processed.
127 |
128 |
129 |
130 |
131 | beforeSend.ic(evt, elt, data)
132 |
133 |
134 | Triggered before sending an intercooler AJAX request to the server. The second argument to the event is
135 | the data hash, and can be added or removed from to change the values sent to the server.
136 |
This attribute allows you to bind an element to a given URL. Once it is bound, when a change occurs that
28 | Intercooler recognizes as affecting the URL (or given an event such as a poll), Intercooler will issue
29 | a GET to the URL and replace the element with the new content, if it is different.
30 |
Like ic-src, this attribute allows you bind to a URL. However, this attribute binds a
35 | style attribute to a URL. The syntax is "style-attribute:url". For
36 | example,
37 | to bind the color of an element to "/color/random", you would say
38 | ic-style-src="color:/color/random"
Like ic-style-src, this attribute allows you bind to a URL. However, this attribute binds
43 | an attribute value to a URL. The syntax is "attribute:url". For
44 | example,
45 | to bind the style of an element to "/style/random", you would say
46 | ic-attr-src="style:/style/random"
This attribute allows you to bind the "action" of an element to a given URL. Once it is bound, when an
69 | "action" occurs (e.g. clicking a button) Intercooler will issue
70 | a GET to the URL and replace the element with the new content, if it is different.
71 | Intercooler will detect any other elements that the GET effects and automatically refresh them.
72 |
This attribute allows you to bind the "action" of an element to a given URL. Once it is bound, when an
78 | "action" occurs (e.g. clicking a button) Intercooler will issue
79 | a POST to the URL and replace the element with the new content, if it is different.
80 | Intercooler will detect any other elements that the POST effects and automatically refresh them.
81 |
This attribute allows you to bind the "action" of an element to a given URL. Once it is bound, when an
87 | "action" occurs (e.g. clicking a button) Intercooler will issue
88 | a PUT to the URL and replace the element with the new content, if it is different.
89 | Intercooler will detect any other elements that the PUT effects and automatically refresh them.
90 |
This attribute allows you to bind the "action" of an element to a given URL. Once it is bound, when an
96 | "action" occurs (e.g. clicking a button) Intercooler will issue
97 | a DELETE to the URL and replace the element with the new content, if it is different.
98 | Intercooler will detect any other elements that the DELETE effects and automatically refresh them.
99 |
A selector attribute that can be used to include additional input with an action request (e.g. can be
116 | used to include a form with an unrelated button.)
This attribute tells Intercooler to poll the source URL for the element it is on in a given interval,
132 | expressed as milliseconds or seconds. (e.g. '500ms' or '2s')
This attributes changes the event on which the element is loaded via ic-src. It can be
138 | used to implement lazy loading of images or charts, infinite scrolling, etc.
This attribute allows force an element to always update the DOM with content after an intercooler
155 | request, even if the content is identical to the current DOM content.
Intercooler makes AJAX requests to various paths when certain events occur (e.g. A button with a
13 | ic-post-to attribute is clicked, or a polling interval occurs.) and expects a response
14 | of a certain format (typically an HTML fragment). Below we describe both the request and response formats.
15 |
16 |
Intercooler Requests
17 |
18 |
19 | Intercooler requests can come take four different forms:
20 |
21 |
22 |
23 |
GET - Typically created due to a refresh of an ic-src attribute.
24 |
POST - Created by an element with a ic-post-to attribute.
25 |
PUT - Created by an element with a ic-put-to attribute.
26 |
DELETE - Created by an element with a ic-delete-from attribute.
27 |
28 |
29 |
30 | Because not all browsers support PUT and DELETE requests in AJAX, Intercooler
31 | uses the Rails convention and adds a _method parameter to the request.
32 |
33 |
34 |
Standard Parameters
35 |
36 |
37 | Intercooler requests include a few standard parameters:
38 |
39 |
40 |
41 |
ic-request - This will always be true for Intercooler-based requests.
42 |
ic-last-refresh - This is a timestamp of the last time the target element was refreshed.
43 | This can be used to calculate time-sensitive UI updates (e.g. appending to a list of messages.)
44 |
ic-fingerprint - The SHA256 fingerprint of the current content. This can be used to avoid
45 | sending down unnecessary updates, caching, etc.
46 |
47 |
48 |
Request Headers
49 |
50 |
51 | Intercooler requests include a few request headers:
52 |
53 |
54 |
55 |
56 |
57 |
Header
58 |
Description
59 |
60 |
61 |
62 |
63 |
64 | X-IC-Request
65 |
66 |
67 | Set to true
68 |
69 |
70 |
71 |
72 | X-HTTP-Method-Override
73 |
74 |
75 | Set to the HTTP Method type (e.g. DELETE) for the request, to communicate the actual
76 | request type to the server if it cannot be directly supported by the client.
77 |
78 |
79 |
80 |
81 |
82 |
83 |
Additional Parameters
84 |
85 |
86 | Also included in the request is the form value of the element that is initiating the request. So, if
87 | the element is an input, it will include its name/value in the request. If it is a form, it will include
88 | the names/values of all inputs within the form.
89 |
90 |
91 |
92 | You can also include other parameters using the ic-include attribute.
93 |
94 |
95 |
Intercooler Responses
96 |
97 |
Intercooler responses are typically HTML fragments. In the typical case, a fragment of HTML will be returned.
98 | Here is a simple example of a response body:
99 |
100 |
101 |
102 | <div>Here Is Some Content!<div>
103 |
104 |
105 |
This would be swapped in as the body of the element that initiated the request.
106 |
107 |
The returned content can contain Intercooler attributes itself, which will be all wired up.
108 |
109 |
You can control the exact style of the swap using the
110 | ic-transition attribute, and you can
111 | control the element that will be swapped out via the request by using the
112 | ic-target attribute.
113 |
114 |
Empty Bodies
115 |
116 |
Intercooler interprets an empty body in a request as a No-Op, and will do nothing in response.
117 |
118 |
119 |
Intercooler HTTP Response Headers
120 |
121 |
Sadly, not all UI patterns can be elegantly captured via straight element swapping. Occasionally
122 | you need to invoke a bit more client side javascript, let other elements know to refresh themselves,
123 | redirect the user entirely, etc.
124 |
125 |
To handle these situations, Intercooler responses have at their disposal some custom HTTP headers. These
126 | headers can be used to instruct intercooler to perform additional work :
127 |
128 |
129 |
The following Intercooler response headers are available:
153 | Allows you to pass JSON data to the event triggered by the X-IC-Trigger header. Note that
154 | extraParameters passed to the event are treated as an argument list if the data is a JSON
155 | array. See the JQuery trigger() documentation for more information.
156 |
157 |
158 |
159 |
160 | X-IC-Refresh
161 |
162 |
163 | A comma separated list of dependency paths to refresh.
164 |
165 |
166 |
167 |
168 | X-IC-Redirect
169 |
170 |
171 | Causes a client-side redirect to the given URL.
172 |
173 |
174 |
175 |
176 | X-IC-Script
177 |
178 |
179 | Allows you to evaluate arbitrary javascript.
180 |
181 |
182 |
183 |
184 | X-IC-CancelPolling
185 |
186 |
187 | Cancels any polling associated with the target element.
188 |
189 |
190 |
191 |
192 | X-IC-Open
193 |
194 |
195 | Opens a new window at the given location.
196 |
197 |
198 |
199 |
200 | X-IC-SetLocation (Experimental)
201 |
202 |
203 | Pushes a new location (still in development)
204 |
205 |
206 |
207 |
208 | X-IC-Transition
209 |
210 |
211 | Overrides the elements normal transition.
212 |
Below are some examples of Intercooler functionality, each with a working demo below the code sample.
99 |
100 |
101 |
102 |
103 |
104 |
105 |
Polling
106 |
This is a simple div that polls an http endpoint for updates every 1 second
107 |
108 |
Code
109 |
110 | <div ic-src="/polling_div" ic-poll="1s">Sample Polling Div. Value is 0</div>
111 |
112 |
113 |
Live Example
114 |
115 |
Sample Polling Div. Value is 0
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
Manual Update
124 |
125 |
This is a div that is refreshed explicitly using events and the Intercooler library
126 |
127 |
Code
128 |
129 |
130 | <div id="manual-update" ic-src="/manual_div">Sample Manual Div. Value is 0</div>
131 | <button onclick="Intercooler.refresh($('#manual-update'));">Update It!</button>
132 |
133 |
134 |
Live Example
135 |
136 |
Sample Manual Div. Value is 0
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
Dependency Detection
146 |
147 |
This is a div that is refreshed automatically when the button is clicked due to the fact that it depends
148 | on a URL that the button targets for update.
149 |
150 |
Code
151 |
152 |
153 | <div ic-src="/dependency_div">Sample Dependency Dectection. You have clicked 0 times</div>
154 | <button ic-post-to="/dependency_div">Increment Counter</button>
155 |
156 |
157 |
Live Example
158 |
159 |
Sample Dependency Dectection. You have clicked 0 times
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
CSS Value Targeting
169 |
170 |
You may want to target the value of an style attribute with an endpoint for a smoother UI experience. Below is an
171 | example targeting the 'width' attribute of the style on the progress bar, allowing for smooth easing as it updates.
You may want to target the value of an attribute with an endpoint for a smoother UI experience. Below
196 | we update the entire style block of the element
This example binds two inputs to two different endpoints. The div below them then depends on a parent path, but sources from
218 | a different URL. When you change the value in the inputs (tab out) the div below will update.
Intercooler.js makes it easy to do incremental inline form element validations against your server. Below
257 | is an example that will only allow properly formatted emails.