Skip to content

Real Life Examples

Steve Losh edited this page Jul 1, 2011 · 2 revisions

Let's slap some real Javascript code in here and see how it might translate.

One

$(function() {
    // Utility functions -----------------------------------------------------------
    function getCurrentTime() {
        var d = new Date();
        return d.getTime();
    }
    function performAtTargetTime(target_time, callback) {
        var wait = target_time - getCurrentTime();

        if (wait <= 0) {
            callback();
        } else {
            setTimeout(callback, wait);
        }
    }

    // Miscellaneous ---------------------------------------------------------------
    $('.infield label').inFieldLabels();
    $('ul.slider').nivoSlider({
        animSpeed: 100,
        beforeNewSlide: function(n) {
            $('.info-container').hide();
            $('#feature-info-' + n).show();
        },
        controlNav: false,
        directionNavHide: false,
        effect: 'fade',
        pauseTime: 4000
    });
    $('.sidebar .refine .filters input').change(function() {
        target = $(this).parents('.filter').find('.target').text().replace(/\s+/g, "");
        $('.sidebar input').attr('disabled', 'disabled');
        window.location = target;
    });

    // Main navigation dropdowns ---------------------------------------------------
    $('nav.main li.has-sub > a').click(function() {
        $('nav.main li.open').removeClass('open');
        $(this).parents('li').addClass('open');
        $(this).parents('li').children('span.dropdown').bind('clickoutside', function() {
            $(this).parents('li.open').removeClass('open');
            $(this).unbind('clickoutside');
        });
        return false;
    });
    $('nav.main a.parent').click(function() {
        $(this).parents('li').removeClass('open');
        return false;
    });

    // Truncation ------------------------------------------------------------------
    $('.truncate').truncate(200, {
        trail: [
            ' <a class="read-more truncate_show" href="#">Read More</a>',
            ' <a class="read-more truncate_hide" href="#">Read Less</a>'
        ]
    });
    $('.truncate_less p:last').append('&hellip;');

    // Trip Planner ----------------------------------------------------------------

    // adding individual items to the trip planner
    $('a.add, a.add-to-trip-planner').click(function() {
        var el = $(this);
        var id = el.siblings('.item-info').find('span.item-id').html();
        var type = el.siblings('.item-info').find('span.item-content-type').html();

        var loading = el.parent().find('div.loading');
        var sib = el.parent().find('a.disabled');
        el.addClass('disabled');
        loading.removeClass('disabled');

        var target_time = getCurrentTime() + 1000;

        $.ajax({
            type: 'POST',
            dataType: 'json',
            url: '/trip-planner/add/',
            data: {'id': id, 'type': type},
            success: function(data, textStatus, jqXHR) {
                // swap out add item icon with remove item icon
                var stop_loading = function() {
                    // update the the trip planner count
                    var trip_planner_count = $('#trip-planner-count');
                    trip_planner_count.html(parseFloat(trip_planner_count.html()) + 1);

                    loading.addClass('disabled');
                    sib.removeClass('disabled');
                };
                performAtTargetTime(target_time, stop_loading);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                // indicate to the user that there was an error
                var stop_loading = function() {
                    loading.addClass('disabled');
                    el.removeClass('disabled');
                };
                performAtTargetTime(target_time, stop_loading);
            }
        });

        return false;
    });

    // removing individual items from the trip planner
    // $('a.added, a.remove-from-trip-planner').click(function() {
    $('a.added').click(function() {
        // ajax call to '/trip-planner/add/'
        var el = $(this);
        var id = el.siblings('.item-info').find('span.item-id').html();
        var type = el.siblings('.item-info').find('span.item-content-type').html();

        var loading = el.parent().find('div.loading');
        var sib = el.parent().find('a.disabled');

        el.addClass('disabled');
        loading.removeClass('disabled');

        var target_time = getCurrentTime() + 1000;

        $.ajax({
            type: 'POST',
            dataType: 'json',
            url: '/trip-planner/remove/',
            data: {'id': id, 'type': type},
            success: function(data, textStatus, jqXHR) {
                // swap out add item icon with remove item icon
                var stop_loading = function() {
                    // update the the trip planner count
                    var trip_planner_count = $('#trip-planner-count');
                    trip_planner_count.html(parseFloat(trip_planner_count.html()) - 1);

                    loading.addClass('disabled');
                    sib.removeClass('disabled');
                };
                performAtTargetTime(target_time, stop_loading);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                // indicate to the user that there was an error
                var stop_loading = function() {
                    loading.addClass('disabled');
                    el.removeClass('disabled');
                };
                performAtTargetTime(target_time, stop_loading);
            }
        });

        return false;
    });

    // removing checked items from the trip planner
    $('a.remove').click(function () {
        var renumber = function() {
            // grab all items that are currently unchecked, and
            // number them appropriately
            var items = $('.select input[type="checkbox"]');
            items.each(function (index, value) {
                $(this).closest('.item').find('div.number').html(index+1);
            });
        };

        var checked = $('.select input[type="checkbox"]:checked');
        var selected_items = checked.closest('.item');
        var ids = $.map(selected_items.find('.item-id'), function (el) {
            return $(el).html();
        });
        ids = ids.join(',');

        $.ajax({
            type: 'POST',
            dataType: 'json',
            url: "/trip-planner/remove-checked/",
            data: {'ids': ids},
            success: function(data, textStatus, jqXHR) {
                selected_items.fadeOut(function() {
                    selected_items.remove();
                    renumber();
                });

                // update the trip planner count
                var trip_planner_count = $('#trip-planner-count');
                trip_planner_count.html(parseFloat(trip_planner_count.html()) - selected_items.length);

            },
            error: function(jqXHR, textStatus, errorThrown) {
                // do something to indicate failure
                alert("Sorry, removing items failed.  Please try again in a few moments.");
            }
        });

        return false;
    });

    // CMS Image Styling -----------------------------------------------------------
    $('.body p img').filter(function() {
        return $(this).css('float') == 'left';
    }).css('margin-right', '10px');
    $('.body p img').filter(function() {
        return $(this).css('float') == 'right';
    }).css('margin-left', '10px');

    // Date Pickers ----------------------------------------------------------------
    $('#date_filter_start').datepicker();
    $('#date_filter_end').datepicker();
    $('#clear-dates').click(function() {
        $('.date-selector').val('');
        $('.date-selector').closest('form').submit();

        return false;
    });

    // Blog Images -----------------------------------------------------------------
    $('section.main section.content p img').filter(function() {
        return $(this).css('float') == 'left';
    }).css('margin-right', '10px');
    $('section.main section.content p img').filter(function() {
        return $(this).css('float') == 'right';
    }).css('margin-left', '10px');
});

