diff options
70 files changed, 2531 insertions, 84 deletions
@@ -26,6 +26,7 @@ gem 'inherited_resources'  gem 'will_paginate', '~> 3.0'  gem 'ransack'  gem 'squeel' +gem 'RedCloth'  gem "acts_as_tree", :git => "git://github.com/dryade/acts_as_tree.git"  gem 'apartment', :git => 'git://github.com/dryade/apartment.git' diff --git a/Gemfile.lock b/Gemfile.lock index bdbcf1e80..6825f1f71 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -51,6 +51,8 @@ GEM    remote: http://rubygems.org/    specs:      GeoRuby (1.3.4) +    RedCloth (4.2.9) +    RedCloth (4.2.9-java)      SyslogLogger (1.4.0)        hoe (>= 1.2.0)      actionmailer (3.1.3) @@ -162,8 +164,8 @@ GEM      jruby-openssl (0.7.4)        bouncy-castle-java      jruby-rack (1.1.5) -    json (1.6.6) -    json (1.6.6-java) +    json (1.7.0) +    json (1.7.0-java)      launchy (2.0.5)        addressable (~> 2.2.6)      launchy (2.0.5-java) @@ -261,7 +263,7 @@ GEM      shoulda-context (1.0.0)      shoulda-matchers (1.0.0)      spoon (0.0.1) -    sprockets (2.0.3) +    sprockets (2.0.4)        hike (~> 1.2)        rack (~> 1.0)        tilt (~> 1.1, != 1.3.0) @@ -296,6 +298,7 @@ PLATFORMS    ruby  DEPENDENCIES +  RedCloth    SyslogLogger    activerecord-jdbcpostgresql-adapter!    activerecord-jdbcsqlite3-adapter diff --git a/app/assets/images/icons/select_parent.png b/app/assets/images/icons/select_parent.png Binary files differnew file mode 100644 index 000000000..429991dc4 --- /dev/null +++ b/app/assets/images/icons/select_parent.png diff --git a/app/assets/javascripts/jquery.tokeninput.js b/app/assets/javascripts/jquery.tokeninput.js new file mode 100644 index 000000000..87641a57a --- /dev/null +++ b/app/assets/javascripts/jquery.tokeninput.js @@ -0,0 +1,860 @@ +/* + * jQuery Plugin: Tokenizing Autocomplete Text Entry + * Version 1.6.0 + * + * Copyright (c) 2009 James Smith (http://loopj.com) + * Licensed jointly under the GPL and MIT licenses, + * choose which one suits your project best! + * + */ + +(function ($) { +// Default settings +var DEFAULT_SETTINGS = { +	// Search settings +    method: "GET", +    contentType: "json", +    queryParam: "q", +    searchDelay: 300, +    minChars: 1, +    propertyToSearch: "name", +    jsonContainer: null, + +	// Display settings +    hintText: "Type in a search term", +    noResultsText: "No results", +    searchingText: "Searching...", +    deleteText: "×", +    animateDropdown: true, + +	// Tokenization settings +    tokenLimit: null, +    tokenDelimiter: ",", +    preventDuplicates: false, + +	// Output settings +    tokenValue: "id", + +	// Prepopulation settings +    prePopulate: null, +    processPrePopulate: false, + +	// Manipulation settings +    idPrefix: "token-input-", + +	// Formatters +    resultsFormatter: function(item){ return "<li>" + item[this.propertyToSearch]+ "</li>" }, +    tokenFormatter: function(item) { return "<li><p>" + item[this.propertyToSearch] + "</p></li>" }, + +	// Callbacks +    onResult: null, +    onAdd: null, +    onDelete: null, +    onReady: null +}; + +// Default classes to use when theming +var DEFAULT_CLASSES = { +    tokenList: "token-input-list", +    token: "token-input-token", +    tokenDelete: "token-input-delete-token", +    selectedToken: "token-input-selected-token", +    highlightedToken: "token-input-highlighted-token", +    dropdown: "token-input-dropdown", +    dropdownItem: "token-input-dropdown-item", +    dropdownItem2: "token-input-dropdown-item2", +    selectedDropdownItem: "token-input-selected-dropdown-item", +    inputToken: "token-input-input-token" +}; + +// Input box position "enum" +var POSITION = { +    BEFORE: 0, +    AFTER: 1, +    END: 2 +}; + +// Keys "enum" +var KEY = { +    BACKSPACE: 8, +    TAB: 9, +    ENTER: 13, +    ESCAPE: 27, +    SPACE: 32, +    PAGE_UP: 33, +    PAGE_DOWN: 34, +    END: 35, +    HOME: 36, +    LEFT: 37, +    UP: 38, +    RIGHT: 39, +    DOWN: 40, +    NUMPAD_ENTER: 108, +    COMMA: 188 +}; + +// Additional public (exposed) methods +var methods = { +    init: function(url_or_data_or_function, options) { +        var settings = $.extend({}, DEFAULT_SETTINGS, options || {}); + +        return this.each(function () { +            $(this).data("tokenInputObject", new $.TokenList(this, url_or_data_or_function, settings)); +        }); +    }, +    clear: function() { +        this.data("tokenInputObject").clear(); +        return this; +    }, +    add: function(item) { +        this.data("tokenInputObject").add(item); +        return this; +    }, +    remove: function(item) { +        this.data("tokenInputObject").remove(item); +        return this; +    }, +    get: function() { +    	return this.data("tokenInputObject").getTokens(); +   	} +} + +// Expose the .tokenInput function to jQuery as a plugin +$.fn.tokenInput = function (method) { +    // Method calling and initialization logic +    if(methods[method]) { +        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); +    } else { +        return methods.init.apply(this, arguments); +    } +}; + +// TokenList class for each input +$.TokenList = function (input, url_or_data, settings) { +    // +    // Initialization +    // + +    // Configure the data source +    if($.type(url_or_data) === "string" || $.type(url_or_data) === "function") { +        // Set the url to query against +        settings.url = url_or_data; + +        // If the URL is a function, evaluate it here to do our initalization work +        var url = computeURL(); + +        // Make a smart guess about cross-domain if it wasn't explicitly specified +        if(settings.crossDomain === undefined) { +            if(url.indexOf("://") === -1) { +                settings.crossDomain = false; +            } else { +                settings.crossDomain = (location.href.split(/\/+/g)[1] !== url.split(/\/+/g)[1]); +            } +        } +    } else if(typeof(url_or_data) === "object") { +        // Set the local data to search through +        settings.local_data = url_or_data; +    } + +    // Build class names +    if(settings.classes) { +        // Use custom class names +        settings.classes = $.extend({}, DEFAULT_CLASSES, settings.classes); +    } else if(settings.theme) { +        // Use theme-suffixed default class names +        settings.classes = {}; +        $.each(DEFAULT_CLASSES, function(key, value) { +            settings.classes[key] = value + "-" + settings.theme; +        }); +    } else { +        settings.classes = DEFAULT_CLASSES; +    } + + +    // Save the tokens +    var saved_tokens = []; + +    // Keep track of the number of tokens in the list +    var token_count = 0; + +    // Basic cache to save on db hits +    var cache = new $.TokenList.Cache(); + +    // Keep track of the timeout, old vals +    var timeout; +    var input_val; + +    // Create a new text input an attach keyup events +    var input_box = $("<input type=\"text\"  autocomplete=\"off\">") +        .css({ +            outline: "none" +        }) +        .attr("id", settings.idPrefix + input.id) +        .focus(function () { +            if (settings.tokenLimit === null || settings.tokenLimit !== token_count) { +                show_dropdown_hint(); +            } +        }) +        .blur(function () { +            hide_dropdown(); +            $(this).val(""); +        }) +        .bind("keyup keydown blur update", resize_input) +        .keydown(function (event) { +            var previous_token; +            var next_token; + +            switch(event.keyCode) { +                case KEY.LEFT: +                case KEY.RIGHT: +                case KEY.UP: +                case KEY.DOWN: +                    if(!$(this).val()) { +                        previous_token = input_token.prev(); +                        next_token = input_token.next(); + +                        if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) { +                            // Check if there is a previous/next token and it is selected +                            if(event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) { +                                deselect_token($(selected_token), POSITION.BEFORE); +                            } else { +                                deselect_token($(selected_token), POSITION.AFTER); +                            } +                        } else if((event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) && previous_token.length) { +                            // We are moving left, select the previous token if it exists +                            select_token($(previous_token.get(0))); +                        } else if((event.keyCode === KEY.RIGHT || event.keyCode === KEY.DOWN) && next_token.length) { +                            // We are moving right, select the next token if it exists +                            select_token($(next_token.get(0))); +                        } +                    } else { +                        var dropdown_item = null; + +                        if(event.keyCode === KEY.DOWN || event.keyCode === KEY.RIGHT) { +                            dropdown_item = $(selected_dropdown_item).next(); +                        } else { +                            dropdown_item = $(selected_dropdown_item).prev(); +                        } + +                        if(dropdown_item.length) { +                            select_dropdown_item(dropdown_item); +                        } +                        return false; +                    } +                    break; + +                case KEY.BACKSPACE: +                    previous_token = input_token.prev(); + +                    if(!$(this).val().length) { +                        if(selected_token) { +                            delete_token($(selected_token)); +                            hidden_input.change(); +                        } else if(previous_token.length) { +                            select_token($(previous_token.get(0))); +                        } + +                        return false; +                    } else if($(this).val().length === 1) { +                        hide_dropdown(); +                    } else { +                        // set a timeout just long enough to let this function finish. +                        setTimeout(function(){do_search();}, 5); +                    } +                    break; + +                case KEY.TAB: +                case KEY.ENTER: +                case KEY.NUMPAD_ENTER: +                case KEY.COMMA: +                  if(selected_dropdown_item) { +                    add_token($(selected_dropdown_item).data("tokeninput")); +                    hidden_input.change(); +                    return false; +                  } +                  break; + +                case KEY.ESCAPE: +                  hide_dropdown(); +                  return true; + +                default: +                    if(String.fromCharCode(event.which)) { +                        // set a timeout just long enough to let this function finish. +                        setTimeout(function(){do_search();}, 5); +                    } +                    break; +            } +        }); + +    // Keep a reference to the original input box +    var hidden_input = $(input) +                           .hide() +                           .val("") +                           .focus(function () { +                               input_box.focus(); +                           }) +                           .blur(function () { +                               input_box.blur(); +                           }); + +    // Keep a reference to the selected token and dropdown item +    var selected_token = null; +    var selected_token_index = 0; +    var selected_dropdown_item = null; + +    // The list to store the token items in +    var token_list = $("<ul />") +        .addClass(settings.classes.tokenList) +        .click(function (event) { +            var li = $(event.target).closest("li"); +            if(li && li.get(0) && $.data(li.get(0), "tokeninput")) { +                toggle_select_token(li); +            } else { +                // Deselect selected token +                if(selected_token) { +                    deselect_token($(selected_token), POSITION.END); +                } + +                // Focus input box +                input_box.focus(); +            } +        }) +        .mouseover(function (event) { +            var li = $(event.target).closest("li"); +            if(li && selected_token !== this) { +                li.addClass(settings.classes.highlightedToken); +            } +        }) +        .mouseout(function (event) { +            var li = $(event.target).closest("li"); +            if(li && selected_token !== this) { +                li.removeClass(settings.classes.highlightedToken); +            } +        }) +        .insertBefore(hidden_input); + +    // The token holding the input box +    var input_token = $("<li />") +        .addClass(settings.classes.inputToken) +        .appendTo(token_list) +        .append(input_box); + +    // The list to store the dropdown items in +    var dropdown = $("<div>") +        .addClass(settings.classes.dropdown) +        .appendTo("body") +        .hide(); + +    // Magic element to help us resize the text input +    var input_resizer = $("<tester/>") +        .insertAfter(input_box) +        .css({ +            position: "absolute", +            top: -9999, +            left: -9999, +            width: "auto", +            fontSize: input_box.css("fontSize"), +            fontFamily: input_box.css("fontFamily"), +            fontWeight: input_box.css("fontWeight"), +            letterSpacing: input_box.css("letterSpacing"), +            whiteSpace: "nowrap" +        }); + +    // Pre-populate list if items exist +    hidden_input.val(""); +    var li_data = settings.prePopulate || hidden_input.data("pre"); +    if(settings.processPrePopulate && $.isFunction(settings.onResult)) { +        li_data = settings.onResult.call(hidden_input, li_data); +    } +    if(li_data && li_data.length) { +        $.each(li_data, function (index, value) { +            insert_token(value); +            checkTokenLimit(); +        }); +    } + +    // Initialization is done +    if($.isFunction(settings.onReady)) { +        settings.onReady.call(); +    } + +    // +    // Public functions +    // + +    this.clear = function() { +        token_list.children("li").each(function() { +            if ($(this).children("input").length === 0) { +                delete_token($(this)); +            } +        }); +    } + +    this.add = function(item) { +        add_token(item); +    } + +    this.remove = function(item) { +        token_list.children("li").each(function() { +            if ($(this).children("input").length === 0) { +                var currToken = $(this).data("tokeninput"); +                var match = true; +                for (var prop in item) { +                    if (item[prop] !== currToken[prop]) { +                        match = false; +                        break; +                    } +                } +                if (match) { +                    delete_token($(this)); +                } +            } +        }); +    } +     +    this.getTokens = function() { +   		return saved_tokens; +   	} + +    // +    // Private functions +    // + +    function checkTokenLimit() { +        if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) { +            input_box.hide(); +            hide_dropdown(); +            return; +        } +    } + +    function resize_input() { +        if(input_val === (input_val = input_box.val())) {return;} + +        // Enter new content into resizer and resize input accordingly +        var escaped = input_val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>'); +        input_resizer.html(escaped); +        input_box.width(input_resizer.width() + 30); +    } + +    function is_printable_character(keycode) { +        return ((keycode >= 48 && keycode <= 90) ||     // 0-1a-z +                (keycode >= 96 && keycode <= 111) ||    // numpad 0-9 + - / * . +                (keycode >= 186 && keycode <= 192) ||   // ; = , - . / ^ +                (keycode >= 219 && keycode <= 222));    // ( \ ) ' +    } + +    // Inner function to a token to the list +    function insert_token(item) { +        var this_token = settings.tokenFormatter(item); +        this_token = $(this_token) +          .addClass(settings.classes.token) +          .insertBefore(input_token); + +        // The 'delete token' button +        $("<span>" + settings.deleteText + "</span>") +            .addClass(settings.classes.tokenDelete) +            .appendTo(this_token) +            .click(function () { +                delete_token($(this).parent()); +                hidden_input.change(); +                return false; +            }); + +        // Store data on the token +        var token_data = {"id": item.id}; +        token_data[settings.propertyToSearch] = item[settings.propertyToSearch]; +        $.data(this_token.get(0), "tokeninput", item); + +        // Save this token for duplicate checking +        saved_tokens = saved_tokens.slice(0,selected_token_index).concat([token_data]).concat(saved_tokens.slice(selected_token_index)); +        selected_token_index++; + +        // Update the hidden input +        update_hidden_input(saved_tokens, hidden_input); + +        token_count += 1; + +        // Check the token limit +        if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) { +            input_box.hide(); +            hide_dropdown(); +        } + +        return this_token; +    } + +    // Add a token to the token list based on user input +    function add_token (item) { +        var callback = settings.onAdd; + +        // See if the token already exists and select it if we don't want duplicates +        if(token_count > 0 && settings.preventDuplicates) { +            var found_existing_token = null; +            token_list.children().each(function () { +                var existing_token = $(this); +                var existing_data = $.data(existing_token.get(0), "tokeninput"); +                if(existing_data && existing_data.id === item.id) { +                    found_existing_token = existing_token; +                    return false; +                } +            }); + +            if(found_existing_token) { +                select_token(found_existing_token); +                input_token.insertAfter(found_existing_token); +                input_box.focus(); +                return; +            } +        } + +        // Insert the new tokens +        if(settings.tokenLimit == null || token_count < settings.tokenLimit) { +            insert_token(item); +            checkTokenLimit(); +        } + +        // Clear input box +        input_box.val(""); + +        // Don't show the help dropdown, they've got the idea +        hide_dropdown(); + +        // Execute the onAdd callback if defined +        if($.isFunction(callback)) { +            callback.call(hidden_input,item); +        } +    } + +    // Select a token in the token list +    function select_token (token) { +        token.addClass(settings.classes.selectedToken); +        selected_token = token.get(0); + +        // Hide input box +        input_box.val(""); + +        // Hide dropdown if it is visible (eg if we clicked to select token) +        hide_dropdown(); +    } + +    // Deselect a token in the token list +    function deselect_token (token, position) { +        token.removeClass(settings.classes.selectedToken); +        selected_token = null; + +        if(position === POSITION.BEFORE) { +            input_token.insertBefore(token); +            selected_token_index--; +        } else if(position === POSITION.AFTER) { +            input_token.insertAfter(token); +            selected_token_index++; +        } else { +            input_token.appendTo(token_list); +            selected_token_index = token_count; +        } + +        // Show the input box and give it focus again +        input_box.focus(); +    } + +    // Toggle selection of a token in the token list +    function toggle_select_token(token) { +        var previous_selected_token = selected_token; + +        if(selected_token) { +            deselect_token($(selected_token), POSITION.END); +        } + +        if(previous_selected_token === token.get(0)) { +            deselect_token(token, POSITION.END); +        } else { +            select_token(token); +        } +    } + +    // Delete a token from the token list +    function delete_token (token) { +        // Remove the id from the saved list +        var token_data = $.data(token.get(0), "tokeninput"); +        var callback = settings.onDelete; + +        var index = token.prevAll().length; +        if(index > selected_token_index) index--; + +        // Delete the token +        token.remove(); +        selected_token = null; + +        // Show the input box and give it focus again +        input_box.focus(); + +        // Remove this token from the saved list +        saved_tokens = saved_tokens.slice(0,index).concat(saved_tokens.slice(index+1)); +        if(index < selected_token_index) selected_token_index--; + +        // Update the hidden input +        update_hidden_input(saved_tokens, hidden_input); + +        token_count -= 1; + +        if(settings.tokenLimit !== null) { +            input_box +                .show() +                .val("") +                .focus(); +        } + +        // Execute the onDelete callback if defined +        if($.isFunction(callback)) { +            callback.call(hidden_input,token_data); +        } +    } + +    // Update the hidden input box value +    function update_hidden_input(saved_tokens, hidden_input) { +        var token_values = $.map(saved_tokens, function (el) { +            return el[settings.tokenValue]; +        }); +        hidden_input.val(token_values.join(settings.tokenDelimiter)); + +    } + +    // Hide and clear the results dropdown +    function hide_dropdown () { +        dropdown.hide().empty(); +        selected_dropdown_item = null; +    } + +    function show_dropdown() { +        dropdown +            .css({ +                position: "absolute", +                top: $(token_list).offset().top + $(token_list).outerHeight(), +                left: $(token_list).offset().left, +                zindex: 999 +            }) +            .show(); +    } + +    function show_dropdown_searching () { +        if(settings.searchingText) { +            dropdown.html("<p>"+settings.searchingText+"</p>"); +            show_dropdown(); +        } +    } + +    function show_dropdown_hint () { +        if(settings.hintText) { +            dropdown.html("<p>"+settings.hintText+"</p>"); +            show_dropdown(); +        } +    } + +    // Highlight the query part of the search term +    function highlight_term(value, term) { +        return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<b>$1</b>"); +    } +     +    function find_value_and_highlight_term(template, value, term) { +        return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + value + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term)); +    } + +    // Populate the results dropdown with some results +    function populate_dropdown (query, results) { +        if(results && results.length) { +            dropdown.empty(); +            var dropdown_ul = $("<ul>") +                .appendTo(dropdown) +                .mouseover(function (event) { +                    select_dropdown_item($(event.target).closest("li")); +                }) +                .mousedown(function (event) { +                    add_token($(event.target).closest("li").data("tokeninput")); +                    hidden_input.change(); +                    return false; +                }) +                .hide(); + +            $.each(results, function(index, value) { +                var this_li = settings.resultsFormatter(value); +                 +                this_li = find_value_and_highlight_term(this_li ,value[settings.propertyToSearch], query);             +                 +                this_li = $(this_li).appendTo(dropdown_ul); +                 +                if(index % 2) { +                    this_li.addClass(settings.classes.dropdownItem); +                } else { +                    this_li.addClass(settings.classes.dropdownItem2); +                } + +                if(index === 0) { +                    select_dropdown_item(this_li); +                } + +                $.data(this_li.get(0), "tokeninput", value); +            }); + +            show_dropdown(); + +            if(settings.animateDropdown) { +                dropdown_ul.slideDown("fast"); +            } else { +                dropdown_ul.show(); +            } +        } else { +            if(settings.noResultsText) { +                dropdown.html("<p>"+settings.noResultsText+"</p>"); +                show_dropdown(); +            } +        } +    } + +    // Highlight an item in the results dropdown +    function select_dropdown_item (item) { +        if(item) { +            if(selected_dropdown_item) { +                deselect_dropdown_item($(selected_dropdown_item)); +            } + +            item.addClass(settings.classes.selectedDropdownItem); +            selected_dropdown_item = item.get(0); +        } +    } + +    // Remove highlighting from an item in the results dropdown +    function deselect_dropdown_item (item) { +        item.removeClass(settings.classes.selectedDropdownItem); +        selected_dropdown_item = null; +    } + +    // Do a search and show the "searching" dropdown if the input is longer +    // than settings.minChars +    function do_search() { +        var query = input_box.val().toLowerCase(); + +        if(query && query.length) { +            if(selected_token) { +                deselect_token($(selected_token), POSITION.AFTER); +            } + +            if(query.length >= settings.minChars) { +                show_dropdown_searching(); +                clearTimeout(timeout); + +                timeout = setTimeout(function(){ +                    run_search(query); +                }, settings.searchDelay); +            } else { +                hide_dropdown(); +            } +        } +    } + +    // Do the actual search +    function run_search(query) { +        var cache_key = query + computeURL(); +        var cached_results = cache.get(cache_key); +        if(cached_results) { +            populate_dropdown(query, cached_results); +        } else { +            // Are we doing an ajax search or local data search? +            if(settings.url) { +                var url = computeURL(); +                // Extract exisiting get params +                var ajax_params = {}; +                ajax_params.data = {}; +                if(url.indexOf("?") > -1) { +                    var parts = url.split("?"); +                    ajax_params.url = parts[0]; + +                    var param_array = parts[1].split("&"); +                    $.each(param_array, function (index, value) { +                        var kv = value.split("="); +                        ajax_params.data[kv[0]] = kv[1]; +                    }); +                } else { +                    ajax_params.url = url; +                } + +                // Prepare the request +                ajax_params.data[settings.queryParam] = query; +                ajax_params.type = settings.method; +                ajax_params.dataType = settings.contentType; +                if(settings.crossDomain) { +                    ajax_params.dataType = "jsonp"; +                } + +                // Attach the success callback +                ajax_params.success = function(results) { +                  if($.isFunction(settings.onResult)) { +                      results = settings.onResult.call(hidden_input, results); +                  } +                  cache.add(cache_key, settings.jsonContainer ? results[settings.jsonContainer] : results); + +                  // only populate the dropdown if the results are associated with the active search query +                  if(input_box.val().toLowerCase() === query) { +                      populate_dropdown(query, settings.jsonContainer ? results[settings.jsonContainer] : results); +                  } +                }; + +                // Make the request +                $.ajax(ajax_params); +            } else if(settings.local_data) { +                // Do the search through local data +                var results = $.grep(settings.local_data, function (row) { +                    return row[settings.propertyToSearch].toLowerCase().indexOf(query.toLowerCase()) > -1; +                }); + +                if($.isFunction(settings.onResult)) { +                    results = settings.onResult.call(hidden_input, results); +                } +                cache.add(cache_key, results); +                populate_dropdown(query, results); +            } +        } +    } + +    // compute the dynamic URL +    function computeURL() { +        var url = settings.url; +        if(typeof settings.url == 'function') { +            url = settings.url.call(); +        } +        return url; +    } +}; + +// Really basic cache for the results +$.TokenList.Cache = function (options) { +    var settings = $.extend({ +        max_size: 500 +    }, options); + +    var data = {}; +    var size = 0; + +    var flush = function () { +        data = {}; +        size = 0; +    }; + +    this.add = function (query, results) { +        if(size > settings.max_size) { +            flush(); +        } + +        if(!data[query]) { +            size += 1; +        } + +        data[query] = results; +    }; + +    this.get = function (query) { +        return data[query]; +    }; +}; +}(jQuery)); diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index fc25b5723..b17893104 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -3,5 +3,6 @@   * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at   * the top of the compiled file, but it's generally better to create a new file per style scope.   *= require_self + *= require jquery-ui   *= require_tree .   */
\ No newline at end of file diff --git a/app/assets/stylesheets/connection_links.css.scss b/app/assets/stylesheets/connection_links.css.scss new file mode 100644 index 000000000..e3aedc918 --- /dev/null +++ b/app/assets/stylesheets/connection_links.css.scss @@ -0,0 +1,40 @@ +// Place all the styles related to the lines controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ +@import "common"; + +#workspace.connection_links.index +{ +    .connection_link:after {  +        @include after_div_for_object;   +    } + +    .connection_links { +        margin-top: 20px; +    } + +    .connection_links:after { +        @include content_to_clear; +    } +     +    .connection_link { +        @include div_for_object; + +        /* to create multi-column index */ +        width: 350px; +        float: left; +        padding-right: 10px; +    } +} + + +#workspace.connection_links.show +{ + +    .summary p label { +        font-weight: bold; +    } +}         + + + diff --git a/app/assets/stylesheets/layout.css.scss b/app/assets/stylesheets/layout.css.scss index 335c5b61b..21640e266 100644 --- a/app/assets/stylesheets/layout.css.scss +++ b/app/assets/stylesheets/layout.css.scss @@ -32,6 +32,16 @@ $text_color: #222;  #map {      float: right; -    width: 600px; +    width: 400px;      height: 400px; +} + +.actions { +    a.add_children { +        background: url(image-path('user_interface/ui/add.png')) no-repeat; +    } + +    a.select_parent { +        background: url(image-path('icons/select_parent.png')) no-repeat; +    }  }
\ No newline at end of file diff --git a/app/assets/stylesheets/pagination.css.scss b/app/assets/stylesheets/pagination.css.scss index 76ff3cb8f..222ab861b 100644 --- a/app/assets/stylesheets/pagination.css.scss +++ b/app/assets/stylesheets/pagination.css.scss @@ -1,52 +1,50 @@  .pagination { +  background: white;    cursor: default; - -  margin: 10px 0; - -  > a, > span, > em { -    padding: 0.2em 0.5em; -    display: block; -    float: left; -    margin-right: 1px; -  } - -  > .disabled{ -    color: #999999; -    /* border: 1px solid #dddddd; */ -  } -   -  > .current{ -    font-style: normal; -    font-weight: bold; -    background: #61970b; -    color: white; -    border: 1px solid #61970b; -  } - -  > a{ -    text-decoration: none; -    color: #61970b; -    border: 1px solid #ddd; -    &:hover, &:focus{ +  margin-top: 20px; +  +  /* self-clearing method: */ +  a, span, em { +      padding: 0.2em 0.5em; +      display: block; +      float: left; +      margin-right: 1px; } +  .disabled { +      color: #999999; +      border: 1px solid #dddddd; } +  .current { +      font-style: normal; +      font-weight: bold; +      background: #61970b; +      color: white; +      border: 1px solid #61970b; } +  a { +      text-decoration: none;        color: #86b41d; -      border-color: #86b41d; -    } -  } - -  .paginated_content {       -      padding: 0.4em 0.6em -  } - -  &:after{ +      border: 1px solid #86b41d; } +  a:hover,  a:focus { +      color: #000033; +      border-color: #000033; } +  .page_info { +      background: #61970b; +      color: white; +      padding: 0.4em 0.6em; +      width: 22em; +      margin-bottom: 0.3em; +      text-align: center; } +  .page_info b { +      color: #000033; +      background: #86b41d; +      padding: 0.1em 0.25em; } +} + +.pagination:after {      content: ".";      display: block;      height: 0;      clear: both; -    visibility: hidden;} - -  * html & { -    height: 1%;} - -  *:first-child+html & { -    overflow: hidden;} -}
\ No newline at end of file +    visibility: hidden; } +* html .pagination{ +    height: 1%; } +*:first-child + html .pagination { +    overflow: hidden; }
\ No newline at end of file diff --git a/app/assets/stylesheets/stop_areas.css.scss b/app/assets/stylesheets/stop_areas.css.scss index 60fba8749..b837f4f15 100644 --- a/app/assets/stylesheets/stop_areas.css.scss +++ b/app/assets/stylesheets/stop_areas.css.scss @@ -101,5 +101,12 @@      }  } +#workspace.stop_areas.select_parent +{ +    .token-input-list{ +        display: inline-block; +    } +} + diff --git a/app/assets/stylesheets/token-input.css b/app/assets/stylesheets/token-input.css new file mode 100644 index 000000000..03bb01c4d --- /dev/null +++ b/app/assets/stylesheets/token-input.css @@ -0,0 +1,113 @@ +/* Example tokeninput style #1: Token vertical list*/ +ul.token-input-list { +    overflow: hidden;  +    height: auto !important;  +    height: 1%; +    width: 400px; +    border: 1px solid #999; +    cursor: text; +    font-size: 12px; +    font-family: Verdana; +    z-index: 999; +    margin: 0; +    padding: 0; +    background-color: #fff; +    list-style-type: none; +    clear: left; +} + +ul.token-input-list li { +    list-style-type: none; +} + +ul.token-input-list li input { +    border: 0; +    width: 350px; +    padding: 3px 8px; +    background-color: white; +    -webkit-appearance: caret; +} + +li.token-input-token { +    overflow: hidden;  +    height: auto !important;  +    height: 1%; +    margin: 3px; +    padding: 3px 5px; +    background-color: #d0efa0; +    color: #000; +    font-weight: bold; +    cursor: default; +    display: block; +} + +li.token-input-token p { +    float: left; +    padding: 0; +    margin: 0; +} + +li.token-input-token span { +    float: right; +    color: #777; +    cursor: pointer; +} + +li.token-input-selected-token { +    background-color: #08844e; +    color: #fff; +} + +li.token-input-selected-token span { +    color: #bbb; +} + +div.token-input-dropdown { +    position: absolute; +    width: 400px; +    background-color: #fff; +    overflow: hidden; +    border-left: 1px solid #ccc; +    border-right: 1px solid #ccc; +    border-bottom: 1px solid #ccc; +    cursor: default; +    font-size: 12px; +    font-family: Verdana; +    z-index: 1; +} + +div.token-input-dropdown p { +    margin: 0; +    padding: 5px; +    font-weight: bold; +    color: #777; +} + +div.token-input-dropdown ul { +    margin: 0; +    padding: 0; +} + +div.token-input-dropdown ul li { +    background-color: #fff; +    padding: 3px; +    list-style-type: none; +} + +div.token-input-dropdown ul li.token-input-dropdown-item { +    background-color: #fafafa; +} + +div.token-input-dropdown ul li.token-input-dropdown-item2 { +    background-color: #fff; +} + +div.token-input-dropdown ul li em { +    font-weight: bold; +    font-style: normal; +} + +div.token-input-dropdown ul li.token-input-selected-dropdown-item { +    background-color: #d0efa0; +} + diff --git a/app/controllers/connection_links_controller.rb b/app/controllers/connection_links_controller.rb new file mode 100644 index 000000000..327fb7989 --- /dev/null +++ b/app/controllers/connection_links_controller.rb @@ -0,0 +1,27 @@ +class ConnectionLinksController < ChouetteController +  defaults :resource_class => Chouette::ConnectionLink + +  belongs_to :referential do +    #belongs_to :departure, :parent_class => Chouette::StopArea, :optional => false +    #belongs_to :arrival, :parent_class => Chouette::StopArea, :optional => false +  end + +  respond_to :html, :xml, :json + + +  protected + +  def collection     +    @q = referential.connection_links.search(params[:q]) +    @connection_links ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page], :per_page => 10) +  end + +  def resource_url(connection_link = nil) +    referential_connection_link_path(referential, connection_link || resource) +  end + +  def collection_url +    referential_connection_links_path(referential) +  end + +end diff --git a/app/controllers/stop_area_parents_controller.rb b/app/controllers/stop_area_parents_controller.rb new file mode 100644 index 000000000..526c1cd42 --- /dev/null +++ b/app/controllers/stop_area_parents_controller.rb @@ -0,0 +1,21 @@ +class StopAreaParentsController < ChouetteController + +  respond_to :json, :only => :index + +  def index +    respond_to do |format|   +      format.json { render :json => parents_maps }   +    end   +  end + +  def parents_maps +    parents.collect do |parent| +      { :id => parent.id.to_s, :name => "#{parent.name} #{parent.country_code}" } +    end +  end + +  def parents  +    referential.stop_areas.find(params[:stop_area_id]).possible_parents.select{ |p| p.name =~ /#{params[:q]}/i  }        +  end + +end diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index baca38598..98111a804 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -13,6 +13,20 @@ class StopAreasController < ChouetteController    #   render :layout => false    # end +  def select_parent +    @stop_area = stop_area +    @parent = stop_area.parent +  end + +  def add_children +    @stop_area = stop_area +  end +   +  def possible_children +    @possible_children= stop_area.possible_children +    render :layout => false +  end +    def index           request.format.kml? ? @per_page = nil : @per_page = 10      index! @@ -39,7 +53,7 @@ class StopAreasController < ChouetteController    end    protected - +      alias_method :stop_area, :resource    def collection diff --git a/app/models/referential.rb b/app/models/referential.rb index dd5908b8b..8faeea170 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -21,6 +21,10 @@ class Referential < ActiveRecord::Base    def time_tables      Chouette::TimeTable.scoped    end +   +  def connection_links +    Chouette::ConnectionLink.scoped +  end    def switch      raise "Referential not created" if new_record? diff --git a/app/views/companies/index.html.erb b/app/views/companies/index.html.erb index b6ed91aff..257e1a945 100644 --- a/app/views/companies/index.html.erb +++ b/app/views/companies/index.html.erb @@ -8,11 +8,19 @@    <%= link_to t("cancel"), referential_companies_path(@referential) %>  <% end %> -<%= will_paginate @companies %> +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @companies %> +  </div> +  <%= will_paginate @companies, :container => false %> +</div>  <div class="companies paginated_content">    <%= render :partial => "company", :collection => @companies %>  </div> -<%= will_paginate @companies %> +<div class="pagination"> +  <%= will_paginate @companies, :container => false %> +</div> +  <% content_for :sidebar do %> diff --git a/app/views/connection_links/_connection_link.erb b/app/views/connection_links/_connection_link.erb new file mode 100644 index 000000000..04ed2e833 --- /dev/null +++ b/app/views/connection_links/_connection_link.erb @@ -0,0 +1,22 @@ +<%= div_for(connection_link) do %> +  <%= link_to truncate(connection_link.name, :length => 30), [@referential, connection_link], :title => "Correspondance #{connection_link.name}" %> +  <div class="info"> +  	<%= connection_link.human_attribute_name('departure') %>  +    <% if connection_link.departure.present? %>  +      <%= link_to_if connection_link.departure, connection_link.departure.name, referential_stop_area_path(@referential, connection_link.departure), :title => "#{connection_link.human_attribute_name('departure')} #{connection_link.departure.name}" %> +    <% else %> +      <%= connection_link.human_attribute_name("undefined") %> +    <% end %> +     - <%= connection_link.human_attribute_name('arrival') %>  +    <% if connection_link.arrival.present? %>  +      <%= link_to_if( connection_link.arrival, connection_link.arrival.name, referential_stop_area_path(@referential, connection_link.arrival), :title => "#{connection_link.human_attribute_name('arrival')} #{connection_link.arrival.name}" )  %> +    <% else %> +      <%= connection_link.human_attribute_name("undefined") %> +    <% end %> + +    <div class="actions">   +      <%= link_to t("actions.edit"), edit_referential_connection_link_path(@referential, connection_link), :class => "edit" %> | +      <%= link_to t("actions.destroy"), referential_connection_link_path(@referential, connection_link), :method => :delete, :confirm =>  t('connection_links.actions.destroy_confirm'), :class => "remove" %> +    </div> +  </div> +<% end %> diff --git a/app/views/connection_links/_form.erb b/app/views/connection_links/_form.erb new file mode 100644 index 000000000..31777c253 --- /dev/null +++ b/app/views/connection_links/_form.erb @@ -0,0 +1,22 @@ +<!-- <%= @connection_link.errors.inspect %> --> +<%= semantic_form_for [@referential, @connection_link] do |form| %> +  <%= form.inputs do %>  +    <%= form.input :name %> +    <%= form.input :connection_link_type, :as => :select, :collection => Chouette::ConnectionLink.connection_link_types, :include_blank => false, :member_label => Proc.new { |type| t("connection_link_types.label.#{type}") }  %> +    <%= form.input :comment %>               +    <% if @connection_link.new_record? %> +      <%= form.input :objectid %>   +    <% else %> +      <li> +      <label><%= @connection_link.human_attribute_name("objectid") %>: </label> +      <%= @connection_link.objectid %> +      </li> +    <% end %> +  <% end %> + +  <%= form.buttons do %> +    <%= form.commit_button true %> +    <li><%= t('or') %></li> +    <li><%= link_to t('cancel'), :back %></li> +  <% end %> +<% end %> diff --git a/app/views/connection_links/edit.html.erb b/app/views/connection_links/edit.html.erb new file mode 100644 index 000000000..77200420b --- /dev/null +++ b/app/views/connection_links/edit.html.erb @@ -0,0 +1,3 @@ +<%= title_tag t('connection_links.edit.title', :connection_link => @connection_link.name ) %> + +<%= render "form" %> diff --git a/app/views/connection_links/index.html.erb b/app/views/connection_links/index.html.erb new file mode 100644 index 000000000..8b9fc04fa --- /dev/null +++ b/app/views/connection_links/index.html.erb @@ -0,0 +1,48 @@ +<%= title_tag t('connection_links.index.title') %>  + +<%= search_form_for @q, :url => referential_connection_links_path(@referential), :html => {:method => :get} do |f| %> +  <%= f.label :name_cont, "#{t('.name')} :" %> +  <%= f.text_field :name_cont %> + +<!-- +  <%= f.hidden_field :departure_id_eq %> +  <%= f.hidden_field :arrival_id_eq %> +--> + +  <%= f.submit t('actions.search') %> <%= t("or") %> +  <%= link_to t("cancel"), referential_connection_links_path(@referential) %> +<% end %> + +<!-- +<% if @q.departure_id_eq.present? %> +<p> +  <%= Chouette::ConnectionLink.human_attribute_name('departure') %> : <%= @referential.stop_areas.find(@q.departure_id_eq).name %> +</p> +<% end %> + +<% if @q.arrival_id_eq.present? %> +<p> +  <%= Chouette::ConnectionLink.human_attribute_name('arrival') %> : <%= @referential.stop_areas.find(@q.arrival_id_eq).name %> +</p> +<% end %> +--> + +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @connection_links %> +  </div> +  <%= will_paginate @connection_links, :container => false %> +</div> +<div class="connection_links paginated_content"> +  <%= render :partial => "connection_link", :collection => @connection_links %> +</div> +<div class="pagination"> +  <%= will_paginate @connection_links, :container => false %> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to t('connection_links.actions.new'), new_referential_connection_link_path(@referential), :class => "add" %></li>  +</ul> + +<% end %> diff --git a/app/views/connection_links/new.html.erb b/app/views/connection_links/new.html.erb new file mode 100644 index 000000000..bd098adc0 --- /dev/null +++ b/app/views/connection_links/new.html.erb @@ -0,0 +1,3 @@ +<%= title_tag  t('connection_links.new.title') %> + +<%= render "form" %> diff --git a/app/views/connection_links/show.html.erb b/app/views/connection_links/show.html.erb new file mode 100644 index 000000000..69aad91ea --- /dev/null +++ b/app/views/connection_links/show.html.erb @@ -0,0 +1,55 @@ +<%= title_tag t('connection_links.show.title', :connection_link => @connection_link.name ) %> + +<div class="connection_link_show"> + +  <div class="summary"> +    <p> +      <label><%= @connection_link.human_attribute_name(:departure) %>: </label> +      <% if @connection_link.departure.present? %>  +        <%= link_to @connection_link.departure.name, [@referential, @connection_link.departure] %> +      <% else %> +         <%= @connection_link.human_attribute_name("undefined") %>   +      <% end %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name(:arrival) %>: </label> +      <% if @connection_link.arrival.present? %>  +         <%= link_to @connection_link.arrival.name, [@referential, @connection_link.arrival] %> +      <% else %> +         <%= @connection_link.human_attribute_name("undefined") %>   +      <% end %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name("name") %>: </label> +      <%= @connection_link.name %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name("connection_link_type") %>: </label> +      <%= t("connection_link_types.label.#{@connection_link.connection_link_type}") %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name("comment") %>: </label> +      <%= @connection_link.comment %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name("objectid") %>: </label> +      <%= @connection_link.objectid %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name("creation_time") %>: </label> +      <%= @connection_link.creation_time %> +    </p> +    <p> +      <label><%= @connection_link.human_attribute_name("creator_id") %>: </label> +      <%= @connection_link.creator_id %> +    </p> +  </div> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to t('connection_links.actions.edit'), edit_referential_connection_link_path(@referential, @connection_link), :class => "edit" %></li> +  <li><%= link_to  t('connection_links.actions.destroy'), referential_connection_link_path(@referential, @connection_link), :method => :delete, :confirm =>  t('connection_links.actions.destroy_confirm'), :class => "remove" %></li> +  <br> +</ul> +<% end %> diff --git a/app/views/help/companies.textile b/app/views/help/companies.textile index c1db6f4d3..07d7789c5 100644 --- a/app/views/help/companies.textile +++ b/app/views/help/companies.textile @@ -9,7 +9,7 @@ Dans la réalité, le transporteur est l'entité en charge de  Ce principe se retrouve dans ce logiciel.   * Il s'agit de l'exploitant de la ligne; chaque ligne est rattachée à un seul transporteur, un transporteur pouvant évidemment gérer plusieurs lignes.  -* Chaque transporteur dispose d'un identifiant fonctionnel (« numéro d'enregistrement ») qui est utilisé dans les échanges XML pour identifier le transporteur et le mettre à jour. Cet identifiant est unique pour toute la base CHOUETTE, quel que soit le réseau ; il est donc important que le gestionnaire de la base CHOUETTE le renseigne d'une manière bien définie et pérenne. +* Chaque transporteur dispose d'un identifiant fonctionnel (« numéro d'enregistrement ») qui est utilisé dans les échanges XML pour identifier le transporteur et le mettre à jour. Cet identifiant est unique pour toute la base CHOUETTE, quel que soit le réseau ; il est donc important que le gestionnaire de la base CHOUETTE le renseigne d'une manière bien définie et pérenne.  h3. Attributs @@ -32,7 +32,7 @@ cet identifiant est composé de 3 parties : préfixe:type:id_techniq  * type = Company : clé identifiant le type d'objet (valeur imposée)  * id_technique : valeur identifiant un seul object d'un type donné pour un même producteur  ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  -il est possible aussi de ne renseigner que le préfixe auquel cas la valeur sera complétée automatiquement. +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement.  =:  - Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois  - Version := version de l'objet (auto incrémenté à chaque modification) diff --git a/app/views/help/connection_links.textile b/app/views/help/connection_links.textile new file mode 100644 index 000000000..941918e2d --- /dev/null +++ b/app/views/help/connection_links.textile @@ -0,0 +1,46 @@ +--- +layout: default +title: Correspondances +--- + +h3. Définition + +Une correspondance ou un changement est, dans un voyage en transports en commun, une étape nécessitant de changer de ligne. Le changement peut se faire soit au sein du même réseau, soit de manière intermodale, c'est-à-dire en changeant également de mode de transport. +La correspondance permet d'établir une liaison entre un arrêt physique (ou une zone d'arrêt de type « arrêt commercial » ou de type « pôle d'échange ») et un autre arrêt physique (ou une autre zone d'arrêt de type « arrêt commercial » ou de type « pôle d'échange »). +Cette liaison définit aussi une durée de parcours entre les arrêts (ou zones) reliés. + +h3. Attributs + +- Nom := nom de la correspondances +- Commentaire := zone de texte libre +- Distance := distance en mètres +- Type := liste de choix parmi « Aérien », « Souterrain» ou mixte « Aérien et souterrain » +- Départ := arrêt de départ de la correspondance +- Arrivée := arrêt d'arrivée de la correspondance +- Durée moyenne := champ de type horaire hh:mm +- Durée pour un voyageur à mobilité réduite := champ de type horaire hh:mm +- Durée pour un voyageur occasionnel := champ de type horaire hh:mm +- Durée pour un habitué := champ de type horaire hh:mm +- Ascenseur := indicateur (Oui ou Non) +- Accès pour personne à mobilité réduite := indicateur (Oui ou Non) +- Escalator disponible := indicateur (Oui ou Non) + +p(attr_data). Données de gestion : + +- Identifiant Neptune :=  +clé unique pérenne identifiant la correspondance pour les échanges Neptune +cet identifiant est composé de 3 parties : préfixe:type:id_technique +* préfixe : clé identifiant un producteur de données unique +* type = ConnectionLink : clé identifiant le type d'objet (valeur imposée) +* id_technique : valeur identifiant un seul object d'un type donné pour un même producteur +ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement. +=: +- Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois +- Version := version de l'objet (auto incrémenté à chaque modification) +- Créé par := compte utilisateur ayant procédé à la dernière modification + +h3. Implémentation + +p. TODO + diff --git a/app/views/help/index.textile b/app/views/help/index.textile index c3b5ee2bd..a5e488cca 100644 --- a/app/views/help/index.textile +++ b/app/views/help/index.textile @@ -3,7 +3,7 @@ layout: default  title: Présentation  --- -Chouette v2 : itération 4 du 16/04/2012 +Chouette v2 : itération 5 du 07/05/2012  Cette itération présente les formulaires de : @@ -12,16 +12,20 @@ Cette itération présente les formulaires de :  * lignes  * arrêts  * calendriers d'application +* correspondances +* séquences d'arrêts  l'avancement actuel permet de :   * créer, modifier et supprimer les objets  * consulter les cartes +* déplacer un arrêt depuis la carte (voir mode opératoire dans l'aide des arrêts) +* associer les arrêts à leurs parents  les action suivantes ne sont pas encore disponible :  -* déplacer un arrêt depuis la carte  * afficher le fond Géoportail  * ajouter ou supprimer des dates et des périodes aux calendriers -* associer les arrêts à leurs parents +* associer des arrêts à une séquences d'arrêts  * associer une ITL à une ligne + diff --git a/app/views/help/lines.textile b/app/views/help/lines.textile index 9997c0d50..78348896f 100644 --- a/app/views/help/lines.textile +++ b/app/views/help/lines.textile @@ -34,7 +34,7 @@ cet identifiant est composé de 3 parties : préfixe:type:id_techniq  * type = Line : clé identifiant le type d'objet (valeur imposée)  * id_technique : valeur identifiant un seul object d'un type donné pour un même producteur  ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  -il est possible aussi de ne renseigner que le préfixe auquel cas la valeur sera complétée automatiquement. +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement.  =:  - Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois  - Version := version de l'objet (auto incrémenté à chaque modification) diff --git a/app/views/help/networks.textile b/app/views/help/networks.textile index 424808f48..2a2de2309 100644 --- a/app/views/help/networks.textile +++ b/app/views/help/networks.textile @@ -29,7 +29,7 @@ cet identifiant est composé de 3 parties : préfixe:type:id_techniq  * type = GroupOfLine : clé identifiant le type d'objet (valeur imposée)  * id_technique : valeur identifiant un seul object d'un type donné pour un même producteur  ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  -il est possible aussi de ne renseigner que le préfixe auquel cas la valeur sera complétée automatiquement. +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement.  =:  - Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois  - Version := version de l'objet (auto incrémenté à chaque modification) diff --git a/app/views/help/normalisation.textile b/app/views/help/normalisation.textile index 2790d5320..6d7793eb4 100644 --- a/app/views/help/normalisation.textile +++ b/app/views/help/normalisation.textile @@ -21,7 +21,7 @@ Ces spécifications d'échange couvrent l'information VP et TC, th&e  * un modèle de données orienté objets décrit en UML, reprenant pour ce qui concerne les transports publics, le modèle conceptuel de données Transmodel V4.0, normalisé au niveau européen ;   * un format d'échange XML spécifié sous forme de schémas XSD.  -Les spécifications TRIDENT ont été implémentées dans plusieurs pays européens, et en France ont été mises en œuvre par la RATP pour son système d'information sur les situations perturbées SIPRE, et également pour les échanges d'information au niveau francilien en cours entre les systèmes de la RATP et du STIF, pour ce qui concerne l'information théorique. +Les spécifications TRIDENT ont été implémentées dans plusieurs pays européens, et en France ont été mises en &œlig;uvre par la RATP pour son système d'information sur les situations perturbées SIPRE, et également pour les échanges d'information au niveau francilien en cours entre les systèmes de la RATP et du STIF, pour ce qui concerne l'information théorique.  Le travail du groupe GT7 a abouti à des spécifications de profil d'échange TRIDENT / Chouette en 2006, qui ont servi de référence pour implémenter le logiciel CHOUETTE et sont utilisées depuis lors par plusieurs projets de SIM en France. diff --git a/app/views/help/routes.textile b/app/views/help/routes.textile new file mode 100644 index 000000000..30234c492 --- /dev/null +++ b/app/views/help/routes.textile @@ -0,0 +1,38 @@ +--- +layout: default +title: Séquence d'arrêts +--- + +h3. Définition + +La séquence d'arrêts est une sélection ordonnée de références aux points d'arrêt (exemple: itinéraires aller et retour d'une ligne). Une séquence d'arrêts est spécifique à une ligne; les séquences d'arrêts peuvent référencer des arrêts communs. + +h3. Attributs + +- Nom := nom de la séquence d'arrêts   +- Nom public := nom public pour les voyageurs +- Commentaire := zone de texte libre sur le réseau +- Direction := orientation principale (points cardinaux, circulaire ou aller/retour) +- Indoce := numéro de la séquence d'arrêts +- Sens := aller ou retour +- Itinéraire associé en sens opposé := référence de l'itinéraire de sens opposé associé + +p(attr_data). Données de gestion : + +- Identifiant Neptune :=  +clé unique pérenne identifiant la séquence d'arrêts pour les échanges Neptune +cet identifiant est composé de 3 parties : préfixe:type:id_technique +* préfixe : clé identifiant un producteur de données unique +* type = Route : clé identifiant le type d'objet (valeur imposée) +* id_technique : valeur identifiant un seul object d'un type donné pour un même producteur +ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement. +=: +- Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois +- Version := version de l'objet (auto incrémenté à chaque modification) +- Créé par := compte utilisateur ayant procédé à la dernière modification + +h3. Implémentation + +p. TODO + diff --git a/app/views/help/stop_areas.textile b/app/views/help/stop_areas.textile index 8c468e9f1..94b73c574 100644 --- a/app/views/help/stop_areas.textile +++ b/app/views/help/stop_areas.textile @@ -68,7 +68,7 @@ cet identifiant est composé de 3 parties : préfixe:type:id_techniq  * type = Line : clé identifiant le type d'objet (valeur imposée)  * id_technique : valeur identifiant un seul object d'un type donné pour un même producteur  ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  -il est possible aussi de ne renseigner que le préfixe auquel cas la valeur sera complétée automatiquement. +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement.  =:  - Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois  - Version := version de l'objet (auto incrémenté à chaque modification) diff --git a/app/views/help/timetables.textile b/app/views/help/timetables.textile index 57fe0d50b..6c55e8440 100644 --- a/app/views/help/timetables.textile +++ b/app/views/help/timetables.textile @@ -43,7 +43,7 @@ cet identifiant est composé de 3 parties : préfixe:type:id_techniq  * type = Timetable : clé identifiant le type d'objet (valeur imposée)  * id_technique : valeur identifiant un seul object d'un type donné pour un même producteur  ce champ obligatoire est automatiquement généré s'il n'est pas renseigné  -il est possible aussi de ne renseigner que le préfixe auquel cas la valeur sera complétée automatiquement. +il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera complétée automatiquement.  =:  - Date de création := date à laquelle l'objet a été créé ou modifié pour la dernière fois  - Version := version de l'objet (auto incrémenté à chaque modification) diff --git a/app/views/help/toc.textile b/app/views/help/toc.textile index f4f6998f8..e3ed1ba6f 100644 --- a/app/views/help/toc.textile +++ b/app/views/help/toc.textile @@ -1,6 +1,6 @@  ---  layout: default -title: sommaire +title: Sommaire  ---  h3. Sommaire @@ -11,10 +11,10 @@ h3. Sommaire  # "Réseaux":networks  # "Transporteurs":companies  # "Lignes":lines -## Séquences d'arrêts +## "Séquences d'arrêts":routes  ## Horaires  # "Arrêts":stop_areas -## Correspondances +## "Correspondances":connection_links  ## Accès  ## Liaisons Arrêt-Accès  # "Calendriers d'application":timetables diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 9c48ff00b..d757c92d4 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -41,6 +41,7 @@              <li><%= tab_link_to Chouette::Company, referential_companies_path(@referential) %></li>              <li><%= tab_link_to Chouette::Line, referential_lines_path(@referential) %></li>              <li><%= tab_link_to Chouette::StopArea, referential_stop_areas_path(@referential) %></li> +            <li><%= tab_link_to Chouette::ConnectionLink, referential_connection_links_path(@referential) %></li>              <li><%= tab_link_to Chouette::TimeTable, referential_time_tables_path(@referential) %></li>            <% end %>              </ul> diff --git a/app/views/lines/index.html.erb b/app/views/lines/index.html.erb index 49c6de226..26b97e0b3 100644 --- a/app/views/lines/index.html.erb +++ b/app/views/lines/index.html.erb @@ -23,11 +23,19 @@  </p>  <% end %> -<%= will_paginate @lines %> + +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @lines %> +  </div> +  <%= will_paginate @lines, :container => false %> +</div>  <div class="lines paginated_content">    <%= render :partial => "line", :collection => @lines %>  </div> -<%= will_paginate @lines %> +<div class="pagination"> +  <%= will_paginate @lines, :container => false %> +</div>  <% content_for :sidebar do %>  <ul class="actions"> diff --git a/app/views/networks/index.html.erb b/app/views/networks/index.html.erb index 4514939f1..825bb3dcb 100644 --- a/app/views/networks/index.html.erb +++ b/app/views/networks/index.html.erb @@ -8,12 +8,18 @@    <%= link_to t("cancel"), referential_networks_path(@referential) %>  <% end %> -<%= will_paginate @networks %> +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @networks %> +  </div> +  <%= will_paginate @networks, :container => false %> +</div>  <div class="networks paginated_content">    <%= render :partial => "network", :collection => @networks %>  </div> -<%= will_paginate @networks %> - +<div class="pagination"> +  <%= will_paginate @networks, :container => false %> +</div>  <% content_for :sidebar do %>  <ul class="actions"> diff --git a/app/views/stop_areas/index.html.erb b/app/views/stop_areas/index.html.erb index deb5b1643..57617f559 100644 --- a/app/views/stop_areas/index.html.erb +++ b/app/views/stop_areas/index.html.erb @@ -8,11 +8,18 @@    <%= link_to t("cancel"), referential_stop_areas_path(@referential) %>  <% end %> -<%= will_paginate @stop_areas %> +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @stop_areas %> +  </div> +  <%= will_paginate @stop_areas, :container => false %> +</div>  <div class="stop_areas paginated_content">    <%= render :partial => "stop_area", :collection => @stop_areas %>  </div> -<%= will_paginate @stop_areas %> +<div class="pagination"> +  <%= will_paginate @stop_areas, :container => false %> +</div>  <% content_for :sidebar do %>  <ul class="actions"> diff --git a/app/views/stop_areas/select_parent.html.erb b/app/views/stop_areas/select_parent.html.erb new file mode 100644 index 000000000..b608b9427 --- /dev/null +++ b/app/views/stop_areas/select_parent.html.erb @@ -0,0 +1,30 @@ +<%= title_tag t('stop_areas.select_parent.title', :stop_area => @stop_area.name ) %> + +<%= semantic_form_for [@referential, @stop_area] do |form| %> +<div> +  <%= form.inputs do %>  +    <%= form.input :parent_id, :as => :text, :input_html => { :"data-pre" => [{ :id => @parent.id.to_s, :name => "#{@parent.name} #{@parent.country_code}" }].to_json }  %> +  <% end %>   +   +  <%= form.buttons do %> +    <%= form.commit_button %> +    ou <%= link_to "revenir", [@referential, @stop_area] %> +  <% end %> +</div> +<% end %> + +<script> +	$(function() { +		$( "#stop_area_parent_id" ).tokenInput('<%= referential_stop_area_stop_area_parents_path(@referential, @stop_area, :format => :json) %>', {  +       crossDomain: false,  +       prePopulate: $('#stop_area_parent_id').data('pre'), +       tokenLimit: 1, +       minChars: 3, +    }); +	}); +</script> +                          +<% content_for :sidebar do %> +<ul class="actions"> +</ul> +<% end %> diff --git a/app/views/stop_areas/show.html.erb b/app/views/stop_areas/show.html.erb index b786eec34..6536ac5cb 100644 --- a/app/views/stop_areas/show.html.erb +++ b/app/views/stop_areas/show.html.erb @@ -90,7 +90,7 @@      <% if @stop_area.parent.present? %>       <div class="parent"> -      <%= link_to([@referential, stop_area.parent]) do %>  +      <%= link_to([@referential, @stop_area.parent]) do %>           <%= image_tag "map/" + @stop_area.parent.type + ".png"   %><span><%= @stop_area.parent.name %></span>                <% end %>        <%= link_to image_tag("user_interface/ui/remove.png"), referential_stop_area_path(@referential, @stop_area.parent), :method => :delete, :confirm =>  t('stop_areas.actions.destroy_confirm'), :class => "remove" %> @@ -125,6 +125,8 @@  <ul class="actions">    <li><%= link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), :class => "edit" %></li>    <li><%= link_to  t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), :method => :delete, :confirm =>  t('stop_areas.actions.destroy_confirm'), :class => "remove" %></li> +  <li><%= link_to  t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), :class => "select_parent" %></li> +  <li><%= link_to  t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), :class => "add_children" %></li>    <br>  </ul>  <% end %> diff --git a/app/views/time_tables/index.html.erb b/app/views/time_tables/index.html.erb index 90225446a..26e484554 100644 --- a/app/views/time_tables/index.html.erb +++ b/app/views/time_tables/index.html.erb @@ -8,11 +8,18 @@    <%= link_to t("cancel"), referential_time_tables_path(@referential) %>  <% end %> -<%= will_paginate @time_tables %> +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @time_tables %> +  </div> +  <%= will_paginate @time_tables, :container => false %> +</div>  <div class="time_tables paginated_content">    <%= render :partial => "time_table", :collection => @time_tables %>  </div> -<%= will_paginate @time_tables %> +<div class="pagination"> +  <%= will_paginate @time_tables, :container => false %> +</div>  <% content_for :sidebar do %> diff --git a/config/locales/connection_link_types.yml b/config/locales/connection_link_types.yml new file mode 100644 index 000000000..2404aeeff --- /dev/null +++ b/config/locales/connection_link_types.yml @@ -0,0 +1,13 @@ +en: +  connection_link_types: +    label: +      underground: Underground +      mixed: Mixed +      overground: Overground +       +fr: +  connection_link_types: +    label: +      underground: Souterrain +      mixed: Mixte +      overground: Aérien diff --git a/config/locales/connection_links.yml b/config/locales/connection_links.yml new file mode 100644 index 000000000..15463e47c --- /dev/null +++ b/config/locales/connection_links.yml @@ -0,0 +1,96 @@ +en: +  connection_links: +    actions: +      new: Add a new connection link +      edit: Edit this connection link +      destroy: Remove this liconnection linkne +      destroy_confirm: Are you sure you want destroy this connection link? +    new: +      title: Add a new connection link +    edit: +      title: Update connection link %{connection_link} +    show: +      title: Connection link %{connection_link} +    index: +      title: Connection_ links +      name: Name +      departure: Start of link +      arrival: End of link +      selection: Selection +      selection_all: All +  activerecord:         +    models:         +      connection_link: Connection link +    attributes: +      connection_link: +        departure: Start of link +        arrival: End of link +        undefined: not yet set +        name: Name +        comment: Comment +        linkdistance: Distance +        connection_link_type: Type +        defaultduration: Average duration +        frequenttravellerduration: Regular passenger duration +        occasionaltravellerduration: Occasional passenger duration +        mobilityrestrictedtravellerduration: Mobility reduced passenger duration +        mobilityrestrictedsuitability: Mobility reduced passenger suitable +        stairsavailability: Escalator +        liftavailability: Lift +        objectid: Neptune identifier +        object_version: Version +        creation_time: Created on +        creator_id: Created by  +  formtastic: +    hints: +      connection_link: +        objectid: "[prefix]:ConnectionLink:[unique_key] : prefix contains only alphanumerical or underscore characters, unique_key accepts also minus character" + +fr: +  connection_links: +    actions: +      new: Ajouter une correspondance +      edit: Modifier cette correspondance +      destroy: Supprimer cette correspondance +      destroy_confirm: Etes vous sûr de détruire cette correspondance ? +    new: +      title: Ajouter une correspondance +    edit: +      title: Modifier la correspondance %{connection_link} +    show: +      title: Correspondance %{connection_link} +    index: +      name: Nom +      title: Correspondances +      departure: Arrêt de départ +      arrival: "Arrêt d'arrivée" +      selection: Sélection +      selection_all: Tous +  activerecord:         +    models:         +      connection_link: Correspondance +    attributes: +      connection_link: +        departure: Arrêt de départ +        arrival: "Arrêt d'arrivée" +        undefined: non défini +        name: Nom +        comment: Commentaire +        linkdistance: Distance +        connection_link_type: Type +        defaultduration: Durée moyenne +        frequenttravellerduration: Durée pour un habitué +        occasionaltravellerduration: Durée pour un voyageur occasionnel +        mobilityrestrictedtravellerduration: Durée pour un voyageur à mobilité réduite +        mobilityrestrictedsuitability: Accès pour personne à mobilité réduite +        stairsavailability: Escalator +        liftavailability: Ascenseur +        objectid: Identifiant Neptune +        object_version: Version +        creation_time: Créé le +        creator_id: Créé par +  formtastic: +    hints: +      connection_link: +        objectid: "[prefixe]:ConnectionLink:[clé_unique]  caractères autorisés : alphanumériques et 'souligné' pour le préfixe, la clé unique accepte en plus le 'moins'" + diff --git a/config/locales/directions.yml b/config/locales/directions.yml index 82b87673a..8e59b0b84 100644 --- a/config/locales/directions.yml +++ b/config/locales/directions.yml @@ -3,8 +3,8 @@ en:      label:        straight_forward: straight forward        backward: backward -      clockwise: clockwise -      anti_clockwise: anticlockwise +      clock_wise: clockwise +      counter_clock_wise: counterclockwise        north: north        north_west: north west        west: west @@ -18,8 +18,8 @@ fr:      label:        straight_forward: aller        backward: retour -      clockwise: sens horaire -      anti_clockwise: sens anti horaire +      clock_wise: sens horaire +      counter_clock_wise: sens anti horaire        north: nord        north_west: nord ouest        west: ouest diff --git a/config/locales/lines.yml b/config/locales/lines.yml index 490a7b630..a2ba7df95 100644 --- a/config/locales/lines.yml +++ b/config/locales/lines.yml @@ -28,7 +28,7 @@ en:          name: Name          published_name: Published name                  number: Number -        transport_mode_name: Transport mode +        transport_mode: Transport mode          comment: Comments          objectid: Neptune identifier          object_version: Version @@ -70,7 +70,7 @@ fr:          name: Nom          published_name: Nom public                  number: Indice -        transport_mode_name: Mode de transport +        transport_mode: Mode de transport          comment: Commentaire          objectid: Identifiant Neptune          object_version: Version diff --git a/config/locales/stop_areas.yml b/config/locales/stop_areas.yml index ca4751dbe..78ca3c2d1 100644 --- a/config/locales/stop_areas.yml +++ b/config/locales/stop_areas.yml @@ -8,6 +8,8 @@ en:        edit: Edit this stop        destroy: Remove this stop        destroy_confirm: Are you sure you want destroy this stop? +      select_parent: Select Parent +      add_children: Add Children      new:        title: Add a new stop      edit: @@ -23,6 +25,8 @@ en:        selection: Selection        selection_all: All        area_type: Area Type +    select_parent: +      title: Select parent of stop area %{stop_area}     activerecord:              models:                stop_area: Stop area @@ -62,6 +66,8 @@ fr:        edit: Modifier cet arrêt        destroy: Supprimer cet arrêt        destroy_confirm: Etes vous sûr de détruire cet arrêt ? +      select_parent: Sélectionner le parent +      add_children: Ajouter un fils      new:        title: Ajouter un arrêt      edit: @@ -77,6 +83,8 @@ fr:        selection: Sélection        selection_all: Tous        area_type: Type d'arrêt  +    select_parent: +      title: Sélection du parent de l'arrêt %{stop_area}     activerecord:              models:                stop_area: Arrêt diff --git a/config/routes.rb b/config/routes.rb index 4aaedc87b..4e7bebfc2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,11 +16,31 @@ ChouetteIhm::Application.routes.draw do    #   resources :products    resources :referentials do      resources :lines, :networks do -      resources :stop_areas +      resources :stop_areas do +        resources :stop_area_parents +        member do +          get 'add_children' +          get 'select_parent' +        end +      end                resources :routes      end -    resources :companies, :stop_areas, :time_tables +    resources :companies, :stop_areas,  :connection_links +     +    resources :time_tables do +      resources :time_table_dates +      resources :time_table_periods +    end + +    resources :stop_areas do +      resources :stop_area_parents  +      member do +        get 'add_children' +        get 'select_parent' +      end +    end +    end     match '/help/(*slug)' => 'help#show' diff --git a/db/migrate/20120426141032_create_chouette_connection_link.rb b/db/migrate/20120426141032_create_chouette_connection_link.rb new file mode 100644 index 000000000..185c49af2 --- /dev/null +++ b/db/migrate/20120426141032_create_chouette_connection_link.rb @@ -0,0 +1,28 @@ +class CreateChouetteConnectionLink < ActiveRecord::Migration +  def up +  create_table "connectionlink", :force => true do |t| +    t.integer  "departureid",    :limit => 8 +    t.integer  "arrivalid",      :limit => 8 +    t.string   "objectid",       :null => false +    t.integer  "objectversion" +    t.datetime "creationtime" +    t.string   "creatorid" +    t.string   "name" +    t.string   "comment" +    t.decimal  "linkdistance",  :precision => 19, :scale => 2 +    t.string   "linktype" +    t.time     "defaultduration" +    t.time     "frequenttravellerduration" +    t.time     "occasionaltravellerduration" +    t.time     "mobilityrestrictedtravellerduration" +    t.boolean  "mobilityrestrictedsuitability" +    t.boolean  "stairsavailability" +    t.boolean  "liftavailability" +    t.integer  "intuserneeds" +  end +   add_index "connectionlink", ["objectid"], :name => "connectionlink_objectid_key", :unique => true +  end + +  def down +  end +end diff --git a/db/schema.rb b/db/schema.rb index 07dc4922d..7666b10bf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@  #  # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120425125542) do +ActiveRecord::Schema.define(:version => 20120426141032) do    create_table "company", :force => true do |t|      t.string   "objectid" @@ -31,6 +31,29 @@ ActiveRecord::Schema.define(:version => 20120425125542) do    add_index "company", ["objectid"], :name => "company_objectid_key", :unique => true    add_index "company", ["registrationnumber"], :name => "company_registrationnumber_key", :unique => true +  create_table "connectionlink", :force => true do |t| +    t.integer  "departureid",                         :limit => 8 +    t.integer  "arrivalid",                           :limit => 8 +    t.string   "objectid",                                                                        :null => false +    t.integer  "objectversion" +    t.datetime "creationtime" +    t.string   "creatorid" +    t.string   "name" +    t.string   "comment" +    t.decimal  "linkdistance",                                     :precision => 19, :scale => 2 +    t.string   "linktype" +    t.time     "defaultduration" +    t.time     "frequenttravellerduration" +    t.time     "occasionaltravellerduration" +    t.time     "mobilityrestrictedtravellerduration" +    t.boolean  "mobilityrestrictedsuitability" +    t.boolean  "stairsavailability" +    t.boolean  "liftavailability" +    t.integer  "intuserneeds" +  end + +  add_index "connectionlink", ["objectid"], :name => "connectionlink_objectid_key", :unique => true +    create_table "line", :force => true do |t|      t.integer  "ptnetworkid",                :limit => 8      t.integer  "companyid",                  :limit => 8 diff --git a/spec/requests/connection_links_spec.rb b/spec/requests/connection_links_spec.rb new file mode 100644 index 000000000..e137a330b --- /dev/null +++ b/spec/requests/connection_links_spec.rb @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe "ConnectionLinks" do +  login_user + +  let!(:referential) { create(:referential).switch } +  let!(:connection_links) { referential; Array.new(2) { create(:connection_link) } } +  subject { connection_links.first } + +  describe "list" do +    it "display connection_links" do +      visit referential_connection_links_path(referential) +      page.should have_content(connection_links.first.name) +      page.should have_content(connection_links.last.name) +    end +     +  end  + +  describe "show" do       +    it "display connection_link" do +      visit referential_connection_links_path(referential) +      click_link "#{connection_links.first.name}" +      page.should have_content(connection_links.first.name) +    end +     +    it "display map" do +      pending ": map not yet implemented" +#      subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) }) +#      visit referential_connection_links_path(referential) +#      click_link "#{connection_links.first.name}" +#      page.should have_selector("#map", :class => 'connection_link') +    end +     +  end + +  describe "new" do      +    it "creates connection_link and return to show" do +      visit referential_connection_links_path(referential) +      click_link "Ajouter une correspondance" +      fill_in "Nom", :with => "ConnectionLink 1" +      fill_in "Identifiant Neptune", :with => "test:ConnectionLink:1"         +      click_button("Créer Correspondance") +      page.should have_content("ConnectionLink 1") +    end +  end + +  describe "edit and return to show" do       +    it "edit connection_link" do +      visit referential_connection_link_path(referential, subject) +      click_link "Modifier cette correspondance" +      fill_in "Nom", :with => "ConnectionLink Modified" +      click_button("Modifier Correspondance") +      page.should have_content("ConnectionLink Modified") +    end +  end + +end diff --git a/spec/requests/time_tables_spec.rb b/spec/requests/time_tables_spec.rb new file mode 100644 index 000000000..720370ead --- /dev/null +++ b/spec/requests/time_tables_spec.rb @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe "TimeTables" do +  login_user + +  let!(:referential) { create(:referential).switch } +  let!(:time_tables) { referential; Array.new(2) { create(:time_table) } } +  subject { time_tables.first } + +  describe "list" do +    it "display time_tables" do +      visit referential_time_tables_path(referential) +      page.should have_content(time_tables.first.comment) +      page.should have_content(time_tables.last.comment) +    end +     +  end  + +  describe "show" do       +    it "display time_table" do +      visit referential_time_tables_path(referential) +      click_link "#{time_tables.first.comment}" +      page.should have_content(time_tables.first.comment) +    end +     +  end + +  describe "new" do       +    it "creates time_table and return to show" do +      visit referential_time_tables_path(referential) +      click_link "Ajouter un calendrier" +      fill_in "Description", :with => "TimeTable 1" +      fill_in "Identifiant Neptune", :with => "test:Timetable:1"         +      click_button("Créer Calendrier") +      page.should have_content("TimeTable 1") +    end +  end + +  describe "edit and return to show" do       +    it "edit time_table" do +      visit referential_time_table_path(referential, subject) +      click_link "Modifier ce calendrier" +      fill_in "Description", :with => "TimeTable Modified" +      click_button("Modifier Calendrier") +      page.should have_content("TimeTable Modified") +    end +  end + +end diff --git a/spec/views/connection_links/edit.html.erb_spec.rb b/spec/views/connection_links/edit.html.erb_spec.rb new file mode 100644 index 000000000..331529ff8 --- /dev/null +++ b/spec/views/connection_links/edit.html.erb_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe "/connection_links/edit" do +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:connection_link) { assign(:connection_link, create(:connection_link)) } +  let!(:connection_links) { Array.new(2) { create(:connection_link) } } + +  describe "test" do +    it "should render h2 with the connection_link name" do +      render     +      rendered.should have_selector("h2", :text => Regexp.new(connection_link.name)) +    end +  end + +  describe "form" do +    it "should render input for name" do +      render +      rendered.should have_selector("form") do +        with_tag "input[type=text][name='connection_link[name]'][value=?]", connection_link.name +      end +    end +  end + +end diff --git a/spec/views/connection_links/index.html.erb_spec.rb b/spec/views/connection_links/index.html.erb_spec.rb new file mode 100644 index 000000000..9732c16c5 --- /dev/null +++ b/spec/views/connection_links/index.html.erb_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe "/connection_links/index" do + +  let!(:referential) { assign( :referential, create(:referential) ) } +  let!(:connection_links) { assign :connection_links, Array.new(2) { create(:connection_link) }.paginate  }   +  let!(:search) { assign :q, Ransack::Search.new(Chouette::ConnectionLink) } + +  it "should render a show link for each group" do         +    render   +    connection_links.each do |connection_link|       +      rendered.should have_selector(".connection_link a[href='#{view.referential_connection_link_path(referential, connection_link)}']", :text => connection_link.name) +    end +  end + +  it "should render a link to create a new group" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{new_referential_connection_link_path(referential)}']") +  end + +end diff --git a/spec/views/connection_links/new.html.erb_spec.rb b/spec/views/connection_links/new.html.erb_spec.rb new file mode 100644 index 000000000..1e9ee570d --- /dev/null +++ b/spec/views/connection_links/new.html.erb_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe "/connection_links/new" do +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:connection_link) { assign(:connection_link, build(:connection_link)) } + +  describe "form" do +     +    it "should render input for name" do +      render +      rendered.should have_selector("form") do +        with_selector "input[type=text][name=?]", connection_link.name +      end +    end + +  end +end diff --git a/spec/views/connection_links/show.html.erb_spec.rb b/spec/views/connection_links/show.html.erb_spec.rb new file mode 100644 index 000000000..bc8d075cf --- /dev/null +++ b/spec/views/connection_links/show.html.erb_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe "/connection_links/show" do +   +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:connection_link) { assign(:connection_link, create(:connection_link)) } + +  it "should render h2 with the connection_link name" do +    render +    rendered.should have_selector("h2", :text => Regexp.new(connection_link.name)) +  end + +  it "should display a map with class 'connection_link'" do +    pending ": map not yet implemented" +  #   render +  #   rendered.should have_selector("#map", :class => 'connection_link') +  end + +  it "should render a link to edit the connection_link" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']") +  end + +  it "should render a link to remove the connection_link" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']") +  end + +end + diff --git a/spec/views/time_tables/edit.html.erb_spec.rb b/spec/views/time_tables/edit.html.erb_spec.rb new file mode 100644 index 000000000..6baf741fc --- /dev/null +++ b/spec/views/time_tables/edit.html.erb_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe "/time_tables/edit" do +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:time_table) { assign(:time_table, create(:time_table) ) } + +  describe "test" do +    it "should render h2 with the group comment" do +      render     +      rendered.should have_selector("h2", :text => Regexp.new(time_table.comment)) +    end +  end + +  describe "form" do +    it "should render input for comment" do +      render +      rendered.should have_selector("form") do +        with_tag "input[type=text][comment='time_table[comment]'][value=?]", time_table.comment +      end +    end + +  end +end diff --git a/spec/views/time_tables/index.html.erb_spec.rb b/spec/views/time_tables/index.html.erb_spec.rb new file mode 100644 index 000000000..7d56ad982 --- /dev/null +++ b/spec/views/time_tables/index.html.erb_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe "/time_tables/index" do + +  let!(:referential) { assign :referential, create(:referential) } +  let!(:time_tables) { assign :time_tables, Array.new(2){ create(:time_table) }.paginate }   +  let!(:search) { assign :q, Ransack::Search.new(Chouette::TimeTable) } + +  it "should render a show link for each group" do         +    render   +    time_tables.each do |time_table|       +      rendered.should have_selector(".time_table a[href='#{view.referential_time_table_path(referential, time_table)}']", :text => time_table.comment) +    end +  end + +  it "should render a link to create a new group" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{new_referential_time_table_path(referential)}']") +  end + +end diff --git a/spec/views/time_tables/new.html.erb_spec.rb b/spec/views/time_tables/new.html.erb_spec.rb new file mode 100644 index 000000000..dd7a35b3b --- /dev/null +++ b/spec/views/time_tables/new.html.erb_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe "/time_tables/new" do +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:time_table) {  assign(:time_table, build(:time_table)) } + +  describe "form" do +     +    it "should render input for comment" do +      render +      rendered.should have_selector("form") do +        with_selector "input[type=text][comment=?]", time_table.comment +      end +    end + +  end +end diff --git a/spec/views/time_tables/show.html.erb_spec.rb b/spec/views/time_tables/show.html.erb_spec.rb new file mode 100644 index 000000000..056919b2b --- /dev/null +++ b/spec/views/time_tables/show.html.erb_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe "/time_tables/show" do +   +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:time_table) { assign(:time_table, create(:time_table)) } + +  it "should render h2 with the time_table comment" do +    render +    rendered.should have_selector("h2", :text => Regexp.new(time_table.comment)) +  end + +  it "should render a link to edit the time_table" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{view.edit_referential_time_table_path(referential, time_table)}']") +  end + +  it "should render a link to remove the time_table" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{view.referential_time_table_path(referential, time_table)}'][class='remove']") +  end + +end + diff --git a/vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png b/vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png Binary files differnew file mode 100644 index 000000000..5b5dab2ab --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png Binary files differnew file mode 100644 index 000000000..ad3d6346e --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png Binary files differnew file mode 100644 index 000000000..42ccba269 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png Binary files differnew file mode 100644 index 000000000..5a46b47cb --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png Binary files differnew file mode 100644 index 000000000..86c2baa65 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.png Binary files differnew file mode 100644 index 000000000..e65ca1297 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.png diff --git a/vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png Binary files differnew file mode 100644 index 000000000..7c9fa6c6e --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.png b/vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.png Binary files differnew file mode 100644 index 000000000..0e05810ff --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.png diff --git a/vendor/assets/stylesheets/images/ui-icons_222222_256x240.png b/vendor/assets/stylesheets/images/ui-icons_222222_256x240.png Binary files differnew file mode 100644 index 000000000..b273ff111 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-icons_222222_256x240.png diff --git a/vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.png b/vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.png Binary files differnew file mode 100644 index 000000000..09d1cdc85 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.png diff --git a/vendor/assets/stylesheets/images/ui-icons_454545_256x240.png b/vendor/assets/stylesheets/images/ui-icons_454545_256x240.png Binary files differnew file mode 100644 index 000000000..59bd45b90 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-icons_454545_256x240.png diff --git a/vendor/assets/stylesheets/images/ui-icons_888888_256x240.png b/vendor/assets/stylesheets/images/ui-icons_888888_256x240.png Binary files differnew file mode 100644 index 000000000..6d02426c1 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-icons_888888_256x240.png diff --git a/vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png b/vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png Binary files differnew file mode 100644 index 000000000..2ab019b73 --- /dev/null +++ b/vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png diff --git a/vendor/assets/stylesheets/jquery-ui.css b/vendor/assets/stylesheets/jquery-ui.css new file mode 100644 index 000000000..9a5a29c86 --- /dev/null +++ b/vendor/assets/stylesheets/jquery-ui.css @@ -0,0 +1,565 @@ +/*! + * jQuery UI CSS Framework 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/*! + * jQuery UI CSS Framework 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_75_ffffff_1x400.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_inset-soft_95_fef1ec_1x100.png) 50% bottom repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! + * jQuery UI Resizable 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! + * jQuery UI Selectable 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/*! + * jQuery UI Accordion 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/*! + * jQuery UI Autocomplete 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; }	 + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { +	list-style:none; +	padding: 2px; +	margin: 0; +	display:block; +	float: left; +} +.ui-menu .ui-menu { +	margin-top: -3px; +} +.ui-menu .ui-menu-item { +	margin:0; +	padding: 0; +	zoom: 1; +	float: left; +	clear: left; +	width: 100%; +} +.ui-menu .ui-menu-item a { +	text-decoration:none; +	display:block; +	padding:.2em .4em; +	line-height:1.5; +	zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { +	font-weight: normal; +	margin: -1px; +} +/*! + * jQuery UI Button 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; }  +button.ui-button-icons-only { width: 3.7em; }  + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4;  } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/*! + * jQuery UI Dialog 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }  +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/*! + * jQuery UI Slider 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! + * jQuery UI Tabs 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/*! + * jQuery UI Datepicker 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month,  +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { +    display: none; /*sorry for IE5*/ +    display/**/: block; /*sorry for IE5*/ +    position: absolute; /*must have*/ +    z-index: -1; /*must have*/ +    filter: mask(); /*must have*/ +    top: -4px; /*must have*/ +    left: -4px; /*must have*/ +    width: 200px; /*must have*/ +    height: 200px; /*must have*/ +}/*! + * jQuery UI Progressbar 1.8.19 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file  | 
