0

My javascript files are working fine in a simple Html/CSS setup; however, when I try to carry over my javascript files to my rails application they seem to be ignored.

I have 2 sets of javascript files: vendor min.js files and my own js files.

I won't show the min.js files because they are quite large files but here are their names anyways:

skel.min.js, jquery.scrollgress.min.js, jquery.min.js, jquery.dropotron.min.js

I have tried placing the main.js & util.js in the app/assets/javascript directory and min.js files in the vender javascript directory.

I have also tried adding <%= javascript_include_tag "customjsFile", "data-turbolinks-track" => true %> and //= require customejsfile to their corresponding locations, but also that didn't work.

Is there something obvious that I am not seeing?

I am runnig Rails 5.0.3.

application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

main.js

(function($) {

skel.breakpoints({
    wide: '(max-width: 1680px)',
    normal: '(max-width: 1280px)',
    narrow: '(max-width: 980px)',
    narrower: '(max-width: 840px)',
    mobile: '(max-width: 736px)',
    mobilep: '(max-width: 480px)'
});

$(function() {

    var $window = $(window),
        $body = $('body'),
        $header = $('#header'),
        $banner = $('#banner');

    // Fix: Placeholder polyfill.
        $('form').placeholder();

    // Prioritize "important" elements on narrower.
        skel.on('+narrower -narrower', function() {
            $.prioritize(
                '.important\\28 narrower\\29',
                skel.breakpoint('narrower').active
            );
        });

    // Dropdowns.
        $('#nav > ul').dropotron({
            alignment: 'center'
        });

    // Off-Canvas Navigation.

        // Navigation Button.
            $(
                '<div id="navButton">' +
                    '<a href="#navPanel" class="toggle"></a>' +
                '</div>'
            )
                .appendTo($body);

        // Navigation Panel.
            $(
                '<div id="navPanel">' +
                    '<nav>' +
                        $('#nav').navList() +
                    '</nav>' +
                '</div>'
            )
                .appendTo($body)
                .panel({
                    delay: 500,
                    hideOnClick: true,
                    hideOnSwipe: true,
                    resetScroll: true,
                    resetForms: true,
                    side: 'left',
                    target: $body,
                    visibleClass: 'navPanel-visible'
                });

        // Fix: Remove transitions on WP<10 (poor/buggy performance).
            if (skel.vars.os == 'wp' && skel.vars.osVersion < 10)
                $('#navButton, #navPanel, #page-wrapper')
                    .css('transition', 'none');

    // Header.
    // If the header is using "alt" styling and #banner is present, use scrollwatch
    // to revert it back to normal styling once the user scrolls past the banner.
    // Note: This is disabled on mobile devices.
        if (!skel.vars.mobile
        &&  $header.hasClass('alt')
        &&  $banner.length > 0) {

            $window.on('load', function() {

                $banner.scrollwatch({
                    delay:      0,
                    range:      1,
                    anchor:     'top',
                    on:         function() { $header.addClass('alt reveal'); },
                    off:        function() { $header.removeClass('alt'); }
                });

            });

        }

});

})(jQuery);

util.js