translates to:

; Utility functions -----------------------------------------------------------
(defn getCurrentTime []
  ((new Date).getTime))

(defn performAtTargetTime [target_time, callback]
  (let [wait (- target_time (getCurrentTime))]
    (if (<= wait 0)
      (callback)
      (setTimeout callback wait))))

; Miscellaneous ---------------------------------------------------------------
(($ '.infield label').inFieldLabels)
(($ 'ul.slider').nivoslider {
    animSpeed 100
    beforeNewSlide #(
        (($ '.info-container').hide)
        (($ (+ '#feature-info-' %).show)))
    controlNav false
    directionNavHide false
    effect 'fade'
    pauseTime 4000
})
(($ '.sidebar .refine .filters input').change #(
    (let [target (chain ($ this)
                        (.parents '.filter')
                        (.find '.target')
                        .text
                        (.replace REGEX))]
    (($ '.sidebar input').attr 'disabled' 'disabled')
    (set window 'location' target))))

; Main navigation dropdowns ---------------------------------------------------
(($ 'nav.main li.has-sub > a').click #(
    (chain ($ 'nav.main li.open')
           (.removeClass 'open'))
    (chain ($ this)
           (.parents 'li')
           (.addClass 'open'))
    (chain ($ this)
           (.parents 'li')
           (.children 'span.dropdown')
           (.bind 'clickoutside' #(
             (chain ($ this)
                    (.parents 'li.open')
                    (.removeClass 'open')
                    (.unbind 'clickoutside')))))
    false
))
(($ 'nav.main a.parent').click #(
    (chain ($ this)
           (.parents 'li')
           (.removeClass 'open'))))

; Truncation ------------------------------------------------------------------
(($ '.truncate').truncate 200 {
    trail: [
        ' <a class="read-more truncate_show" href="#">Read More</a>',
        ' <a class="read-more truncate_hide" href="#">Read Less</a>'
    ]
})
(($ '.truncate_less p:last').append '&hellip;')

