Build-in components

There are components which are integrated into AbsurdJS and you are able to inject them in every of the your component's functions.



is

A helper component wrapping common tasks.

appended ( selector )

It checks if there is a DOM element matching the passed selector

No minification:
absurd.component('MyComp', {
    constructor: function(is) {
        if(is.appended('body')) {
            console.log('Yes, there is a body tag.');
        }
    }
})();
Minification protection:
absurd.component('MyComp', {
    constructor: ['is', function(is) {
        if(is.appended('body')) {
            console.log('Yes, there is a body tag.');
        }
    }]
})();

hidden ( element )

It checks if the element is visible. If the method is called without parameters AbsurdJS uses the current component's element.

absurd.component('MyComp', {
    constructor: function(is) {
        if(is.hidden()) {
            console.log('Yes, the element is hidden.');
        }
    }
})();

router

Class providing single page app routing. It supports hash based URLs and may use the History API. A demo could be found here. Read about how this class is created in A modern JavaScript router in 100 lines. To be sure that everything works run the test suite here).

add ( regex, handler )

Registering a new route.

absurd.component('MyComp', {
    constructor: function(router) {
        router
        .add(/about\/?$/, function() {
            // matching: /about
        })
        .add(/products\/(.*)\/edit\/(.*)\/(.*)?$/, function(id, a, b) {
            // matching: products/34/edit/a/b
        })
        .add(function() {
            // default route
        });
    }
})();

remove ( regex | handler )

Deletes a registered route.

absurd.component('MyComp', {
    constructor: function(router) {
        router.remove(/about/);
    }
})();

flush ( )

Removes all the added routes.

absurd.component('MyComp', {
    constructor: function(router) {
        router.flush();
    }
})();

config ( options )

The options is an object with two possible properties - mode could be hash (default) or history, root contains the root path of your application. Have in mind that if the History API is not supported mode is always hash even if you set history. The root option is required only if the router uses pushState i.e. the History API.

absurd.component('MyComp', {
    constructor: function(router) {
        router.config({ 
            mode: 'history',
            root: '/single-page-app/test/' 
        });
    }
})();

listen ( )

Starts listening for changes in the URL. If this method is not called you should call check manually.

absurd.component('MyComp', {
    constructor: function(router) {
        router.listen();
    }
})();

check ( )

It compares the current URL and if it is a new one and matches some of the registered routes it calls the handler. The method is called internally by the listen method.

absurd.component('MyComp', {
    constructor: function(router) {
        router.check();
    }
})();

Changes the current URL.

absurd.component('MyComp', {
    constructor: function(router) {
        router.navigate('/products/show/33');
    }
})();

ajax

The class deals with GET and POST requests. It also handles the loading of external JSON files. To be sure that everything works run the test suite here.

GET request

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request('data/data.txt')
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

GET request with parameters

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({
            url: 'data/data-get.php', 
            data: { 
                a: 'AbsurdJS is a javascript library', 
                b: 'with super powers.'
            }
        })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

POST request

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({
            url: 'data/data-post.php', 
            method: 'post'
        })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

POST request with parameters

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({
            url: 'data/data-post.php', 
            data: { 
                a: 'AbsurdJS is a javascript library', 
                b: 'with super powers.'
            },
            method: 'post'
        })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

PUT request

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({ 'data/data.php', method: 'put' })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

DELETE request

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({ 'data/data.php', method: 'delete' })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

Setting headers

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({
            url: 'data/header.php', 
            headers: { 
                'absurd-header': 'oh yeah'
            }
        })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

Getting JSON

absurd.component('TestingAjax', {
    constructor: function(ajax) {
        ajax
        .request({
            url: 'data/data.json', 
            json: true
        })
        .done(function(data) {
            // ...
        })
        .fail(function(xhr) {
            // ...  
        })
        .always(function(xhr) {
            // ...
        })
    }
})();

dom

We are communicating with DOM elements all the time, getting or setting values. This module simplifies these processes.

Accessing a DOM element

HTML:
<p class="content">Paragraph</p>
JavaScript:
absurd.component('TestingDOM', {
    constructor: function(dom) {
        var el = dom('.content').el;
        console.log(el.outerHTML); 
        // <p class="content">Paragraph</p>
    }
})();

Accessing several DOM elements at once

HTML:
<section>
    <h1>AbsurdJS</h1>
    <p>JavaScript library with super powers</p>
    <footer>
        absurdjs.com
        <br />
        <small>version: 0.3</small>
    </footer>
</section>
JavaScript:
absurd.component('TestingDOM', {
    constructor: function(dom) {
        var els = dom({
            title: 'h1',
            text: 'p',
            other: {
                version: 'footer small'
            }
        }, 'section');
        console.log(els.title.el.innerHTML);
        // AbsurdJS
        console.log(els.text.el.innerHTML);
        // JavaScript library with super powers
        console.log(els.other.version.el.innerHTML);
        // version: 0.3
    }
})();

Scoping

By default the dom function is querying the DOM tree from the current document object. However, if your component has a valid html property set up and you call populate before to use dom the scope is changed. For example:

HTML:
<p class="content">A</p>
<section>
    <p class="content">B</p>
