diff options
| author | Owen <despito@MacBook-Pro-de-Despito.local> | 2014-07-14 19:06:42 +0300 |
|---|---|---|
| committer | Owen <despito@MacBook-Pro-de-Despito.local> | 2014-07-14 19:06:42 +0300 |
| commit | 335af0bbf19ef4e6454233c9b4d212ee5aaa9d0d (patch) | |
| tree | 7433f0c265acf863db5a6615eab6f601c94e0dad /scripts | |
| parent | 2d98eaaf727834c128fdd2513d43d677d97fe8d7 (diff) | |
Target and adjacent nodes are highlighted when clicked
Background click remove editing boxes and highlights
Deliverables test button adds 140 random tasks and dates
Links between nodes have two colors: blue and green for dependencies
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/ScrollTo.js | 17 | ||||
| -rw-r--r-- | scripts/buttons.js | 63 | ||||
| -rwxr-xr-x | scripts/datepicker.js | 2371 | ||||
| -rw-r--r-- | scripts/gant.js | 185 | ||||
| -rw-r--r-- | scripts/rhizicore.js | 895 | ||||
| -rw-r--r-- | scripts/robot.js | 23 | ||||
| -rw-r--r-- | scripts/textanalysis.js | 378 |
7 files changed, 3433 insertions, 499 deletions
diff --git a/scripts/ScrollTo.js b/scripts/ScrollTo.js new file mode 100644 index 00000000..a015f08c --- /dev/null +++ b/scripts/ScrollTo.js @@ -0,0 +1,17 @@ +$.fn.scrollTo = function( target, options, callback ){ + if(typeof options == 'function' && arguments.length == 2){ callback = options; options = target; } + var settings = $.extend({ + scrollTarget : target, + offsetTop : 50, + duration : 500, + easing : 'swing' + }, options); + return this.each(function(){ + var scrollPane = $(this); + var scrollTarget = (typeof settings.scrollTarget == "number") ? settings.scrollTarget : $(settings.scrollTarget); + var scrollY = (typeof scrollTarget == "number") ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop); + scrollPane.animate({scrollTop : scrollY }, parseInt(settings.duration), settings.easing, function(){ + if (typeof callback == 'function') { callback.call(this); } + }); + }); +}
\ No newline at end of file diff --git a/scripts/buttons.js b/scripts/buttons.js index 4b3409d2..e1e39a68 100644 --- a/scripts/buttons.js +++ b/scripts/buttons.js @@ -17,9 +17,70 @@ function Colorize(){ $('.td5').click(function(){chosencolor="objective"}); } -$('#textanalyser').submit(function(){return false;}); + $('.tutorial').click(function(){}); +var key="#47989379"; + + +$('.save').click(function(){ + + var jsonsave='{"nodes":['; + console.log(nodes); + for(var i=0;i<nodes.length;i++){ + var node=nodes[i]; + jsonsave+='{"id":"'+node.id+'","type":"'+node.type+'","state":"'+"perm"+'","start":"'+node.start+'","end":"'+node.end+'"}'; + if(i!==nodes.length-1)jsonsave+=','; + } + jsonsave+='],"links":['; + + for(var j=0;j<links.length;j++){ + var link=links[j]; + jsonsave+='{"source":"'+link.source.id+'","target":"'+link.target.id+'","name":"'+link.name+'"}'; + if(j!==links.length-1)jsonsave+=","; + } + jsonsave+=']}'; + console.log(jsonsave); + localStorage.setItem(key, JSON.stringify(jsonsave)); + +}); + +$('.load').click(function(){ + var data = JSON.parse(JSON.parse(localStorage.getItem(key))); + console.log(data); + for(var i=0; i<data["nodes"].length; i++){ + var node=data.nodes[i]; + console.log(data.nodes[i].id); + graph.addNodeComplete(node.id,node.type,"perm",node.start,node.end); + } + + for(var j=0; j<data["links"].length; j++){ + var node=data.links[j]; + + console.log(data.links[j].name); + graph.addLink(fetchNode(link.source),fetchNode(link.target),link.name); + } + +}); + + $('.deliverabletest').click(function(){ + deliverableTest(); + }); + +function fetchNode(id){ + for( x in nodes){ + if(x.id===id){ + console.log("found"); + return x; + } + } + return null; +} + + + + + diff --git a/scripts/datepicker.js b/scripts/datepicker.js new file mode 100755 index 00000000..1d1aa9cf --- /dev/null +++ b/scripts/datepicker.js @@ -0,0 +1,2371 @@ +/*! jQuery UI - v1.11.0 - 2014-06-28 +* http://jqueryui.com +* Includes: core.js, datepicker.js +* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { +/*! + * jQuery UI Core 1.11.0 + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/ui-core/ + */ + + +// $.ui might exist from components with no dependencies, e.g., $.ui.position +$.ui = $.ui || {}; + +$.extend( $.ui, { + version: "1.11.0", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + scrollParent: function() { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return (/(auto|scroll)/).test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); + }).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; + }, + + uniqueId: (function() { + var uuid = 0; + + return function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + }); + }; + })(), + + removeUniqueId: function() { + return this.each(function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// selectors +function focusable( element, isTabIndexNotNaN ) { + var map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap=#" + mapName + "]" )[0]; + return !!img && visible( img ); + } + return ( /input|select|textarea|button|object/.test( nodeName ) ? + !element.disabled : + "a" === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN) && + // the element and all of its ancestors must be visible + visible( element ); +} + +function visible( element ) { + return $.expr.filters.visible( element ) && + !$( element ).parents().addBack().filter(function() { + return $.css( this, "visibility" ) === "hidden"; + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } +}); + +// support: jQuery <1.8 +if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); +} + +// support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) +if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { + $.fn.removeData = (function( removeData ) { + return function( key ) { + if ( arguments.length ) { + return removeData.call( this, $.camelCase( key ) ); + } else { + return removeData.call( this ); + } + }; + })( $.fn.removeData ); +} + +// deprecated +$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + +$.fn.extend({ + focus: (function( orig ) { + return function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + orig.apply( this, arguments ); + }; + })( $.fn.focus ), + + disableSelection: (function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.bind( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }; + })(), + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + } +}); + +// $.ui.plugin is deprecated. Use $.widget() extensions instead. +$.ui.plugin = { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args, allowDisconnected ) { + var i, + set = instance.plugins[ name ]; + + if ( !set ) { + return; + } + + if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } +}; + + +/*! + * jQuery UI Datepicker 1.11.0 + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/datepicker/ + */ + + +$.extend($.ui, { datepicker: { version: "1.11.0" } }); + +var datepicker_instActive; + +function datepicker_getZindex( elem ) { + var position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + + return 0; +} +/* Date picker manager. + Use the singleton instance of this class, $.datepicker, to interact with the date picker. + Settings for (groups of) date pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + +function Datepicker() { + this._curInst = null; // The current instance in use + this._keyEvent = false; // If the last event was a key event + this._disabledInputs = []; // List of date picker inputs that have been disabled + this._datepickerShowing = false; // True if the popup picker is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division + this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class + this._appendClass = "ui-datepicker-append"; // The name of the append marker class + this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class + this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class + this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class + this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class + this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class + this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class + this.regional = []; // Available regional settings, indexed by language code + this.regional[""] = { // Default regional settings + closeText: "Done", // Display text for close link + prevText: "Prev", // Display text for previous month link + nextText: "Next", // Display text for next month link + currentText: "Today", // Display text for current month link + monthNames: ["January","February","March","April","May","June", + "July","August","September","October","November","December"], // Names of months for drop-down and formatting + monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting + dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting + dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting + dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday + weekHeader: "Wk", // Column header for week of the year + dateFormat: "mm/dd/yy", // See format options on parseDate + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: "" // Additional text to append to the year in the month headers + }; + this._defaults = { // Global defaults for all the date picker instances + showOn: "focus", // "focus" for popup on focus, + // "button" for trigger button, or "both" for either + showAnim: "fadeIn", // Name of jQuery animation for popup + showOptions: {}, // Options for enhanced animations + defaultDate: null, // Used when field is blank: actual date, + // +/-number for offset from today, null for today + appendText: "", // Display text following the input box, e.g. showing the format + buttonText: "...", // Text for trigger button + buttonImage: "", // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links + gotoCurrent: false, // True if today link goes back to current selection instead + changeMonth: false, // True if month can be selected directly, false if only prev/next + changeYear: false, // True if year can be selected directly, false if only prev/next + yearRange: "c-10:c+10", // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) + showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it + calculateWeek: this.iso8601Week, // How to calculate the week of the year, + // takes a Date and returns the number of the week for it + shortYearCutoff: "+10", // Short year values < this are in the current century, + // > this are in the previous century, + // string value starting with "+" for current year + value + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + duration: "fast", // Duration of display/closure + beforeShowDay: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", + // [2] = cell title (optional), e.g. $.datepicker.noWeekends + beforeShow: null, // Function that takes an input field and + // returns a set of custom settings for the date picker + onSelect: null, // Define a callback function when a date is selected + onChangeMonthYear: null, // Define a callback function when the month or year is changed + onClose: null, // Define a callback function when the datepicker is closed + numberOfMonths: 1, // Number of months to show at a time + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) + stepMonths: 1, // Number of months to step back/forward + stepBigMonths: 12, // Number of months to step back/forward for the big links + altField: "", // Selector for an alternate field to store selected dates into + altFormat: "", // The date format to use for the alternate field + constrainInput: true, // The input is constrained by the current date format + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false, // True to size the input for the date format, false to leave as is + disabled: false // The initial disabled state + }; + $.extend(this._defaults, this.regional[""]); + this.regional.en = $.extend( true, {}, this.regional[ "" ]); + this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); + this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); +} + +$.extend(Datepicker.prototype, { + /* Class name added to elements to indicate already configured with a date picker. */ + markerClassName: "hasDatepicker", + + //Keep track of the maximum number of rows displayed (see #7043) + maxRows: 4, + + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, + + /* Override the default settings for all instances of the date picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function(settings) { + datepicker_extendRemove(this._defaults, settings || {}); + return this; + }, + + /* Attach the date picker to a jQuery selection. + * @param target element - the target input field or division or span + * @param settings object - the new settings to use for this date picker instance (anonymous) + */ + _attachDatepicker: function(target, settings) { + var nodeName, inline, inst; + nodeName = target.nodeName.toLowerCase(); + inline = (nodeName === "div" || nodeName === "span"); + if (!target.id) { + this.uuid += 1; + target.id = "dp" + this.uuid; + } + inst = this._newInst($(target), inline); + inst.settings = $.extend({}, settings || {}); + if (nodeName === "input") { + this._connectDatepicker(target, inst); + } else if (inline) { + this._inlineDatepicker(target, inst); + } + }, + + /* Create a new instance object. */ + _newInst: function(target, inline) { + var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars + return {id: id, input: target, // associated target + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection + drawMonth: 0, drawYear: 0, // month being drawn + inline: inline, // is datepicker inline or not + dpDiv: (!inline ? this.dpDiv : // presentation div + datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; + }, + + /* Attach the date picker to an input field. */ + _connectDatepicker: function(target, inst) { + var input = $(target); + inst.append = $([]); + inst.trigger = $([]); + if (input.hasClass(this.markerClassName)) { + return; + } + this._attachments(input, inst); + input.addClass(this.markerClassName).keydown(this._doKeyDown). + keypress(this._doKeyPress).keyup(this._doKeyUp); + this._autoSize(inst); + $.data(target, "datepicker", inst); + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + }, + + /* Make attachments based on settings. */ + _attachments: function(input, inst) { + var showOn, buttonText, buttonImage, + appendText = this._get(inst, "appendText"), + isRTL = this._get(inst, "isRTL"); + + if (inst.append) { + inst.append.remove(); + } + if (appendText) { + inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); + input[isRTL ? "before" : "after"](inst.append); + } + + input.unbind("focus", this._showDatepicker); + + if (inst.trigger) { + inst.trigger.remove(); + } + + showOn = this._get(inst, "showOn"); + if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field + input.focus(this._showDatepicker); + } + if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked + buttonText = this._get(inst, "buttonText"); + buttonImage = this._get(inst, "buttonImage"); + inst.trigger = $(this._get(inst, "buttonImageOnly") ? + $("<img/>").addClass(this._triggerClass). + attr({ src: buttonImage, alt: buttonText, title: buttonText }) : + $("<button type='button'></button>").addClass(this._triggerClass). + html(!buttonImage ? buttonText : $("<img/>").attr( + { src:buttonImage, alt:buttonText, title:buttonText }))); + input[isRTL ? "before" : "after"](inst.trigger); + inst.trigger.click(function() { + if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { + $.datepicker._hideDatepicker(); + } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker(input[0]); + } else { + $.datepicker._showDatepicker(input[0]); + } + return false; + }); + } + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function(inst) { + if (this._get(inst, "autoSize") && !inst.inline) { + var findMax, max, maxI, i, + date = new Date(2009, 12 - 1, 20), // Ensure double digits + dateFormat = this._get(inst, "dateFormat"); + + if (dateFormat.match(/[DM]/)) { + findMax = function(names) { + max = 0; + maxI = 0; + for (i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? + "monthNames" : "monthNamesShort")))); + date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? + "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); + } + inst.input.attr("size", this._formatDate(inst, date).length); + } + }, + + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function(target, inst) { + var divSpan = $(target); + if (divSpan.hasClass(this.markerClassName)) { + return; + } + divSpan.addClass(this.markerClassName).append(inst.dpDiv); + $.data(target, "datepicker", inst); + this._setDate(inst, this._getDefaultDate(inst), true); + this._updateDatepicker(inst); + this._updateAlternate(inst); + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, + + /* Pop-up the date picker in a "dialog" box. + * @param input element - ignored + * @param date string or Date - the initial date to display + * @param onSelect function - the function to call when a date is selected + * @param settings object - update the dialog date picker instance's settings (anonymous object) + * @param pos int[2] - coordinates for the dialog's position within the screen or + * event - with x/y coordinates or + * leave empty for default (screen centre) + * @return the manager object + */ + _dialogDatepicker: function(input, date, onSelect, settings, pos) { + var id, browserWidth, browserHeight, scrollX, scrollY, + inst = this._dialogInst; // internal instance + + if (!inst) { + this.uuid += 1; + id = "dp" + this.uuid; + this._dialogInput = $("<input type='text' id='" + id + + "' style='position: absolute; top: -100px; width: 0px;'/>"); + this._dialogInput.keydown(this._doKeyDown); + $("body").append(this._dialogInput); + inst = this._dialogInst = this._newInst(this._dialogInput, false); + inst.settings = {}; + $.data(this._dialogInput[0], "datepicker", inst); + } + datepicker_extendRemove(inst.settings, settings || {}); + date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); + this._dialogInput.val(date); + + this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); + if (!this._pos) { + browserWidth = document.documentElement.clientWidth; + browserHeight = document.documentElement.clientHeight; + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; + } + + // move input on screen for focus, but hidden behind dialog + this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass(this._dialogClass); + this._showDatepicker(this._dialogInput[0]); + if ($.blockUI) { + $.blockUI(this.dpDiv); + } + $.data(this._dialogInput[0], "datepicker", inst); + return this; + }, + + /* Detach a datepicker from its control. + * @param target element - the target input field or division or span + */ + _destroyDatepicker: function(target) { + var nodeName, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + $.removeData(target, "datepicker"); + if (nodeName === "input") { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass(this.markerClassName). + unbind("focus", this._showDatepicker). + unbind("keydown", this._doKeyDown). + unbind("keypress", this._doKeyPress). + unbind("keyup", this._doKeyUp); + } else if (nodeName === "div" || nodeName === "span") { + $target.removeClass(this.markerClassName).empty(); + } + }, + + /* Enable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _enableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = false; + inst.trigger.filter("button"). + each(function() { this.disabled = false; }).end(). + filter("img").css({opacity: "1.0", cursor: ""}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().removeClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", false); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + }, + + /* Disable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _disableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = true; + inst.trigger.filter("button"). + each(function() { this.disabled = true; }).end(). + filter("img").css({opacity: "0.5", cursor: "default"}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().addClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", true); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + this._disabledInputs[this._disabledInputs.length] = target; + }, + + /* Is the first field in a jQuery collection disabled as a datepicker? + * @param target element - the target input field or division or span + * @return boolean - true if disabled, false if enabled + */ + _isDisabledDatepicker: function(target) { + if (!target) { + return false; + } + for (var i = 0; i < this._disabledInputs.length; i++) { + if (this._disabledInputs[i] === target) { + return true; + } + } + return false; + }, + + /* Retrieve the instance data for the target control. + * @param target element - the target input field or division or span + * @return object - the associated instance data + * @throws error if a jQuery problem getting data + */ + _getInst: function(target) { + try { + return $.data(target, "datepicker"); + } + catch (err) { + throw "Missing instance data for this datepicker"; + } + }, + + /* Update or retrieve the settings for a date picker attached to an input field or division. + * @param target element - the target input field or division or span + * @param name object - the new settings to update or + * string - the name of the setting to change or retrieve, + * when retrieving also "all" for all instance settings or + * "defaults" for all global defaults + * @param value any - the new value for the setting + * (omit if above is an object or to retrieve a value) + */ + _optionDatepicker: function(target, name, value) { + var settings, date, minDate, maxDate, + inst = this._getInst(target); + + if (arguments.length === 2 && typeof name === "string") { + return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : + (inst ? (name === "all" ? $.extend({}, inst.settings) : + this._get(inst, name)) : null)); + } + + settings = name || {}; + if (typeof name === "string") { + settings = {}; + settings[name] = value; + } + + if (inst) { + if (this._curInst === inst) { + this._hideDatepicker(); + } + + date = this._getDateDatepicker(target, true); + minDate = this._getMinMaxDate(inst, "min"); + maxDate = this._getMinMaxDate(inst, "max"); + datepicker_extendRemove(inst.settings, settings); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { + inst.settings.minDate = this._formatDate(inst, minDate); + } + if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { + inst.settings.maxDate = this._formatDate(inst, maxDate); + } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker(target); + } else { + this._enableDatepicker(target); + } + } + this._attachments($(target), inst); + this._autoSize(inst); + this._setDate(inst, date); + this._updateAlternate(inst); + this._updateDatepicker(inst); + } + }, + + // change method deprecated + _changeDatepicker: function(target, name, value) { + this._optionDatepicker(target, name, value); + }, + + /* Redraw the date picker attached to an input field or division. + * @param target element - the target input field or division or span + */ + _refreshDatepicker: function(target) { + var inst = this._getInst(target); + if (inst) { + this._updateDatepicker(inst); + } + }, + + /* Set the dates for a jQuery selection. + * @param target element - the target input field or division or span + * @param date Date - the new date + */ + _setDateDatepicker: function(target, date) { + var inst = this._getInst(target); + if (inst) { + this._setDate(inst, date); + this._updateDatepicker(inst); + this._updateAlternate(inst); + } + }, + + /* Get the date(s) for the first entry in a jQuery selection. + * @param target element - the target input field or division or span + * @param noDefault boolean - true if no default date is to be used + * @return Date - the current date + */ + _getDateDatepicker: function(target, noDefault) { + var inst = this._getInst(target); + if (inst && !inst.inline) { + this._setDateFromField(inst, noDefault); + } + return (inst ? this._getDate(inst) : null); + }, + + /* Handle keystrokes. */ + _doKeyDown: function(event) { + var onSelect, dateStr, sel, + inst = $.datepicker._getInst(event.target), + handled = true, + isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); + + inst._keyEvent = true; + if ($.datepicker._datepickerShowing) { + switch (event.keyCode) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv); + if (sel[0]) { + $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); + } + + onSelect = $.datepicker._get(inst, "onSelect"); + if (onSelect) { + dateStr = $.datepicker._formatDate(inst); + + // trigger custom callback + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); + } else { + $.datepicker._hideDatepicker(); + } + + return false; // don't submit the form + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + break; // next month/year on page down/+ ctrl + case 35: if (event.ctrlKey || event.metaKey) { + $.datepicker._clearDate(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if (event.ctrlKey || event.metaKey) { + $.datepicker._gotoToday(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // -1 day on ctrl or command +left + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +left on Mac + break; + case 38: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, -7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // +1 day on ctrl or command +right + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +right + break; + case 40: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, +7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; + } + } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home + $.datepicker._showDatepicker(this); + } else { + handled = false; + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }, + + /* Filter entered characters - based on date format. */ + _doKeyPress: function(event) { + var chars, chr, + inst = $.datepicker._getInst(event.target); + + if ($.datepicker._get(inst, "constrainInput")) { + chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); + chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); + return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); + } + }, + + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function(event) { + var date, + inst = $.datepicker._getInst(event.target); + + if (inst.input.val() !== inst.lastVal) { + try { + date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + (inst.input ? inst.input.val() : null), + $.datepicker._getFormatConfig(inst)); + + if (date) { // only if valid + $.datepicker._setDateFromField(inst); + $.datepicker._updateAlternate(inst); + $.datepicker._updateDatepicker(inst); + } + } + catch (err) { + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + * If false returned from beforeShow event handler do not show. + * @param input element - the input field attached to the date picker or + * event - if triggered by focus + */ + _showDatepicker: function(input) { + input = input.target || input; + if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger + input = $("input", input.parentNode)[0]; + } + + if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here + return; + } + + var inst, beforeShow, beforeShowSettings, isFixed, + offset, showAnim, duration; + + inst = $.datepicker._getInst(input); + if ($.datepicker._curInst && $.datepicker._curInst !== inst) { + $.datepicker._curInst.dpDiv.stop(true, true); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + } + } + + beforeShow = $.datepicker._get(inst, "beforeShow"); + beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; + if(beforeShowSettings === false){ + return; + } + datepicker_extendRemove(inst.settings, beforeShowSettings); + + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField(inst); + + if ($.datepicker._inDialog) { // hide cursor + input.value = ""; + } + if (!$.datepicker._pos) { // position below input + $.datepicker._pos = $.datepicker._findPos(input); + $.datepicker._pos[1] += input.offsetHeight; // add the height + } + + isFixed = false; + $(input).parents().each(function() { + isFixed |= $(this).css("position") === "fixed"; + return !isFixed; + }); + + offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; + $.datepicker._pos = null; + //to avoid flashes on Firefox + inst.dpDiv.empty(); + // determine sizing offscreen + inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); + $.datepicker._updateDatepicker(inst); + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset(inst, offset, isFixed); + inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? + "static" : (isFixed ? "fixed" : "absolute")), display: "none", + left: offset.left + "px", top: offset.top + "px"}); + + if (!inst.inline) { + showAnim = $.datepicker._get(inst, "showAnim"); + duration = $.datepicker._get(inst, "duration"); + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); + $.datepicker._datepickerShowing = true; + + if ( $.effects && $.effects.effect[ showAnim ] ) { + inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); + } else { + inst.dpDiv[showAnim || "show"](showAnim ? duration : null); + } + + if ( $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + $.datepicker._curInst = inst; + } + }, + + /* Generate the date picker content. */ + _updateDatepicker: function(inst) { + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + datepicker_instActive = inst; // for delegate hover events + inst.dpDiv.empty().append(this._generateHTML(inst)); + this._attachHandlers(inst); + inst.dpDiv.find("." + this._dayOverClass + " a"); + + var origyearshtml, + numMonths = this._getNumberOfMonths(inst), + cols = numMonths[1], + width = 17; + + inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); + if (cols > 1) { + inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); + } + inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + + "Class"]("ui-datepicker-multi"); + inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + + "Class"]("ui-datepicker-rtl"); + + if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + // deffered render of the years select (to avoid flashes on Firefox) + if( inst.yearshtml ){ + origyearshtml = inst.yearshtml; + setTimeout(function(){ + //assure that inst.yearshtml didn't change. + if( origyearshtml === inst.yearshtml && inst.yearshtml ){ + inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); + } + origyearshtml = inst.yearshtml = null; + }, 0); + } + }, + + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + // Support: IE and jQuery <1.9 + _shouldFocusInput: function( inst ) { + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); + }, + + /* Check positioning to remain on screen. */ + _checkOffset: function(inst, offset, isFixed) { + var dpWidth = inst.dpDiv.outerWidth(), + dpHeight = inst.dpDiv.outerHeight(), + inputWidth = inst.input ? inst.input.outerWidth() : 0, + inputHeight = inst.input ? inst.input.outerHeight() : 0, + viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), + viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); + + offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); + offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; + offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; + + // now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight) : 0); + + return offset; + }, + + /* Find an object's position on the screen. */ + _findPos: function(obj) { + var position, + inst = this._getInst(obj), + isRTL = this._get(inst, "isRTL"); + + while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { + obj = obj[isRTL ? "previousSibling" : "nextSibling"]; + } + + position = $(obj).offset(); + return [position.left, position.top]; + }, + + /* Hide the date picker from view. + * @param input element - the input field attached to the date picker + */ + _hideDatepicker: function(input) { + var showAnim, duration, postProcess, onClose, + inst = this._curInst; + + if (!inst || (input && inst !== $.data(input, "datepicker"))) { + return; + } + + if (this._datepickerShowing) { + showAnim = this._get(inst, "showAnim"); + duration = this._get(inst, "duration"); + postProcess = function() { + $.datepicker._tidyDialog(inst); + }; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); + } else { + inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : + (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); + } + + if (!showAnim) { + postProcess(); + } + this._datepickerShowing = false; + + onClose = this._get(inst, "onClose"); + if (onClose) { + onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); + } + + this._lastInput = null; + if (this._inDialog) { + this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); + if ($.blockUI) { + $.unblockUI(); + $("body").append(this.dpDiv); + } + } + this._inDialog = false; + } + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function(inst) { + inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); + }, + + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function(event) { + if (!$.datepicker._curInst) { + return; + } + + var $target = $(event.target), + inst = $.datepicker._getInst($target[0]); + + if ( ( ( $target[0].id !== $.datepicker._mainDivId && + $target.parents("#" + $.datepicker._mainDivId).length === 0 && + !$target.hasClass($.datepicker.markerClassName) && + !$target.closest("." + $.datepicker._triggerClass).length && + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || + ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { + $.datepicker._hideDatepicker(); + } + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(id, offset, period) { + var target = $(id), + inst = this._getInst(target[0]); + + if (this._isDisabledDatepicker(target[0])) { + return; + } + this._adjustInstDate(inst, offset + + (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning + period); + this._updateDatepicker(inst); + }, + + /* Action for current link. */ + _gotoToday: function(id) { + var date, + target = $(id), + inst = this._getInst(target[0]); + + if (this._get(inst, "gotoCurrent") && inst.currentDay) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } else { + date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function(id, select, period) { + var target = $(id), + inst = this._getInst(target[0]); + + inst["selected" + (period === "M" ? "Month" : "Year")] = + inst["draw" + (period === "M" ? "Month" : "Year")] = + parseInt(select.options[select.selectedIndex].value,10); + + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a day. */ + _selectDay: function(id, month, year, td) { + var inst, + target = $(id); + + if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { + return; + } + + inst = this._getInst(target[0]); + inst.selectedDay = inst.currentDay = $("a", td).html(); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate(id, this._formatDate(inst, + inst.currentDay, inst.currentMonth, inst.currentYear)); + }, + + /* Erase the input field and hide the date picker. */ + _clearDate: function(id) { + var target = $(id); + this._selectDate(target, ""); + }, + + /* Update the input field with the selected date. */ + _selectDate: function(id, dateStr) { + var onSelect, + target = $(id), + inst = this._getInst(target[0]); + + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) { + inst.input.val(dateStr); + } + this._updateAlternate(inst); + + onSelect = this._get(inst, "onSelect"); + if (onSelect) { + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback + } else if (inst.input) { + inst.input.trigger("change"); // fire the change event + } + + if (inst.inline){ + this._updateDatepicker(inst); + } else { + this._hideDatepicker(); + this._lastInput = inst.input[0]; + if (typeof(inst.input[0]) !== "object") { + inst.input.focus(); // restore focus + } + this._lastInput = null; + } + }, + + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function(inst) { + var altFormat, date, dateStr, + altField = this._get(inst, "altField"); + + if (altField) { // update alternate field too + altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); + date = this._getDate(inst); + dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); + $(altField).each(function() { $(this).val(dateStr); }); + } + }, + + /* Set as beforeShowDay function to prevent selection of weekends. + * @param date Date - the date to customise + * @return [boolean, string] - is this date selectable?, what is its CSS class? + */ + noWeekends: function(date) { + var day = date.getDay(); + return [(day > 0 && day < 6), ""]; + }, + + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ + iso8601Week: function(date) { + var time, + checkDate = new Date(date.getTime()); + + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + + time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + }, + + /* Parse a string value into a date object. + * See formatDate below for the possible formats. + * + * @param format string - the expected format of the date + * @param value string - the date in the above format + * @param settings Object - attributes include: + * shortYearCutoff number - the cutoff year for determining the century (optional) + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return Date - the extracted date value or null if value is blank + */ + parseDate: function (format, value, settings) { + if (format == null || value == null) { + throw "Invalid arguments"; + } + + value = (typeof value === "object" ? value.toString() : value + ""); + if (value === "") { + return null; + } + + var iFormat, dim, extra, + iValue = 0, + shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, + shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + year = -1, + month = -1, + day = -1, + doy = -1, + literal = false, + date, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Extract a number from the string value + getNumber = function(match) { + var isDoubled = lookAhead(match), + size = (match === "@" ? 14 : (match === "!" ? 20 : + (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), + digits = new RegExp("^\\d{1," + size + "}"), + num = value.substring(iValue).match(digits); + if (!num) { + throw "Missing number at position " + iValue; + } + iValue += num[0].length; + return parseInt(num[0], 10); + }, + // Extract a name from the string value and convert to an index + getName = function(match, shortNames, longNames) { + var index = -1, + names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { + return [ [k, v] ]; + }).sort(function (a, b) { + return -(a[1].length - b[1].length); + }); + + $.each(names, function (i, pair) { + var name = pair[1]; + if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { + index = pair[0]; + iValue += name.length; + return false; + } + }); + if (index !== -1) { + return index + 1; + } else { + throw "Unknown name at position " + iValue; + } + }, + // Confirm that a literal character matches the string value + checkLiteral = function() { + if (value.charAt(iValue) !== format.charAt(iFormat)) { + throw "Unexpected literal at position " + iValue; + } + iValue++; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + checkLiteral(); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + day = getNumber("d"); + break; + case "D": + getName("D", dayNamesShort, dayNames); + break; + case "o": + doy = getNumber("o"); + break; + case "m": + month = getNumber("m"); + break; + case "M": + month = getName("M", monthNamesShort, monthNames); + break; + case "y": + year = getNumber("y"); + break; + case "@": + date = new Date(getNumber("@")); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "!": + date = new Date((getNumber("!") - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if (lookAhead("'")){ + checkLiteral(); + } else { + literal = true; + } + break; + default: + checkLiteral(); + } + } + } + + if (iValue < value.length){ + extra = value.substr(iValue); + if (!/^\s+/.test(extra)) { + throw "Extra/unparsed characters found in date: " + extra; + } + } + + if (year === -1) { + year = new Date().getFullYear(); + } else if (year < 100) { + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + (year <= shortYearCutoff ? 0 : -100); + } + + if (doy > -1) { + month = 1; + day = doy; + do { + dim = this._getDaysInMonth(year, month - 1); + if (day <= dim) { + break; + } + month++; + day -= dim; + } while (true); + } + + date = this._daylightSavingAdjust(new Date(year, month - 1, day)); + if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { + throw "Invalid date"; // E.g. 31/02/00 + } + return date; + }, + + /* Standard date formats. */ + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) + COOKIE: "D, dd M yy", + ISO_8601: "yy-mm-dd", + RFC_822: "D, d M y", + RFC_850: "DD, dd-M-y", + RFC_1036: "D, d M y", + RFC_1123: "D, d M yy", + RFC_2822: "D, d M yy", + RSS: "D, d M y", // RFC 822 + TICKS: "!", + TIMESTAMP: "@", + W3C: "yy-mm-dd", // ISO 8601 + + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + + /* Format a date object into a string value. + * The format can be combinations of the following: + * d - day of month (no leading zero) + * dd - day of month (two digit) + * o - day of year (no leading zeros) + * oo - day of year (three digit) + * D - day name short + * DD - day name long + * m - month of year (no leading zero) + * mm - month of year (two digit) + * M - month name short + * MM - month name long + * y - year (two digit) + * yy - year (four digit) + * @ - Unix timestamp (ms since 01/01/1970) + * ! - Windows ticks (100ns since 01/01/0001) + * "..." - literal text + * '' - single quote + * + * @param format string - the desired format of the date + * @param date Date - the date value to format + * @param settings Object - attributes include: + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return string - the date in the above format + */ + formatDate: function (format, date, settings) { + if (!date) { + return ""; + } + + var iFormat, + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Format a number, with leading zero if necessary + formatNumber = function(match, value, len) { + var num = "" + value; + if (lookAhead(match)) { + while (num.length < len) { + num = "0" + num; + } + } + return num; + }, + // Format a name, short or long as requested + formatName = function(match, value, shortNames, longNames) { + return (lookAhead(match) ? longNames[value] : shortNames[value]); + }, + output = "", + literal = false; + + if (date) { + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + output += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + output += formatNumber("d", date.getDate(), 2); + break; + case "D": + output += formatName("D", date.getDay(), dayNamesShort, dayNames); + break; + case "o": + output += formatNumber("o", + Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); + break; + case "m": + output += formatNumber("m", date.getMonth() + 1, 2); + break; + case "M": + output += formatName("M", date.getMonth(), monthNamesShort, monthNames); + break; + case "y": + output += (lookAhead("y") ? date.getFullYear() : + (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); + break; + case "@": + output += date.getTime(); + break; + case "!": + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if (lookAhead("'")) { + output += "'"; + } else { + literal = true; + } + break; + default: + output += format.charAt(iFormat); + } + } + } + } + return output; + }, + + /* Extract all possible characters from the date format. */ + _possibleChars: function (format) { + var iFormat, + chars = "", + literal = false, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + chars += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": case "m": case "y": case "@": + chars += "0123456789"; + break; + case "D": case "M": + return null; // Accept anything + case "'": + if (lookAhead("'")) { + chars += "'"; + } else { + literal = true; + } + break; + default: + chars += format.charAt(iFormat); + } + } + } + return chars; + }, + + /* Get a setting value, defaulting if necessary. */ + _get: function(inst, name) { + return inst.settings[name] !== undefined ? + inst.settings[name] : this._defaults[name]; + }, + + /* Parse existing date and initialise date picker. */ + _setDateFromField: function(inst, noDefault) { + if (inst.input.val() === inst.lastVal) { + return; + } + + var dateFormat = this._get(inst, "dateFormat"), + dates = inst.lastVal = inst.input ? inst.input.val() : null, + defaultDate = this._getDefaultDate(inst), + date = defaultDate, + settings = this._getFormatConfig(inst); + + try { + date = this.parseDate(dateFormat, dates, settings) || defaultDate; + } catch (event) { + dates = (noDefault ? "" : dates); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = (dates ? date.getDate() : 0); + inst.currentMonth = (dates ? date.getMonth() : 0); + inst.currentYear = (dates ? date.getFullYear() : 0); + this._adjustInstDate(inst); + }, + + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function(inst) { + return this._restrictMinMax(inst, + this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); + }, + + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function(inst, date, defaultDate) { + var offsetNumeric = function(offset) { + var date = new Date(); + date.setDate(date.getDate() + offset); + return date; + }, + offsetString = function(offset) { + try { + return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + offset, $.datepicker._getFormatConfig(inst)); + } + catch (e) { + // Ignore + } + + var date = (offset.toLowerCase().match(/^c/) ? + $.datepicker._getDate(inst) : null) || new Date(), + year = date.getFullYear(), + month = date.getMonth(), + day = date.getDate(), + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, + matches = pattern.exec(offset); + + while (matches) { + switch (matches[2] || "d") { + case "d" : case "D" : + day += parseInt(matches[1],10); break; + case "w" : case "W" : + day += parseInt(matches[1],10) * 7; break; + case "m" : case "M" : + month += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + case "y": case "Y" : + year += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + } + matches = pattern.exec(offset); + } + return new Date(year, month, day); + }, + newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : + (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + + newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); + if (newDate) { + newDate.setHours(0); + newDate.setMinutes(0); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + } + return this._daylightSavingAdjust(newDate); + }, + + /* Handle switch to/from daylight saving. + * Hours may be non-zero on daylight saving cut-over: + * > 12 when midnight changeover, but then cannot generate + * midnight datetime, so jump to 1AM, otherwise reset. + * @param date (Date) the date to check + * @return (Date) the corrected date + */ + _daylightSavingAdjust: function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }, + + /* Set the date(s) directly. */ + _setDate: function(inst, date, noChange) { + var clear = !date, + origMonth = inst.selectedMonth, + origYear = inst.selectedYear, + newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { + this._notifyChange(inst); + } + this._adjustInstDate(inst); + if (inst.input) { + inst.input.val(clear ? "" : this._formatDate(inst)); + } + }, + + /* Retrieve the date(s) directly. */ + _getDate: function(inst) { + var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : + this._daylightSavingAdjust(new Date( + inst.currentYear, inst.currentMonth, inst.currentDay))); + return startDate; + }, + + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function(inst) { + var stepMonths = this._get(inst, "stepMonths"), + id = "#" + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find("[data-handler]").map(function () { + var handler = { + prev: function () { + $.datepicker._adjustDate(id, -stepMonths, "M"); + }, + next: function () { + $.datepicker._adjustDate(id, +stepMonths, "M"); + }, + hide: function () { + $.datepicker._hideDatepicker(); + }, + today: function () { + $.datepicker._gotoToday(id); + }, + selectDay: function () { + $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); + return false; + }, + selectMonth: function () { + $.datepicker._selectMonthYear(id, this, "M"); + return false; + }, + selectYear: function () { + $.datepicker._selectMonthYear(id, this, "Y"); + return false; + } + }; + $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); + }); + }, + + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function(inst) { + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, + printDate, dRow, tbody, daySettings, otherMonth, unselectable, + tempDate = new Date(), + today = this._daylightSavingAdjust( + new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time + isRTL = this._get(inst, "isRTL"), + showButtonPanel = this._get(inst, "showButtonPanel"), + hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), + navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), + numMonths = this._getNumberOfMonths(inst), + showCurrentAtPos = this._get(inst, "showCurrentAtPos"), + stepMonths = this._get(inst, "stepMonths"), + isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), + currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : + new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + drawMonth = inst.drawMonth - showCurrentAtPos, + drawYear = inst.drawYear; + + if (drawMonth < 0) { + drawMonth += 12; + drawYear--; + } + if (maxDate) { + maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), + maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); + maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); + while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { + drawMonth--; + if (drawMonth < 0) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; + + prevText = this._get(inst, "prevText"); + prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), + this._getFormatConfig(inst))); + + prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + + " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); + + nextText = this._get(inst, "nextText"); + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), + this._getFormatConfig(inst))); + + next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + + " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); + + currentText = this._get(inst, "currentText"); + gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); + currentText = (!navigationAsDateFormat ? currentText : + this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); + + controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + + this._get(inst, "closeText") + "</button>" : ""); + + buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + + (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + + ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; + + firstDay = parseInt(this._get(inst, "firstDay"),10); + firstDay = (isNaN(firstDay) ? 0 : firstDay); + + showWeek = this._get(inst, "showWeek"); + dayNames = this._get(inst, "dayNames"); + dayNamesMin = this._get(inst, "dayNamesMin"); + monthNames = this._get(inst, "monthNames"); + monthNamesShort = this._get(inst, "monthNamesShort"); + beforeShowDay = this._get(inst, "beforeShowDay"); + showOtherMonths = this._get(inst, "showOtherMonths"); + selectOtherMonths = this._get(inst, "selectOtherMonths"); + defaultDate = this._getDefaultDate(inst); + html = ""; + dow; + for (row = 0; row < numMonths[0]; row++) { + group = ""; + this.maxRows = 4; + for (col = 0; col < numMonths[1]; col++) { + selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + cornerClass = " ui-corner-all"; + calender = ""; + if (isMultiMonth) { + calender += "<div class='ui-datepicker-group"; + if (numMonths[1] > 1) { + switch (col) { + case 0: calender += " ui-datepicker-group-first"; + cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; + case numMonths[1]-1: calender += " ui-datepicker-group-last"; + cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; + default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; + } + } + calender += "'>"; + } + calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + + (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + + (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + + this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, + row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers + "</div><table class='ui-datepicker-calendar'><thead>" + + "<tr>"; + thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); + for (dow = 0; dow < 7; dow++) { // days of the week + day = (dow + firstDay) % 7; + thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + + "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; + } + calender += thead + "</tr></thead><tbody>"; + daysInMonth = this._getDaysInMonth(drawYear, drawMonth); + if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { + inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); + } + leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; + curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate + numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); + for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows + calender += "<tr>"; + tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + + this._get(inst, "calculateWeek")(printDate) + "</td>"); + for (dow = 0; dow < 7; dow++) { // create date picker days + daySettings = (beforeShowDay ? + beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); + otherMonth = (printDate.getMonth() !== drawMonth); + unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + tbody += "<td class='" + + ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends + (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months + ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key + (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? + // or defaultDate is current printedDate and defaultDate is selectedDate + " " + this._dayOverClass : "") + // highlight selected day + (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days + (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates + (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day + (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) + ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title + (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions + (otherMonth && !showOtherMonths ? " " : // display for other months + (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + + (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + + (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day + (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months + "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date + printDate.setDate(printDate.getDate() + 1); + printDate = this._daylightSavingAdjust(printDate); + } + calender += tbody + "</tr>"; + } + drawMonth++; + if (drawMonth > 11) { + drawMonth = 0; + drawYear++; + } + calender += "</tbody></table>" + (isMultiMonth ? "</div>" + + ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); + group += calender; + } + html += group; + } + html += buttonPanel; + inst._keyEvent = false; + return html; + }, + + /* Generate the month and year header. */ + _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort) { + + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, + changeMonth = this._get(inst, "changeMonth"), + changeYear = this._get(inst, "changeYear"), + showMonthAfterYear = this._get(inst, "showMonthAfterYear"), + html = "<div class='ui-datepicker-title'>", + monthHtml = ""; + + // month selection + if (secondary || !changeMonth) { + monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; + } else { + inMinYear = (minDate && minDate.getFullYear() === drawYear); + inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); + monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; + for ( month = 0; month < 12; month++) { + if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { + monthHtml += "<option value='" + month + "'" + + (month === drawMonth ? " selected='selected'" : "") + + ">" + monthNamesShort[month] + "</option>"; + } + } + monthHtml += "</select>"; + } + + if (!showMonthAfterYear) { + html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); + } + + // year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ""; + if (secondary || !changeYear) { + html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; + } else { + // determine range of years to display + years = this._get(inst, "yearRange").split(":"); + thisYear = new Date().getFullYear(); + determineYear = function(value) { + var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : + (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : + parseInt(value, 10))); + return (isNaN(year) ? thisYear : year); + }; + year = determineYear(years[0]); + endYear = Math.max(year, determineYear(years[1] || "")); + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; + for (; year <= endYear; year++) { + inst.yearshtml += "<option value='" + year + "'" + + (year === drawYear ? " selected='selected'" : "") + + ">" + year + "</option>"; + } + inst.yearshtml += "</select>"; + + html += inst.yearshtml; + inst.yearshtml = null; + } + } + + html += this._get(inst, "yearSuffix"); + if (showMonthAfterYear) { + html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; + } + html += "</div>"; // Close datepicker_header + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function(inst, offset, period) { + var year = inst.drawYear + (period === "Y" ? offset : 0), + month = inst.drawMonth + (period === "M" ? offset : 0), + day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), + date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); + + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if (period === "M" || period === "Y") { + this._notifyChange(inst); + } + }, + + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function(inst, date) { + var minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + newDate = (minDate && date < minDate ? minDate : date); + return (maxDate && newDate > maxDate ? maxDate : newDate); + }, + + /* Notify change of month/year. */ + _notifyChange: function(inst) { + var onChange = this._get(inst, "onChangeMonthYear"); + if (onChange) { + onChange.apply((inst.input ? inst.input[0] : null), + [inst.selectedYear, inst.selectedMonth + 1, inst]); + } + }, + + /* Determine the number of months to show. */ + _getNumberOfMonths: function(inst) { + var numMonths = this._get(inst, "numberOfMonths"); + return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); + }, + + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function(inst, minMax) { + return this._determineDate(inst, this._get(inst, minMax + "Date"), null); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function(year, month) { + return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function(year, month) { + return new Date(year, month, 1).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function(inst, offset, curYear, curMonth) { + var numMonths = this._getNumberOfMonths(inst), + date = this._daylightSavingAdjust(new Date(curYear, + curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); + + if (offset < 0) { + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + } + return this._isInRange(inst, date); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function(inst, date) { + var yearSplit, currentYear, + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + minYear = null, + maxYear = null, + years = this._get(inst, "yearRange"); + if (years){ + yearSplit = years.split(":"); + currentYear = new Date().getFullYear(); + minYear = parseInt(yearSplit[0], 10); + maxYear = parseInt(yearSplit[1], 10); + if ( yearSplit[0].match(/[+\-].*/) ) { + minYear += currentYear; + } + if ( yearSplit[1].match(/[+\-].*/) ) { + maxYear += currentYear; + } + } + + return ((!minDate || date.getTime() >= minDate.getTime()) && + (!maxDate || date.getTime() <= maxDate.getTime()) && + (!minYear || date.getFullYear() >= minYear) && + (!maxYear || date.getFullYear() <= maxYear)); + }, + + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function(inst) { + var shortYearCutoff = this._get(inst, "shortYearCutoff"); + shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); + return {shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), + monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + }, + + /* Format the given date for display. */ + _formatDate: function(inst, day, month, year) { + if (!day) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; + } + var date = (day ? (typeof day === "object" ? day : + this._daylightSavingAdjust(new Date(year, month, day))) : + this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); + return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); + } +}); + +/* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ +function datepicker_bindHover(dpDiv) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.delegate(selector, "mouseout", function() { + $(this).removeClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).removeClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).removeClass("ui-datepicker-next-hover"); + } + }) + .delegate(selector, "mouseover", function(){ + if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? dpDiv.parent()[0] : datepicker_instActive.input[0])) { + $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); + $(this).addClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).addClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).addClass("ui-datepicker-next-hover"); + } + } + }); +} + +/* jQuery extend now ignores nulls! */ +function datepicker_extendRemove(target, props) { + $.extend(target, props); + for (var name in props) { + if (props[name] == null) { + target[name] = props[name]; + } + } + return target; +} + +/* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ +$.fn.datepicker = function(options){ + + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } + + /* Initialise the date picker. */ + if (!$.datepicker.initialized) { + $(document).mousedown($.datepicker._checkExternalClick); + $.datepicker.initialized = true; + } + + /* Append datepicker main container to body if not exist. */ + if ($("#"+$.datepicker._mainDivId).length === 0) { + $("body").append($.datepicker.dpDiv); + } + + var otherArgs = Array.prototype.slice.call(arguments, 1); + if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + return this.each(function() { + typeof options === "string" ? + $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker._attachDatepicker(this, options); + }); +}; + +$.datepicker = new Datepicker(); // singleton instance +$.datepicker.initialized = false; +$.datepicker.uuid = new Date().getTime(); +$.datepicker.version = "1.11.0"; + +var datepicker = $.datepicker; + + + +}));
\ No newline at end of file diff --git a/scripts/gant.js b/scripts/gant.js new file mode 100644 index 00000000..ae5b63aa --- /dev/null +++ b/scripts/gant.js @@ -0,0 +1,185 @@ + +function checkSwitch(checkswitch) { + + + + if (checkswitch.checked) { + + $('#gantbox').fadeOut(300); + $('.missingdates').fadeOut(300); + graphstate = "GRAPH"; + var fake_e = {}; + fake_e.alpha = 0.1; + tick(fake_e); + + //boxedin=false; + + } else { + $('#gantbox').fadeIn(300); + $('.missingdates').fadeIn(300); + graphstate = "GANTT"; + var fake_e = {}; + fake_e.alpha = 0.1; + tick(fake_e); + + + initAxis(); + + $('#gantbox').scrollLeft(scrollValue); + //boxedin=true; + } + + + + + + +} + +window.onscroll = function (e) { + var horizontal_position = 0; + if (pageXOffset)//usual + horizontal_position = pageXOffset; + else if (document.documentElement.clientWidth) + horizontal_position = document.documentElement.scrollLeft; + else if (document.body)//ie quirks + horizontal_position = document.body.scrollLeft; + + $('.debug').html(scrollValue); + + var your_div = $('#gantbox'); + $('#gantbox').scrollLeft((horizontal_position)); +} + +$('#gantbox').scroll(function () { + scrollValue=$('#gantbox').scrollLeft(); + $('.debug').html(scrollValue); + var fake_e = {}; + fake_e.alpha = 0.0; + tick(fake_e); +}); + + + + +function initAxis() { + + $('#gantbox').html(""); + + + var w,h = $("#gantbox").innerHeight() - 80; + + var bar_height = 20; + var row_height = bar_height + 10; + var vertical_padding = 150 + var bar_start_offset = 40; + var h = 15 * row_height + vertical_padding; + + + var min = deliverables[0].startdate; + var max = deliverables[0].enddate; + + for (var i = 0; i < deliverables.length; i++) { + var deliv = deliverables[i]; + if (min > deliv.startdate) min = deliv.startdate; + if (end < deliv.enddate) end = deliv.enddate; + } + min = new Date(); ///with min + max = new Date(max); + console.log("min "+min+" max "+max); + + ///update interval + var timeDiff = Math.abs(max.getTime() - min.getTime()); + var diffDays = timeDiff / (1000 * 3600 * 24); + w=Math.round(diffDays*15-100); + graphinterval = w / diffDays; + + + var svg = d3.select("#gantbox") + .append("svg") + .attr("width", w) + .attr("height", h); + + var paddingLeft = 150; + var paddingTop = 120; + + var xScale = d3.time.scale() + .domain([min, max]).nice() + .range([paddingLeft, w]); + + var xAxis = d3.svg.axis() + .scale(xScale) + .orient("bottom"); + + // Lines + var line = svg.append("g") + .selectAll("line") + .data(xScale.ticks(40)) + .enter().append("line") + .attr("x1", xScale) + .attr("x2", xScale) + .attr("y1", paddingTop + 30) + .attr("y2", h - 50) + .style("stroke", "#ccc"); + + var y = function (i) { + return i * row_height + paddingTop + bar_start_offset; + } + + labelY = function (i) { + return i * row_height + paddingTop + bar_start_offset + 13; + } + + // Company bars + var bar = svg.selectAll("rect") + .data(function (d) { + return Math.random() * 5; + }); + + bar.enter().append("rect") + .attr("y", -100) + .attr("x", -1000) + .attr("width", 100) + .attr("height", bar_height) + .attr("class", "company-bar") + .on("mouseover", function (d) { + d3.select(this).style("fill", "#F5AF00"); + getCompanyData(String(d.uid)) + }) + .on("mouseout", function () { + d3.select(this).style("fill", "#fc0"); + }); + + + + var label = svg.selectAll("text") + .data(deliverables, function (key) { + return key.id + });; + + label.enter().append("text") + .attr("class", "bar-label") + // .attr("text-anchor","end") + .attr("x", paddingLeft - 10) + .attr("y", function (d, i) { + return labelY(i); + }) + .text(function (d) { + d.id + }); + + + + // Bottom Axis + var btmAxis = svg.append("g") + .attr("transform", "translate(0," + (h - 25) + ")") + .attr("class", "axis") + .call(xAxis); + + // Top Axis + var topAxis = svg.append("g") + .attr("transform", "translate(0," + paddingTop + ")") + .attr("class", "axis") + .call(xAxis); + +}
\ No newline at end of file diff --git a/scripts/rhizicore.js b/scripts/rhizicore.js index 8ccb5718..b8c4efe5 100644 --- a/scripts/rhizicore.js +++ b/scripts/rhizicore.js @@ -1,415 +1,722 @@ +//CORE VARIABLES +var addednodes = []; + +var graphstate = "GRAPH"; +var graphinterval = 0; + +var boxedin = false; + +var deliverables = []; + +var boxedin, nodetext, linktext, link, links, node, nodes, circle; + +var scrollValue = 0; + function myGraph(el) { ///FUNCTIONS - this.addNode = function (id,type,state) { - var node=findNode(id,null); - if(node !== undefined) { + this.addNode = function (id, type, state) { + var start = 0, + end = 0; + var node = findNode(id, null); + if (node !== undefined) { + graph.editState(id, null, "temp"); + } else { + nodes.push({ + "id": id, + "type": type, + "state": state, + "start": start, + "end": end + }); - }else{ - nodes.push({"id":id,"type":type,"state":state}); + } update(); - } } - this.removeNode = function (id,state) { - var i = 0; - var n = findNode(id,state); - while (i < links.length) { - if ((links[i]['source'] === n)||(links[i]['target'] == n)) links.splice(i,1); - else i++; - } - var index = findNodeIndex(id,state); - if(index !== undefined) { - nodes.splice(index, 1); + this.addNodeComplete = function (id, type, state, start, end) { + var node = findNode(id, null); + if (node !== undefined) { + graph.editState(id, null, "temp"); + } else { + nodes.push({ + "id": id, + "type": type, + "state": state, + "start": start, + "end": end + }); + + } update(); - } } - this.addLink = function (sourceId, targetId, name) { - var sourceNode = findNode(sourceId,null); - var targetNode = findNode(targetId,null); + this.removeNode = function (id, state) { + var i = 0; + var n = findNode(id, state); + while (i < links.length) { + if ((links[i]['source'] === n) || (links[i]['target'] == n)) links.splice(i, 1); + else i++; + } + var index = findNodeIndex(id, state); + if (index !== undefined) { + nodes.splice(index, 1); + update(); + } + } + + this.highlightNode = function (id, state) { + var i = 0, + j = 0; + var n = findNode(id, state); + var adjacentnode; + + this.removeHighlight(); + //highlight node + if (n !== undefined && n.state!=="chosen" && n.state!=="temp") { + n.state = "chosen"; + + while (i < links.length) { + if (links[i]['source'] === n){ + adjacentnode=findNode(links[i]['target'].id,null); + if(adjacentnode.state!=="temp")adjacentnode.state = "exit"; + links[i]['state'] = "exit"; + } + if(links[i]['target'] === n) { + adjacentnode=findNode(links[i]['source'].id,null); + if(adjacentnode.state!=="temp")adjacentnode.state = "enter"; + links[i]['state'] = "enter"; + } + i++; + } + update(); + + } - if((sourceNode !== undefined) && (targetNode !== undefined)) { - links.push({"source": sourceNode, "target": targetNode, "name": name}); - update(); - }else{ - } } - this.editLink = function (sourceId, targetId,newname) { - var link= findLink(sourceId, targetId, newname); - if(link !== undefined) { - link.name=newname; + this.removeHighlight = function(){ + var k=0; + while (k < nodes.length) { + if(nodes[k]['state'] === "enter" || nodes[k]['state'] === "exit" || nodes[k]['state'] === "chosen"){ + nodes[k]['state'] = "perm"; + } + k++; + } + var j=0; + //highlight all connections + while (j < links.length) { + links[j]['state'] = "perm"; + j++; + } update(); - }else{ - } } - this.editLinkTarget = function (sourceId, targetId,newTarget) { - var link= findLink(sourceId, targetId, null); - if(link !== undefined ) { - link.target=findNode(newTarget,null); - update(); - }else{ + this.addLink = function (sourceId, targetId, name, state) { + var sourceNode = findNode(sourceId, null); + var targetNode = findNode(targetId, null); - } + if ((sourceNode !== undefined) && (targetNode !== undefined)) { + links.push({ + "source": sourceNode, + "target": targetNode, + "name": name, + "state": state + }); + update(); + } else { + + } } - this.editName = function (id,type,newname) { - var index = findNode(id,type); - if((index !== undefined)){ - index.id=newname; - update(); - } - } + this.editLink = function (sourceId, targetId, newname) { + var link = findLink(sourceId, targetId, newname); + if (link !== undefined) { + link.name = newname; + update(); + } else {} + } + this.editLinkTarget = function (sourceId, targetId, newTarget) { + var link = findLink(sourceId, targetId, null); + if (link !== undefined) { + link.target = findNode(newTarget, null); + update(); + } else { + } + } - this.editType = function (id,state,newtype) { - var index = findNode(id,state); - if((index !== undefined)){ - index.type=newtype; - update(); - } - } + this.editName = function (id, type, newname) { + var index = findNode(id, type); + if ((index !== undefined)) { + index.id = newname; + update(); + } + } - this.editState = function (id,state,newstate) { - var index = findNode(id,state); - if((index !== undefined)){ - index.state=newstate; - update(); - } -} + this.editDates = function (id, type, start, end) { + var index = findNode(id, type); + if ((index !== undefined)) { + index.start = start; + index.end = end; + update(); + } + } -this.findCoordinates = function(id, type){ - var index = findNode(id,type); - if((index !== undefined)){ - $('.typeselection').css('top',index.y-90); - $('.typeselection').css('left',index.x-230); - } -} + this.editType = function (id, state, newtype) { + var index = findNode(id, state); + if ((index !== undefined)) { + index.type = newtype; + update(); + } + } -var findLink = function (sourceId, targetId, name) { - for (var i=0; i < links.length; i++) { - if (links[i].source.id === sourceId && links[i].target.id === targetId){ - return links[i]; + this.editState = function (id, state, newstate) { + var index = findNode(id, state); + if ((index !== undefined)) { + index.state = newstate; + update(); + } } - } -} + this.findCoordinates = function (id, type) { + var index = findNode(id, type); + if ((index !== undefined)) { + $('.typeselection').css('top', index.y - 90); + $('.typeselection').css('left', index.x - 230); + } + } -var findNode = function (id,state) { - //id=id.toLowerCase(); - for (var i=0; i < nodes.length; i++) { - if (nodes[i].id === id || nodes[i].state === state) - return nodes[i] - }; + + + var findLink = function (sourceId, targetId, name) { + for (var i = 0; i < links.length; i++) { + if (links[i].source.id === sourceId && links[i].target.id === targetId) { + return links[i]; + } + } } - var findNodeIndex = function (id,state) { - for (var i=0; i < nodes.length; i++) { - if (nodes[i].id === id || nodes[i].state === state) - return i - }; + + var findNode = function (id, state) { + //id=id.toLowerCase(); + for (var i = 0; i < nodes.length; i++) { + if (nodes[i].id === id || nodes[i].state === state) + return nodes[i] + }; + } + + var findNodeIndex = function (id, state) { + for (var i = 0; i < nodes.length; i++) { + if (nodes[i].id === id || nodes[i].state === state) + return i + }; } ///GRAPH BUILDER var w = $(el).innerWidth(), - h = $(el).innerHeight(); + h = $(el).innerHeight(); var color = d3.scale.category20(); var vis = this.vis = d3.select(el).append("svg:svg") - .attr("width", w) - .attr("height", h) - .append("g") - .call(d3.behavior.zoom().center([w/2,h/2]).on("zoom", zoom)) - .append("g"); + .attr("width", w) + .attr("height", h) + .append("g") + .call(d3.behavior.zoom().center([w / 2, h / 2]).on("zoom", zoom)) + .append("g"); - vis.append("rect") - .attr("class", "overlay") - .attr("width", w) - .attr("height", h); + var force = d3.layout.force() - .gravity(.08) - .distance(120) - .charge(-600) - .size([w, h]); + .distance(120) + .charge(-600) + .size([w, h]); - var nodes = force.nodes(), + nodes = force.nodes(); links = force.links(); - + var update = function () { - vis.selectAll("*").remove(); - var link = vis.selectAll(".link") - .data(links); + vis.selectAll("*").remove(); + link = vis.selectAll(".link") + .data(links); - vis.append("svg:defs").selectAll("marker") - .data(["end"]) // Different link/path types can be defined here - .enter().append("svg:marker") // This section adds in the arrows - .attr("id", String) - .attr("viewBox", "0 -5 10 10") - .attr("refX", 23) - .attr("refY", -1.8) - .attr("markerWidth", 5) - .attr("markerHeight", 5) - .attr("orient", "auto") - .style("fill", "#aaa") - .append("svg:path") - .attr("d", "M0,-5L10,0L0,5"); + vis.append("rect") + .attr("class", "overlay") + .attr("width", w) + .attr("height", h) + .on("click", function() { + mousedown(); + }); - link.enter().append("path") - .attr("d", "M0,-5L10,0L0,5") - .attr("class", "link") - .attr("marker-end", "url(#end)"); + vis.append("svg:defs").selectAll("marker") + .data(["end"]) // Different link/path types can be defined here + .enter().append("svg:marker") // This section adds in the arrows + .attr("id", String) + .attr("viewBox", "0 -5 10 10") + .attr("refX", 23) + .attr("refY", -1.8) + .attr("markerWidth", 5) + .attr("markerHeight", 5) + .attr("orient", "auto") + .style("fill", "#aaa") + .append("svg:path") + .attr("d", "M0,-5L10,0L0,5"); + link.enter().append("path") + .attr("d", "M0,-5L10,0L0,5") + .attr("class", function(d){ + + if(d.state === "enter"){return "enterlink";} + else if(d.state === "exit"){return "exitlink";} + else return "link"; + + }) + .attr("marker-end", "url(#end)"); - var linktext = vis.selectAll(".linklabel").data(links); - linktext.enter() - .append("text") - .attr("class", "linklabel") - .attr("text-anchor", "middle") - .text(function(d) { if(d.name.length<14)return d.name; else return d.name.substring(0,11)+"..."; }) - .on("click",function(d,i) {editLink(d,i);}); - link.exit().remove(); + linktext = vis.selectAll(".linklabel").data(links); + linktext.enter() + .append("text") + .attr("class", "linklabel") + .attr("text-anchor", "middle") + .text(function (d) { + if (d.name.length < 25) return d.name; + else return d.name.substring(0, 14) + "..."; + }) + .on("click", function (d, i) { + editLink(d, i); + }); + link.exit().remove(); - var node = vis.selectAll(".node") - .data(nodes, function(d) { return d.id;}); - var nodeEnter = node.enter() - .append("g").call(force.drag); + node = vis.selectAll(".node") + .data(nodes, function (d) { + return d.id; + }); - var nodetext=nodeEnter.insert("text") - .attr("class", "nodetext") - .attr("dx", 20) - .attr("dy", ".35em") - .text(function(d) {if(d.state==="temp")return d.id+"|"; else{if(d.id.length<14)return d.id; else return d.id.substring(0,11)+"...";}}) - .on("click",function(d,i) {editNode(d,i);showInfo(d,i);}); + var nodeEnter = node.enter() + .append("g").call(force.drag); - var circle= nodeEnter.insert("circle") - .attr("class", "circle") - .attr("r", function(d) { if(d.state==="temp" && d.type!=="empty") return '16px'; else return customSize(d.type); }) - .style("fill", function(d) { return customColor(d.type); }) - .style("stroke-width", function(d){if(d.state==="temp" && d.type!=="empty") return "3px"; else return "1.5px";}) - .style("box-shadow", function(d){ if(d.state==="temp")return "0 0 40px #FFFF8F"; else return "0 0 0px #FFFF8F";}) - .on("click",function(d,i) {showInfo(d,i);}); + nodetext = nodeEnter.insert("text") + .attr("class", "nodetext") + .attr("dx", 20) + .attr("dy", ".35em") + .text(function (d) { + if (d.state === "temp") return d.id + "|"; + else { + if (d.id.length < 14) return d.id; + else return d.id.substring(0, 11) + "..."; + } + }) + .on("click", function (d, i) { + editNode(d, i); + showInfo(d, i); + }); - node.exit().remove(); + circle = nodeEnter.insert("circle") + .attr("class", "circle") + .attr("r", function (d) { + if (d.state === "temp" && d.type !== "empty") return '16px'; + else return customSize(d.type); + }) + .style("fill", function (d) { + return customColor(d.type); + }) + .style("stroke", function (d) { + if(d.state === "chosen"){ + return "#EDE275"; + } + if(d.state === "enter"){ + return "#EDE275"; + }if(d.state === "exit"){ + return "#EDE275"; + }else{ return "#fff";} + }) + .style("stroke-width", function (d) { + if (d.state === "temp" && d.type !== "empty" || d.state==="chosen") return "3px"; + else return "1.5px"; + }) + .style("box-shadow", function (d) { + if (d.state === "temp") return "0 0 40px #FFFF8F"; + else return "0 0 0px #FFFF8F"; + }) + .on("click", function (d, i) { + showInfo(d, i); + }); - //d3.select("body").on("mousedown", mousedown); + node.exit().remove(); - function transform(d) { - return "translate(" + d.x + "," + d.y + ")"; - } + //d3.select("body").on("mousedown", mousedown); - function getCentroid(selection) { - var element = selection.node(), - bbox = element.getBBox(); - return [bbox.x + bbox.width/2, bbox.y + bbox.height/2]; - } - var boxedin=false; - force.on("tick", function() { - - if(boxedin){ - circle.attr("cx", function(d) { return d.x = Math.max(14, Math.min(w - 14, d.x)); }) - .attr("cy", function(d) { return d.y = Math.max(114, Math.min(h - 14, d.y)); }); + force.on("tick", tick); - nodetext.attr("transform",transform); - }else{ - node.attr("transform",transform); - } - - link.attr("d", function(d) { - var dx = d.target.x - d.source.x, - dy = d.target.y - d.source.y, - dr = Math.sqrt(dx * dx + dy * dy); - return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; - }); + //update deliverables + deliverables = []; + for (var i = 0; i < nodes.length; i++) { + var current = nodes[i]; + if (current.type === "deliverable") { + deliverables.push({ + "id": nodes[i].id, + "startdate": nodes[i].start, + "enddate": nodes[i].end + }); + } + //Do something + } - linktext.attr("transform", function(d) { - return "translate(" + (d.source.x + d.target.x) / 2 + "," - + (d.source.y + d.target.y) / 2 + ")"; }); - }); - - force.nodes(nodes) - .links(links) - .start(); + force.nodes(nodes) + .links(links) + .start(); } update(); - } +} - graph = new myGraph(document.body); +graph = new myGraph(document.body); -var addednodes=[]; +function tick(e) { + //console.log(e); - function zoom() { - //vis.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); - } + function transform(d) { + if (graphstate === "GRAPH" || d.type === "deliverable") { + if (d.state === "temp") { + if (d.type === "empty") { + d.x = 180; + d.y = 150; - function showInfo(d,i){ - if(d.type==="deliverable"){ - $('.info').html('<form id="editbox"><label>name:</label><input id="editboxname"/><label>description:</label><input id="editdescription"/><label>URL:</label><input id="editurl"/><label>Start date:</label><input id="editstartdate"/><label>End date:</label><input id="editenddate"/><button>edit</button></form>'); - }else{ - $('.info').html('<form id="editbox"><label>name:</label><input id="editboxname"/><label>description:</label><input id="editdescription"/><label>URL:</label><input id="editurl"/><button>edit</button></form>'); - + } else { + if (addednodes.length % 2 === 0) { + d.x = 180; + d.y = 150; + } else { + d.x = 300; + d.y = 150; + + } + } + return "translate(" + d.x + "," + d.y + ")"; + } else { + return "translate(" + d.x + "," + d.y + ")"; + } + } else { + return "translate(0,0)"; + } + return "translate(" + d.x + "," + d.y + ")"; } - $('#editboxname').val(d.id); - $('#editdescription').val(d.type); - $('#editurl').val('www.'+d.id+'.com'); - //switchtype start date end date - } + + + function getCentroid(selection) { + var element = selection.node(), + bbox = element.getBBox(); + return [bbox.x + bbox.width / 2, bbox.y + bbox.height / 2]; + } + + + if (graphstate === "GANTT") { + var k = 20 * e.alpha; + var today = new Date(); + var missingcounter = 0; + nodes.forEach(function (d, i) { - function mousedown(){ - $('.editinfo').css('top',-100); - $('.editinfo').css('left',0); - d3.event.stopPropagation(); - } + if ((d.start === 0 || d.end === 0) ){ + d.x = 450 + missingcounter * 100; + d.y = window.innerWidth / 2; + if (missingcounter >= 6) { + d.x = 450 + (missingcounter - 6) * 100; + d.y = window.innerWidth / 2 + 50; + } + missingcounter++; + } else { + //var min= 150+graphinterval*Math.ceil(Math.abs(d.start.getTime() - today.getTime()) / (1000 * 3600 * 24)) - $('.gantbox').scrollLeft(); + //var max= 150+graphinterval*Math.ceil(Math.abs(d.end.getTime() - d.start.getTime()) / (1000 * 3600 * 24)) - $('.gantbox').scrollLeft(); + //d.x = min+Math.sin(today.getTime()/1000*Math.PI*2/10)*max; + d.x = 150 + graphinterval * Math.ceil(Math.abs(d.start.getTime() - today.getTime()) / (1000 * 3600 * 24)) - $('#gantbox').scrollLeft(); + d.y = 150 + d.start.getHours() * 17; + } + if(d.state==="chosen"){ + scrollValue=d.x; + } - function AddedUnique(newnode){ - truth=true; - for(var p=0;p<addednodes.length;p++){ - if(addednodes[p]===newnode){ - truth=false; - } + }); + } else { + /*nodes.forEach(function (d, i) { + if(d.state==="chosen"){ + d.x=window.innerWidth/2; + d.y=window.innerHeight/2; + } + });*/ + + + + var k = 15 * e.alpha; + links.forEach(function (d, i) { + d.source.x -= k; + d.target.x += k; + d.source.y -= k / 3; + d.target.y += k / 3; + }); } - return truth; - } - - function editNode(d,i){ - var oldname=d.id; - $('.editinfo').css('top',d.y-12); - $('.editinfo').css('left',d.x+18); - $('#editname').val(oldname); + if (boxedin) { + circle.attr("cx", function (d) { + return d.x = Math.max(14, Math.min(w - 14, d.x)); + }) + .attr("cy", function (d) { + return d.y = Math.max(114, Math.min(h - 14, d.y)); + }); - $('#editform').submit(function () { - if(AddedUnique($('#editname').val())){ - $('.editinfo').css('top',-100); - $('.editinfo').css('left',0); - graph.editName(oldname,"whatever",$('#editname').val()); - var index=addednodes.indexOf(oldname); - addednodes[index]=$('#editname').val(); - console.log(addednodes[index]); - }else{ - var choice=$('#editname').val(); - $('#editname').val(choice+"(2)"); + nodetext.attr("transform", transform); + } else { + node.attr("transform", transform); } - return false; - }); - } - function editLink(d,i){ - var dx=(d.source.x + d.target.x) / 2; - var dy=(d.source.y + d.target.y) / 2; - var oldname=d.name; - $('.editlinkinfo').css('top',dy-17); - $('.editlinkinfo').css('left',dx-18); - $('#editlinkname').val(oldname); + link.attr("d", function (d) { + + if (graphstate === "GRAPH") { + var dx = d.target.x - d.source.x, + dy = d.target.y - d.source.y, + dr = Math.sqrt(dx * dx + dy * dy); + return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; + } else if (graphstate === "GANTT") { + if(d.state=== "enter" || d.state=== "exit"){ + var dx = d.target.x - d.source.x, + dy = d.target.y - d.source.y, + dr = Math.sqrt(dx * dx + dy * dy)*5; + return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; + }else{ + + return "M" + 0 + "," + 0 + "A" + dr + "," + dr + " 0 0,1 " + 0 + "," + 0; + } + } - $('#editlinkform').submit(function () { - graph.editLink(d.source.id,d.target.id,$('#editlinkname').val()); - $('.editlinkinfo').css('top',-100); - $('.editlinkinfo').css('left',0); - return false; }); - } + linktext.attr("transform", function (d) { + if (graphstate === "GRAPH") { + return "translate(" + (d.source.x + d.target.x) / 2 + "," + (d.source.y + d.target.y) / 2 + ")"; + } else { + return "translate(0,0)"; + } + }); - function customColor(type){ - var color; - switch(type){ - case "person": - color='#FCB924'; - break; - case "project": - color='#009DDC'; - break; - case "skill": - color='#62BB47'; - break; - case "deliverable": - color='#E03A3E'; - break; - case "objective": - color='#933E99'; - break; - case "empty": - color="#080808"; - break; - case 6: - color="#fff"; - break; - } - return color; } -function customSize(type){ - var size; - switch(type){ - case "person": - size=12; - break; - case "project": - size=12; - break; - case "skill": - size=12; - break; - case "deliverable": - size=12; - break; - case "objective": - size=12; - break; - case "empty": - size=9; - break; - case 6: - size=0x30334C; - break; - } - return size; + +function deliverableTest() { + for (var i = 0; i < 140; i++) { + var end = randomDate(new Date(), new Date("01-01-2018")); + var start = randomDate(new Date(), end); + graph.addNodeComplete("Task " + i, "deliverable", "perm", start, end); + } + + for (var i = 0; i < 140; i++) { + var endindex = Math.floor(Math.random() * i); + var startindex = Math.floor(Math.random() * i); + if(nodes[endindex].start>nodes[startindex].start){ + graph.addLink("Task " + startindex, "Task " + endindex, " ", "perm"); + }else{ + graph.addLink("Task " + endindex, "Task " + startindex, " ", "perm"); + } + } + + function randomDate(start, end) { + return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); + } +} + + + + +function zoom() { + //vis.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); } +function showInfo(d, i) { + + graph.highlightNode(d.id,null); + + if (d.type === "deliverable") { + $('.info').html('<form id="editbox"><label>description:</label><input id="editdescription"/><label>URL:</label><input id="editurl"/><label>Start date:</label><input id="editstartdate"/><label>End date:</label><input id="editenddate"/><button>Save</button></form><div id="deletenode"><button>Delete</button></div>'); + } else { + $('.info').html('<form id="editbox"><label>description:</label><input id="editdescription"/><label>URL:</label><input id="editurl"/><button>Save</button></form><div id="deletenode"><button>Delete</button></div>'); + + + } + $("#editenddate").datepicker({ + inline: true, + showOtherMonths: true, + dayNamesMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + }); + + $("#editstartdate").datepicker({ + inline: true, + showOtherMonths: true, + dayNamesMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + }); + + $('#editdescription').val(d.type); + + $('#editurl').val('www.' + d.id + '.com'); + + if (d.type === "deliverable") { + $('#editstartdate').val(d.start); + $('#editenddate').val(d.end); + } + + $("#editbox").submit(function () { + if (d.type === "deliverable") graph.editDates(d.id, null, new Date($("#editstartdate").val()), new Date($("#editenddate").val())); + return false; + }); + + $("#deletenode").click(function () { + if (confirm('This node and all its connections will be deleted, are you sure?')) { + graph.removeNode(d.id, null); + } + }); +} +function mousedown() { + $('.editinfo').css('top', -100); + $('.editinfo').css('left', 0); + $('.editlinkinfo').css('top', -100); + $('.editlinkinfo').css('left', 0); + d3.event.stopPropagation(); + graph.removeHighlight(); +} +function AddedUnique(newnode) { + truth = true; + for (var p = 0; p < addednodes.length; p++) { + if (addednodes[p] === newnode) { + truth = false; + } + } + return truth; +} +function editNode(d, i) { + var oldname = d.id; + $('.editinfo').css('top', d.y - 12); + $('.editinfo').css('left', d.x + 18); + $('#editname').val(oldname); + $('#editform').submit(function () { + if (AddedUnique($('#editname').val())) { + $('.editinfo').css('top', -100); + $('.editinfo').css('left', 0); + graph.editName(oldname, "whatever", $('#editname').val()); + var index = addednodes.indexOf(oldname); + addednodes[index] = $('#editname').val(); + console.log(addednodes[index]); + } else { + var choice = $('#editname').val(); + $('#editname').val(choice + "(2)"); + } + return false; + }); +} +function editLink(d, i) { + var dx = (d.source.x + d.target.x) / 2; + var dy = (d.source.y + d.target.y) / 2; + var oldname = d.name; + $('.editlinkinfo').css('top', dy - 17); + $('.editlinkinfo').css('left', dx - 18); + $('#editlinkname').val(oldname); + $('#editlinkform').submit(function () { + graph.editLink(d.source.id, d.target.id, $('#editlinkname').val()); + $('.editlinkinfo').css('top', -100); + $('.editlinkinfo').css('left', 0); + return false; + }); +} +function customColor(type) { + var color; + switch (type) { + case "person": + color = '#FCB924'; + break; + case "project": + color = '#009DDC'; + break; + case "skill": + color = '#62BB47'; + break; + case "deliverable": + color = '#E03A3E'; + break; + case "objective": + color = '#933E99'; + break; + case "empty": + color = "#080808"; + break; + case 6: + color = "#fff"; + break; + } + return color; +} +function customSize(type) { + var size; + switch (type) { + case "person": + size = 12; + break; + case "project": + size = 12; + break; + case "skill": + size = 12; + break; + case "deliverable": + size = 12; + break; + case "objective": + size = 12; + break; + case "empty": + size = 9; + break; + case 6: + size = 0x30334C; + break; + } + return size; +}
\ No newline at end of file diff --git a/scripts/robot.js b/scripts/robot.js index f3ccc989..3292b51f 100644 --- a/scripts/robot.js +++ b/scripts/robot.js @@ -1,16 +1,23 @@ -var sentence="#Rhizibot is showing you a #tutorial "; +var sentence=""; +/*sentence+="#Rhizibot is showing you a #tutorial "; sentence+="#Rhizi visualizes data with #Graphs "; sentence+="#Graphs are great to display #relationships "; sentence+="#nodes are #entities "; sentence+="#nodes are #concepts "; sentence+="#entities can be #concepts "; sentence+="#concepts have context with #relationships "; -sentence+="We built this entire graph in 30 seconds, try it out yourself!"; +sentence+="We built this entire graph in 30 seconds, try it out yourself!";*/ sentence=""; var arr=["works on","contibutes to","likes","knows","is an expert at","donates to"]; -for(var a=0;a<30;a++){ - sentence+="#"+names[Math.floor(Math.random()*names.length)]+" "+arr[Math.round(Math.random()*4)]+" #"+sugg[Math.floor(Math.random()*sugg.length)]+" "; +var arr2=["is used by","is liked by","employs"]; +for(var a=0;a<10;a++){ + if(Math.random()>0.5){ + sentence+="#"+names[Math.floor(Math.random()*names.length)]+" "+arr[Math.round(Math.random()*4)]+" #"+sugg[Math.floor(Math.random()*sugg.length)]+" "; + }else{ + sentence+="#"+sugg[Math.floor(Math.random()*sugg.length)]+" "+arr2[Math.round(Math.random()*2)]+" #"+names[Math.floor(Math.random()*names.length)]+" "; + + } } var counter=0; @@ -23,12 +30,12 @@ setTimeout( Robot, 1000 ); }); -/* -var answer = confirm ("Would you like a tutorial?") + +/*var answer = confirm ("Would you like a tutorial?") if (answer) -setTimeout( Robot, 100 ); +setTimeout( Robot, 100 );*/ + -*/ function Robot(){ diff --git a/scripts/textanalysis.js b/scripts/textanalysis.js index 002ed516..1306a863 100644 --- a/scripts/textanalysis.js +++ b/scripts/textanalysis.js @@ -1,269 +1,255 @@ var text = ""; var opened = false; -var sugg=["AJAX","Neo4J","Rhizi","Research","CRI","SageBionetworks","Hero.coli","CSS","NodeJS","HTML5","Angular","D3","ProofOfConcept","Graphs","CloudComputing","BigData","ProblemSolving","PHP","Javascript","BackBone","Cooperation","SemanticWeb"]; -var typeindex=0; -var names=["Jean-ChristopheThalabard","MaévaVignes","AbdelElAbed","ValérieTaly","SébastienDutreuil","AntoineBERGEL","AntoineAngot","JérômeFeret","CharlèneGayrard","HugoJimenezPerez","CaterinaUrban","GaëlleChevalon","IanMarcus","AntoineTALY","ChantalLOTTON","Ana-MariaLennon-Duménil","FrédériqueCarlier-Grynkorn","PascalMartin","TamaraMilosevic","NicolasCarpi","StéphaneDaoudy","DanijelaMaticVignjevic","EugenioCinquemani","VincentDAHIREL","MartinLenz","MaïlysChassagne","AnneSchmidt","SophieSacquinMora","Richard-EmmanuelEastes","MichelMorange","EwaZlotek-Zlotkiewicz","A.m.o.d.s.e.nC.h.o.t.i.a","AlexandreVaugoux","AnnemiekJMCornelissen","ClémentNizak","AntoineFrenoy","ArielB.Lindner","BenjaminBrogniart","ChristopheZimmer","ClaireRibrault","DavidTareste","DenisLafeuille","DorGarbash","DusanMISEVIC","EddaNitschke","FrançoisTaddei","GregoryBatt","JeanLucLebrun","JesseHimmelstein","KevinLhoste","LauraCiriani","LivioRiboli-Sasco","NathalieSussfeld","JakeEdwinWintermute","MarlyneNogbou","MatthieuPiel","PascalHersen","Pierre-YvesBourguignon","TimoBetz","RaphaëlGoujet","StéphaneDebove","VincentDanos","TamKienDuong"]; -var nodetypes=["person","project","skill","deliverable","objective"]; -var previousorder="NOTHING"; -var nodecounter=0; -var nodereplaced=false; +var sugg = ["AJAX", "Neo4J", "Rhizi", "Research", "CRI", "SageBionetworks", "Hero.coli", "CSS", "NodeJS", "HTML5", "Angular", "D3", "ProofOfConcept", "Graphs", "CloudComputing", "BigData", "ProblemSolving", "PHP", "Javascript", "BackBone", "Cooperation", "SemanticWeb"]; +var typeindex = 0; +var names = ["Jean-ChristopheThalabard", "MaévaVignes", "AbdelElAbed", "ValérieTaly", "SébastienDutreuil", "AntoineBERGEL", "AntoineAngot", "JérômeFeret", "CharlèneGayrard", "HugoJimenezPerez", "CaterinaUrban", "GaëlleChevalon", "IanMarcus", "AntoineTALY", "ChantalLOTTON", "Ana-MariaLennon-Duménil", "FrédériqueCarlier-Grynkorn", "PascalMartin", "TamaraMilosevic", "NicolasCarpi", "StéphaneDaoudy", "DanijelaMaticVignjevic", "EugenioCinquemani", "VincentDAHIREL", "MartinLenz", "MaïlysChassagne", "AnneSchmidt", "SophieSacquinMora", "Richard-EmmanuelEastes", "MichelMorange", "EwaZlotek-Zlotkiewicz", "A.m.o.d.s.e.nC.h.o.t.i.a", "AlexandreVaugoux", "AnnemiekJMCornelissen", "ClémentNizak", "AntoineFrenoy", "ArielB.Lindner", "BenjaminBrogniart", "ChristopheZimmer", "ClaireRibrault", "DavidTareste", "DenisLafeuille", "DorGarbash", "DusanMISEVIC", "EddaNitschke", "FrançoisTaddei", "GregoryBatt", "JeanLucLebrun", "JesseHimmelstein", "KevinLhoste", "LauraCiriani", "LivioRiboli-Sasco", "NathalieSussfeld", "JakeEdwinWintermute", "MarlyneNogbou", "MatthieuPiel", "PascalHersen", "Pierre-YvesBourguignon", "TimoBetz", "RaphaëlGoujet", "StéphaneDebove", "VincentDanos", "TamKienDuong"]; +var nodetypes = ["person", "project", "skill", "deliverable", "objective"]; +var previousorder = "NOTHING"; +var nodecounter = 0; +var nodereplaced = false; -var newlink=""; +var newlink = ""; -var ExecutionStack=[]; +var ExecutionStack = []; $('#textanalyser').autocompleteTrigger({ - triggerStart : '#', - triggerEnd: '', - source: sugg + triggerStart: '#', + triggerEnd: '', + source: sugg }); -$(document).keydown(function(e){ - //RIGHT - if (e.keyCode == 37 && (previousorder==="EDITNODE" || previousorder==="NEWNODE")) { - changeType(null,"up"); +$('#textanalyser').submit(function () { + alert("kldffsgdklgfdmlfdkfglfgsdklgfdkfssfglk,dgf"); + if (previousorder === "EDITNODE") { + $('#textanalyser').val(text + " "); + } return false; - } +}); - //LEFT - if (e.keyCode == 39 && (previousorder==="EDITNODE" || previousorder==="NEWNODE")) { - changeType(null,"down"); - return false; - } +$(document).keydown(function (e) { + //RIGHT + if (e.keyCode == 37 && (previousorder === "EDITNODE" || previousorder === "NEWNODE")) { + changeType(null, "up"); + return false; + } - //ENTER - if(e.keyCode == 13){ - if(previousorder==="CLOSENODE"){ - $('#textanalyser').val(text+" "); - } + //LEFT + if (e.keyCode == 39 && (previousorder === "EDITNODE" || previousorder === "NEWNODE")) { + changeType(null, "down"); + return false; } - if(e.keyCode == 73){ - zoom(); + + + if (e.keyCode == 73) { + zoom(); } //DELTE - if(e.keyCode == 46 || e.keyCode == 8){ - if(previousorder==="CLOSENODE" || previousorder==="NEWNODE")return false; + if (e.keyCode == 46 || e.keyCode == 8) { + if (previousorder === "CLOSENODE" || previousorder === "NEWNODE") return false; } - }); +}); -function changeType(arg,id){ - if(arg==='up'){ - if(typeindex<4)typeindex++; - else typeindex=0; - graph.editType(id,"temp",nodetypes[typeindex]); +function changeType(arg, id) { + if (arg === 'up') { + if (typeindex < 4) typeindex++; + else typeindex = 0; + graph.editType(id, "temp", nodetypes[typeindex]); - $('.typeselection').html('<table><tr><td style="height:28px"></td></tr><tr><td>'+"Chosen Type: "+nodetypes[typeindex]+'</td></tr></table>'); - }else{ - if(typeindex>0)typeindex--; - else typeindex=4; + $('.typeselection').html('<table><tr><td style="height:28px"></td></tr><tr><td>' + "Chosen Type: " + nodetypes[typeindex] + '</td></tr></table>'); + } else { + if (typeindex > 0) typeindex--; + else typeindex = 4; - if(previousorder==="EDITNODE")graph.editType(id,"temp",nodetypes[typeindex]); - $('.typeselection').html('<table><tr><td style="height:28px"></td></tr><tr><td>'+"Chosen Type: "+nodetypes[typeindex]+'</td></tr></table>'); + if (previousorder === "EDITNODE") graph.editType(id, "temp", nodetypes[typeindex]); + $('.typeselection').html('<table><tr><td style="height:28px"></td></tr><tr><td>' + "Chosen Type: " + nodetypes[typeindex] + '</td></tr></table>'); - } + } } -window.setInterval(function(){ - if ($('#textanalyser').val() != text ) - { - $('.typeselection').css('top',-300); - $('.typeselection').css('left',0); - // text changed - text = $('#textanalyser').val(); - console.log(text); - ExecutionStack.push(text); - TextAnalyser(text); - +window.setInterval(function () { + if ($('#textanalyser').val() != text) { + $('.typeselection').css('top', -300); + $('.typeselection').css('left', 0); + // text changed + text = $('#textanalyser').val(); + //console.log(text); + ExecutionStack.push(text); + TextAnalyser(text); + } - },5); +}, 5); -function TextAnalyser(newtext){ - var states=["NOTHING","NEWNODE","EDITNODE","CLOSENODE","NEWLINK","EDITLINK"]; - var order=previousorder; - var nodetype="new"; - var array=[]; - var arraytext=""; +function TextAnalyser(newtext) { + var states = ["NOTHING", "NEWNODE", "EDITNODE", "CLOSENODE", "NEWLINK", "EDITLINK"]; + var order = previousorder; + var nodetype = "new"; + var array = []; + var arraytext = ""; - var newnode=""; - var index=newtext.length; + var newnode = ""; + var index = newtext.length; - array=newtext.match(/([#]\w+)/g); - for(var i=nodecounter-1;i<=nodecounter;i++){ - if(addednodes[i]!==undefined)newlink=newtext.replace(addednodes[i],""); - newlink=newlink.replace("#",""); - } + array = newtext.match(/([#]\w+)/g); + for (var i = nodecounter - 1; i <= nodecounter; i++) { + if (addednodes[i] !== undefined) newlink = newtext.replace(addednodes[i], ""); + newlink = newlink.replace("#", ""); + } - var lastchar=newtext.charAt(newtext.length-1); - switch(lastchar){ + var lastchar = newtext.charAt(newtext.length - 1); + switch (lastchar) { case " ": - if(previousorder==="NEWNODE")order="CLOSENODE"; - if(previousorder==="EDITNODE")order="CLOSENODE"; - if(previousorder==="NEWLINK")order="EDITLINK"; - break; + if (previousorder === "NEWNODE") order = "CLOSENODE"; + if (previousorder === "EDITNODE") order = "CLOSENODE"; + if (previousorder === "NEWLINK") order = "EDITLINK"; + break; case "#": - if(previousorder==="NEWNODE")order="EDITNODE"; - else if(previousorder==="EDITNODE")order="EDITNODE"; - else order="NEWNODE"; - break; + if (previousorder === "NEWNODE") order = "EDITNODE"; + else if (previousorder === "EDITNODE") order = "EDITNODE"; + else order = "NEWNODE"; + break; default: - if(previousorder==="NEWNODE")order="EDITNODE"; - if(previousorder==="CLOSENODE")order="NEWLINK"; - if(previousorder==="NEWLINK")order="EDITLINK"; - break; - } + if (previousorder === "NEWNODE") order = "EDITNODE"; + if (previousorder === "CLOSENODE") order = "NEWLINK"; + if (previousorder === "NEWLINK") order = "EDITLINK"; + break; + } + + //console.log(order); - console.log(order); + //ORDER CYCLE + previousorder = order; + var lol = ""; + for (var k = 0; k < addednodes.length; k++) { + lol += k + " " + addednodes[k] + "|"; + } + console.log(lol); - //ORDER CYCLE - previousorder=order; - var lol=""; - for(var k=0;k<addednodes.length;k++){ - lol+=k+" "+addednodes[k]+"|"; - } - console.log(lol); - - //edit words - switch(order){ - case "NOTHING": - newnode=""; + //edit words + switch (order) { + case "NOTHING": + newnode = ""; break; - case "NEWNODE": - newnode=""; + case "NEWNODE": + newnode = ""; break; - case "EDITNODE": - do{ - newnode=newtext.charAt(index)+newnode; - newnode=newnode.replace(/\s/g, ''); - index--; - }while(newtext.charAt(index)!=="#" && index>0); + case "EDITNODE": + do { + newnode = newtext.charAt(index) + newnode; + newnode = newnode.replace(/\s/g, ''); + index--; + } while (newtext.charAt(index) !== "#" && index > 0); break; - case "CLOSENODE": - do{ - newnode=newtext.charAt(index)+newnode; - newnode=newnode.replace(/\s/g, ''); - index--; - }while(newtext.charAt(index)!=="#" && index>0); + case "CLOSENODE": + do { + newnode = newtext.charAt(index) + newnode; + newnode = newnode.replace(/\s/g, ''); + index--; + } while (newtext.charAt(index) !== "#" && index > 0); break; - case "NEWLINK": + case "NEWLINK": - newlink=""; + newlink = ""; break; - case "EDITLINK": - newnode=""; + case "EDITLINK": + newnode = ""; break; - } + } - $('.debug').html("node n "+nodecounter+" state: "+order+" nodename: |"+newnode+ "| link: |"+newlink+"| lastnode: |"+addednodes[nodecounter-2]+"rep: "+nodereplaced); + //$('.debug').html("node n "+nodecounter+" state: "+order+" nodename: |"+newnode+ "| link: |"+newlink+"| lastnode: |"+addednodes[nodecounter-2]+"rep: "+nodereplaced); - switch(order){ - case states[0]: - window.setTimeout(function(){$('#textanalyser').css('box-shadow','0 0 0px #303030')},200); + switch (order) { + case states[0]: + window.setTimeout(function () { + $('#textanalyser').css('box-shadow', '0 0 0px #303030') + }, 200); break; - case states[1]: + case states[1]: + - - if(nodecounter%2 === 0){ - graph.addNode("",nodetypes[typeindex],"temp"); - }else{ - graph.addNode("",nodetypes[typeindex],"temp"); + if (nodecounter % 2 === 0) { + graph.addNode("", nodetypes[typeindex], "temp"); + } else { + graph.addNode("", nodetypes[typeindex], "temp"); } - graph.editType("x","temp",nodetypes[typeindex]); + graph.editType("x", "temp", nodetypes[typeindex]); nodecounter++; break; - case states[2]: - if(nodereplaced===true){ - //graph.removeLink(); - //graph.addLink - graph.addNode(newnode,nodetypes[typeindex],"temp"); - graph.editLinkTarget(addednodes[nodecounter-2],replacement,newnode); - replacement=""; - } - nodereplaced=false; - if(AddedUnique(newnode)){ - - }else if(nodecounter%2===0){ - console.log("not unique, replace"); - graph.addLink(addednodes[nodecounter-2],newnode,newlink); - graph.removeNode("x","temp"); - nodereplaced=true; - replacement=newnode; - } - graph.editName("x","temp",newnode); - graph.findCoordinates("x","temp"); - break; - case states[3]: - - nodereplaced=false; - graph.editState("x","temp","perm"); - addednodes.push(newnode); - if(Unique(newnode))sugg.push(newnode); - - if(nodecounter%2 === 0){ - - $('#textanalyser').css('box-shadow','0 0 30px #FFFF8F'); - $('#textanalyser').val(""); - graph.removeNode("x","temp"); - previousorder=states[0]; - newnode=""; - } - break; - case states[4]: - graph.addNode("","empty","temp"); - graph.addLink(addednodes[nodecounter-1],"",newlink); - break; - case states[5]: - graph.editLink(addednodes[nodecounter-1],"",newlink); - break; - } - - - - } - - - - - function Unique(newnode){ - truth=true; - for(var p=0;p<sugg.length;p++){ - if(sugg[p]===newnode){ - truth=false; - } - } - return truth; - } - - - - - - - + case states[2]: + if (nodereplaced === true) { + //graph.removeLink(); + //graph.addLink + graph.addNode(newnode, nodetypes[typeindex], "temp"); + graph.editLinkTarget(addednodes[nodecounter - 2], replacement, newnode); + replacement = ""; + } + nodereplaced = false; + if (AddedUnique(newnode)) { + } else if (nodecounter % 2 === 0) { + console.log("not unique, replace"); + graph.addLink(addednodes[nodecounter - 2], newnode, newlink, "temp"); + graph.removeNode("x", "temp"); + nodereplaced = true; + replacement = newnode; + } + graph.editName("x", "temp", newnode); + graph.findCoordinates("x", "temp"); + break; + case states[3]: + nodereplaced = false; + graph.editState("x", "temp", "perm"); + addednodes.push(newnode); + if (Unique(newnode)) sugg.push(newnode); + if (nodecounter % 2 === 0) { + $('#textanalyser').css('box-shadow', '0 0 30px #FFFF8F'); + $('#textanalyser').val(""); + graph.removeNode("x", "temp"); + previousorder = states[0]; + newnode = ""; + } + break; + case states[4]: + graph.addNode("", "empty", "temp"); + graph.addLink(addednodes[nodecounter - 1], "", newlink, "perm"); + break; + case states[5]: + graph.editLink(addednodes[nodecounter - 1], "", newlink); + break; + } +} +function Unique(newnode) { + truth = true; + for (var p = 0; p < sugg.length; p++) { + if (sugg[p] === newnode) { + truth = false; + } + } + return truth; +}
\ No newline at end of file |