; Trip Planner ----------------------------------------------------------------
; adding individual items to the trip planner
(($ 'a.add, a.add-to-trip-planner').click #(
   (let [el ($ this)
         id (chain el
                   (.siblings '.item-info')
                   (.find ('span.item-id')
                   .html))
         type (chain el
                     (.siblings '.item-info')
                     (.find 'span.item-content-type')
                     .html)
         loading (el.parent.find 'div.loading')
         sib (el.parent.find 'a.disabled')
         target_time (+ (getCurrentTime) 1000)]
     (el.addClass 'disabled')
     (loading.removeClass 'disabled')
     ($.ajax {
        type 'POST'
        dataType 'json'
        url '/trip-planner/add/'
        data {'id' id
              'type' type},
        success #(
            ; swap out add item icon with remove item icon
            (performAtTargetTime target_time #(
                // update the the trip planner count
                (let [trip_planner_count ($ '#trip-planner-count')]
                   (trip_planner_count.html (+ 1 (parseFloat trip_planner_count.html)))
                   (loading.addClass 'disabled')
                   (sib.removeClass 'disabled')
                )
            ))
        )
        error: #(
            ; indicate to the user that there was an error
            (performAtTargetTimetarget_time #(
                (loading.addClass 'disabled')
                (el.removeClass 'disabled')
            ))
        )
     })
     false)))

; removing individual items from the trip planner
; $('a.added, a.remove-from-trip-planner').click(function() {
$('a.added').click(function() {
    // ajax call to '/trip-planner/add/'
    var el = $(this);
    var id = el.siblings('.item-info').find('span.item-id').html();
    var type = el.siblings('.item-info').find('span.item-content-type').html();

    var loading = el.parent().find('div.loading');
    var sib = el.parent().find('a.disabled');

    el.addClass('disabled');
    loading.removeClass('disabled');

    var target_time = getCurrentTime() + 1000;

    $.ajax({
        type: 'POST',
        dataType: 'json',
        url: '/trip-planner/remove/',
        data: {'id': id, 'type': type},
        success: function(data, textStatus, jqXHR) {
            // swap out add item icon with remove item icon
            var stop_loading = function() {
                // update the the trip planner count
                var trip_planner_count = $('#trip-planner-count');
                trip_planner_count.html(parseFloat(trip_planner_count.html()) - 1);

                loading.addClass('disabled');
                sib.removeClass('disabled');
            };
            performAtTargetTime(target_time, stop_loading);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            // indicate to the user that there was an error
            var stop_loading = function() {
                loading.addClass('disabled');
                el.removeClass('disabled');
            };
            performAtTargetTime(target_time, stop_loading);
        }
    });

    return false;
});

; removing checked items from the trip planner
$('a.remove').click(function () {
    var renumber = function() {
        // grab all items that are currently unchecked, and
        // number them appropriately
        var items = $('.select input[type="checkbox"]');
        items.each(function (index, value) {
            $(this).closest('.item').find('div.number').html(index+1);
        });
    };

    var checked = $('.select input[type="checkbox"]:checked');
    var selected_items = checked.closest('.item');
    var ids = $.map(selected_items.find('.item-id'), function (el) {
        return $(el).html();
    });
    ids = ids.join(',');

    $.ajax({
        type: 'POST',
        dataType: 'json',
        url: "/trip-planner/remove-checked/",
        data: {'ids': ids},
        success: function(data, textStatus, jqXHR) {
            selected_items.fadeOut(function() {
                selected_items.remove();
                renumber();
            });

            // update the trip planner count
            var trip_planner_count = $('#trip-planner-count');
            trip_planner_count.html(parseFloat(trip_planner_count.html()) - selected_items.length);

        },
        error: function(jqXHR, textStatus, errorThrown) {
            // do something to indicate failure
            alert("Sorry, removing items failed.  Please try again in a few moments.");
        }
    });

    return false;
});

; CMS Image Styling -----------------------------------------------------------
((($ '.body p img').filter #(
    (= (($ this).css 'float') 'left')
)).css 'margin-right' '10px')
((($ '.body p img').filter #(
    (= (($ this).css 'float') 'right')
)).css 'margin-left' '10px')

; Date Pickers ----------------------------------------------------------------
(($ '#date_filter_start').datepicker)
(($ '#date_filter_end').datepicker)
(($ '#clear-dates').click #(
    (($ '.date-selector').val '')
    (chain ($ '.date-selector')
           (.closest 'form')
           .submit)
    false
))

; Blog Images -----------------------------------------------------------------
((($ 'section.main section.content p img').filter #(
    (= (($this).css 'float') 'left')
)).css 'margin-right' '10px')
((($ 'section.main section.content p img').filter #(
    (= (($this).css 'float') 'right')
)).css 'margin-left' '10px')
Something went wrong with that request. Please try again.