(function($) {

/**
 * Generate an indented list of links from a nav. Meant for use with panel().
 * @return {jQuery} jQuery object.
 */
$.fn.navList = function() {

    var $this = $(this);
        $a = $this.find('a'),
        b = [];

    $a.each(function() {

        var $this = $(this),
            indent = Math.max(0, $this.parents('li').length - 1),
            href = $this.attr('href'),
            target = $this.attr('target');

        b.push(
            '<a ' +
                'class="link depth-' + indent + '"' +
                ( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
                ( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
            '>' +
                '<span class="indent-' + indent + '"></span>' +
                $this.text() +
            '</a>'
        );

    });

    return b.join('');

};

/**
 * Panel-ify an element.
 * @param {object} userConfig User config.
 * @return {jQuery} jQuery object.
 */
$.fn.panel = function(userConfig) {

    // No elements?
        if (this.length == 0)
            return $this;

    // Multiple elements?
        if (this.length > 1) {

            for (var i=0; i < this.length; i++)
                $(this[i]).panel(userConfig);

            return $this;

        }

    // Vars.
        var $this = $(this),
            $body = $('body'),
            $window = $(window),
            id = $this.attr('id'),
            config;

    // Config.
        config = $.extend({

            // Delay.
                delay: 0,

            // Hide panel on link click.
                hideOnClick: false,

            // Hide panel on escape keypress.
                hideOnEscape: false,

            // Hide panel on swipe.
                hideOnSwipe: false,

            // Reset scroll position on hide.
                resetScroll: false,

            // Reset forms on hide.
                resetForms: false,

            // Side of viewport the panel will appear.
                side: null,

            // Target element for "class".
                target: $this,

            // Class to toggle.
                visibleClass: 'visible'

        }, userConfig);

        // Expand "target" if it's not a jQuery object already.
            if (typeof config.target != 'jQuery')
                config.target = $(config.target);

    // Panel.

        // Methods.
            $this._hide = function(event) {

                // Already hidden? Bail.
                    if (!config.target.hasClass(config.visibleClass))
                        return;

                // If an event was provided, cancel it.
                    if (event) {

                        event.preventDefault();
                        event.stopPropagation();

                    }

                // Hide.
                    config.target.removeClass(config.visibleClass);

                // Post-hide stuff.
                    window.setTimeout(function() {

                        // Reset scroll position.
                            if (config.resetScroll)
                                $this.scrollTop(0);

                        // Reset forms.
                            if (config.resetForms)
                                $this.find('form').each(function() {
                                    this.reset();
                                });

                    }, config.delay);

            };

        // Vendor fixes.
            $this
                .css('-ms-overflow-style', '-ms-autohiding-scrollbar')
                .css('-webkit-overflow-scrolling', 'touch');

        // Hide on click.
            if (config.hideOnClick) {

                $this.find('a')
                    .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');

                $this
                    .on('click', 'a', function(event) {

                        var $a = $(this),
                            href = $a.attr('href'),
                            target = $a.attr('target');

                        if (!href || href == '#' || href == '' || href == '#' + id)
                            return;

                        // Cancel original event.
                            event.preventDefault();
                            event.stopPropagation();

                        // Hide panel.
                            $this._hide();

                        // Redirect to href.
                            window.setTimeout(function() {

                                if (target == '_blank')
                                    window.open(href);
                                else
                                    window.location.href = href;

                            }, config.delay + 10);

                    });

            }

        // Event: Touch stuff.
            $this.on('touchstart', function(event) {

                $this.touchPosX = event.originalEvent.touches[0].pageX;
                $this.touchPosY = event.originalEvent.touches[0].pageY;

            })

            $this.on('touchmove', function(event) {

                if ($this.touchPosX === null
                ||  $this.touchPosY === null)
                    return;

                var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
                    diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
                    th = $this.outerHeight(),
                    ts = ($this.get(0).scrollHeight - $this.scrollTop());

                // Hide on swipe?
                    if (config.hideOnSwipe) {

                        var result = false,
                            boundary = 20,
                            delta = 50;

                        switch (config.side) {

                            case 'left':
                                result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
                                break;

                            case 'right':
                                result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
                                break;

                            case 'top':
                                result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
                                break;

                            case 'bottom':
                                result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
                                break;

                            default:
                                break;

                        }

                        if (result) {

                            $this.touchPosX = null;
                            $this.touchPosY = null;
                            $this._hide();

                            return false;

                        }

                    }

                // Prevent vertical scrolling past the top or bottom.
                    if (($this.scrollTop() < 0 && diffY < 0)
                    || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {

                        event.preventDefault();
                        event.stopPropagation();

                    }

            });

        // Event: Prevent certain events inside the panel from bubbling.
            $this.on('click touchend touchstart touchmove', function(event) {
                event.stopPropagation();
            });

        // Event: Hide panel if a child anchor tag pointing to its ID is clicked.
            $this.on('click', 'a[href="#' + id + '"]', function(event) {

                event.preventDefault();
                event.stopPropagation();

                config.target.removeClass(config.visibleClass);

            });

    // Body.

        // Event: Hide panel on body click/tap.
            $body.on('click touchend', function(event) {
                $this._hide(event);
            });

        // Event: Toggle.
            $body.on('click', 'a[href="#' + id + '"]', function(event) {

                event.preventDefault();
                event.stopPropagation();

                config.target.toggleClass(config.visibleClass);

            });

    // Window.

        // Event: Hide on ESC.
            if (config.hideOnEscape)
                $window.on('keydown', function(event) {

                    if (event.keyCode == 27)
                        $this._hide(event);

                });

    return $this;

};

/**
 * Apply "placeholder" attribute polyfill to one or more forms.
 * @return {jQuery} jQuery object.
 */
$.fn.placeholder = function() {

    // Browser natively supports placeholders? Bail.
        if (typeof (document.createElement('input')).placeholder != 'undefined')
            return $(this);

    // No elements?
        if (this.length == 0)
            return $this;

    // Multiple elements?
        if (this.length > 1) {

            for (var i=0; i < this.length; i++)
                $(this[i]).placeholder();

            return $this;

        }

    // Vars.
        var $this = $(this);

    // Text, TextArea.
        $this.find('input[type=text],textarea')
            .each(function() {

                var i = $(this);

                if (i.val() == ''
                ||  i.val() == i.attr('placeholder'))
                    i
                        .addClass('polyfill-placeholder')
                        .val(i.attr('placeholder'));

            })
            .on('blur', function() {

                var i = $(this);

                if (i.attr('name').match(/-polyfill-field$/))
                    return;

                if (i.val() == '')
                    i
                        .addClass('polyfill-placeholder')
                        .val(i.attr('placeholder'));

            })
            .on('focus', function() {

                var i = $(this);

                if (i.attr('name').match(/-polyfill-field$/))
                    return;

                if (i.val() == i.attr('placeholder'))
                    i
                        .removeClass('polyfill-placeholder')
                        .val('');

            });

    // Password.
        $this.find('input[type=password]')
            .each(function() {

                var i = $(this);
                var x = $(
                            $('<div>')
                                .append(i.clone())
                                .remove()
                                .html()
                                .replace(/type="password"/i, 'type="text"')
                                .replace(/type=password/i, 'type=text')
                );

                if (i.attr('id') != '')
                    x.attr('id', i.attr('id') + '-polyfill-field');

                if (i.attr('name') != '')
                    x.attr('name', i.attr('name') + '-polyfill-field');

                x.addClass('polyfill-placeholder')
                    .val(x.attr('placeholder')).insertAfter(i);

                if (i.val() == '')
                    i.hide();
                else
                    x.hide();

                i
                    .on('blur', function(event) {

                        event.preventDefault();

                        var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');

                        if (i.val() == '') {

                            i.hide();
                            x.show();

                        }

                    });

                x
                    .on('focus', function(event) {

                        event.preventDefault();

                        var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');

                        x.hide();

                        i
                            .show()
                            .focus();

                    })
                    .on('keypress', function(event) {

                        event.preventDefault();
                        x.val('');

                    });

            });

    // Events.
        $this
            .on('submit', function() {

                $this.find('input[type=text],input[type=password],textarea')
                    .each(function(event) {

                        var i = $(this);

                        if (i.attr('name').match(/-polyfill-field$/))
                            i.attr('name', '');

                        if (i.val() == i.attr('placeholder')) {

                            i.removeClass('polyfill-placeholder');
                            i.val('');

                        }

                    });

            })
            .on('reset', function(event) {

                event.preventDefault();

                $this.find('select')
                    .val($('option:first').val());

                $this.find('input,textarea')
                    .each(function() {

                        var i = $(this),
                            x;

                        i.removeClass('polyfill-placeholder');

                        switch (this.type) {

                            case 'submit':
                            case 'reset':
                                break;

                            case 'password':
                                i.val(i.attr('defaultValue'));

                                x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');

                                if (i.val() == '') {
                                    i.hide();
                                    x.show();
                                }
                                else {
                                    i.show();
                                    x.hide();
                                }

                                break;

                            case 'checkbox':
                            case 'radio':
                                i.attr('checked', i.attr('defaultValue'));
                                break;

                            case 'text':
                            case 'textarea':
                                i.val(i.attr('defaultValue'));

                                if (i.val() == '') {
                                    i.addClass('polyfill-placeholder');
                                    i.val(i.attr('placeholder'));
                                }

                                break;

                            default:
                                i.val(i.attr('defaultValue'));
                                break;

                        }
                    });

            });

    return $this;

};

/**
 * Moves elements to/from the first positions of their respective parents.
 * @param {jQuery} $elements Elements (or selector) to move.
 * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
 */
$.prioritize = function($elements, condition) {

    var key = '__prioritize';

    // Expand $elements if it's not already a jQuery object.
        if (typeof $elements != 'jQuery')
            $elements = $($elements);

    // Step through elements.
        $elements.each(function() {

            var $e = $(this), $p,
                $parent = $e.parent();

            // No parent? Bail.
                if ($parent.length == 0)
                    return;

            // Not moved? Move it.
                if (!$e.data(key)) {

                    // Condition is false? Bail.
                        if (!condition)
                            return;

                    // Get placeholder (which will serve as our point of reference for when this element needs to move back).
                        $p = $e.prev();

                        // Couldn't find anything? Means this element's already at the top, so bail.
                            if ($p.length == 0)
                                return;

                    // Move element to top of parent.
                        $e.prependTo($parent);

                    // Mark element as moved.
                        $e.data(key, $p);

                }

            // Moved already?
                else {

                    // Condition is true? Bail.
                        if (condition)
                            return;

                    $p = $e.data(key);

                    // Move element back to its original location (using our placeholder).
                        $e.insertAfter($p);

                    // Unmark element as moved.
                        $e.removeData(key);

                }

        });

};

})(jQuery);

original index.html file

 <html>        
    <body>
        .
        . 
        .
        <script src="assets/js/jquery.min.js"></script>
        <script src="assets/js/jquery.dropotron.min.js"></script>
        <script src="assets/js/jquery.scrollgress.min.js"></script>
        <script src="assets/js/skel.min.js"></script>
        <script src="assets/js/util.js"></script>
        <!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
        <script src="assets/js/main.js"></script>
     </body>
</html>
11
  • Can you please share your application.js? Commented Oct 2, 2017 at 9:03
  • Sure thing! (Let me know if you would like me to post any other code) Commented Oct 2, 2017 at 16:10
  • By "ignored" you mean not loaded? Not executed (with/without errors)? Commented Oct 2, 2017 at 16:18
  • Correct. ^ The javascript files are used for a menu dropdown and to create a menu button when the screen reduce for a responsive design. Commented Oct 2, 2017 at 16:20
  • Don't really know, I think you could try again with //= require customejsfile and add a bunch of logs to the js files to see what's happening. Maybe jquery was loaded twice or some files are not loaded in the right order, note "the order in which files are included by require_tree is unspecified" Commented Oct 2, 2017 at 16:33

1 Answer 1

1

Note my origin index.html file. I had to emulate that behavior in rails.

This is a working solution, all though I am not sure if it is the most efficient or Rails appropiate soultion.

step 1:

I created a javascript file called _js-file.html.erb and included it to the bottom of my application.html.erb file <%= render 'layouts/js-file' %>

<%= javascript_include_tag('jquery.min.js') %>
<%= javascript_include_tag('jquery.dropotron.min.js') %>
<%= javascript_include_tag('jquery.scrollgress.min.js') %>
<%= javascript_include_tag('skel.min.js') %>
<%= javascript_include_tag('util.js') %>
<%= javascript_include_tag('main.js') %>

step 2:

next you have to comply with the precompile assets go into your assets.rb file found in config/initializers/ folder and add your javascript files.

Rails.application.config.assets.precompile += %w( filename1.js filename2.js ...)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.