</section>
JavaScript:
absurd.component('TestingDOM', {
    html: 'section',
    constructor: function(dom) {
        this.populate();
        var el = dom('.content').el;
        console.log(el.outerHTML); 
        // <p class="content">B</p>
    }
})();

Of course, if you want you may specify your own scope.

HTML:
<p class="content">A</p>
<section>
    <p class="content">B</p>
</section>
<section id='my-section'>
    <p class="content">C</p>
</section>
JavaScript:
absurd.component('TestingDOM', {
    constructor: function(dom) {
        var el = dom('.content', '#my-section').el;
        console.log(el.outerHTML); 
        // <p class="content">B</p>
    }
})();

Setting and getting value from a text field

HTML:
<form>
    <input type="text" value="default text"/>
</form>
JavaScript:
absurd.component('TestingDOM', {
    constructor: function(dom) {
        var input = dom('[type="text"]');
        console.log(input.val()); // default text
        input.val('absurdjs'); // sets a new value
    }
})();

Setting and getting value from a text area and select box

HTML:
<form>
    <textarea>JavaScript is </textarea>
    <select>
        <option value="cool">cool</option>
        <option value="awesome" selected="selected">awesome</option>
        <option value="difficult">difficult</option>
    </select>
</form>
JavaScript:
absurd.component('TestingDOM', {
    constructor: function(dom) {
        var textarea = dom('textarea');
        var select = dom('select');
        console.log(textarea.val() + select.val());
        // JavaScript is awesome
        textarea.val('Coding is ');
        select.val('difficult');
        console.log(textarea.val() + select.val());
        // Conding is difficult
    }
})();

Setting and getting value from a radio and check boxes

HTML:
<form>
    <input type="radio" value="oA" name="options"> option A
    <input type="radio" value="oB" name="options" checked> option B
    <input type="checkbox" value="f1" name="features"> feature 1
    <input type="checkbox" value="f2" checked name="features"> feature 2
    <input type="checkbox" value="f3" checked name="features"> feature 2
</form>
JavaScript:
absurd.component('TestingDOM', {
    ready: function(dom) {
        console.log(dom('[type="radio"]').val());
        // oB
        console.log(dom('[type="checkbox"]').val());
        // ['f2', 'f3']
    }
})();

Setting and getting value from any other DOM element

HTML:
<div class="content">
    <h1>AbsurdJS</h1>
    <div class="inner">
        <p>JavaScript library with super powers. Find the official web site <a href="http://absurdjs.com">here</a>.</p>
    </div>
    <footer>footer</footer>
</div>
JavaScript:
absurd.component('TestingDOM', {
    ready: function(dom) {
        console.log(dom('h1').val());
        // AbsurdJS
        console.log(dom('.inner').val());
        // JavaScript library with super powers.
        // Find the official web site here.
        console.log(dom('.inner a').val());
        // here

        // setting new values
        dom('.inner').val('New Text');
        dom('h1').val('New Title');
    }
})();

Getting values of several elements at once

HTML:
<form class="contacts">
    Name:
    <input type="text" name="name" value="John" />
    <br />Your email:
    <input type="email" name="email"  value="j@j.com" />
    <br />Experience:
    <input type="radio" name="exp" value="l1" /> level 1
    <input type="radio" name="exp" value="l2" /> level 2
    <input type="radio" name="exp" value="l3" checked /> level 3
    <br />
    <div class="info">
        Version: <span class="ver">0.3</span>
        Position: <span class="pos">web</span>
    </div>
</form>
JavaScript:
absurd.component('TestingDOM', {
    ready: function(dom) {
        console.log(dom({
            user: {
                name: '[name="name"]',
                mail: '[name="email"]',
                exp: '[name="exp"]'
            },
            information: {
                version: '.ver',
                position: '.pos'
            }
        }, 'form.contacts').val());
    }
})();

The result of the code above is the following object:

{
    information: {
        position: "web",
        version: "0.3"
    },
    user: {
        exp: "l3",
        mail: "j@j.com",
        name: "John"
    }
}

mq

AbsurdJS provides an API for using Media Queries in JavaScript. It works with window.matchMedia by default but also has a polyfill if that feature is not supported by the browser.

The mq method accepts three properties. The first one is your query, the second one is a callback function which is called once at the beginning and again on every match or mismatch. The last argument tells to Absurd to use the polyfill or not. You will usually leave it blank.

ready: function(mq) {
    // the handler is called at least once 
    // it is fired again if the query changes its status
    mq('all and (min-width: 300px)', function(match) {
        // match = true or false
    });
}

Here is a full example showing a div with text Test which becomes green or red depending on the browser's width.

absurd.component('MyComp', {
    html: { div: 'Test' },
    css: { div: { color: '#f00' }},    
    ready: function(dom, mq) {
        this.set('parent', dom('body').el).populate();
        mq('all and (min-width: 300px)', function(match) {
            if(match) { 
                this.css.div.color = '#0f0';
            } else {
                this.css.div.color = '#f00';
            }
            this.populate();
        });
    }
})();

To see the result in the JSBin example drag the panels' divider to the left.





comments powered by Disqus