<commit_before>/* ***************************************************************************
 * controls.js
 * ===========
 * Reusable complex UI controls implemented in Javascript are placed here.
 *
 * Dependencies: utils.js
 *****************************************************************************/

/* Classes
 **********/

/*************************************
 ToolbarControl
 --------------
 Used for creating a set of controls to issue commands to the application by
 the user.

 Parameters
  container
   The DOM element that controls are put in. Will be cleared at init.
 *************************************/
function ToolbarControl(container) {
    clearElement(container);
    this.element = container;
}
    ToolbarControl.prototype.addButton = function(label, callback) {
        button = document.createElement("button");
        button.type = "button";
        button.appendChild(document.createTextNode(label));
        button.addEventListener("click", callback, false);
        this.element.appendChild(button);
    }

/*************************************
 ListViewControl
 ---------------
 Manages a tabular data view, similar to the ListView controls you find in
 OS APIs.

 Control is implemented as two separate <table> elements. This allows the
 content to scroll independantly of the headers if needed. Early versions of
 the control contained both parts in the same table, but it eventually
 proved difficult to operate properly with CSS and JS.

 Parameters
  parent
   DOM element that will hold the control. New element will be appended to it.

 CSS styling
    Every element generated by the control is given a class name, so it can be
   styled with CSS. To prevent conflicts with other classes used on the page,
   all names are prefixed with uilc (UI List Control). Class tree follows:

   <table> - Head table - uilcHeadTable
   \- <thead> - Header container - uilcHead
    \- <tr> - Header row - uilcHeadRow
     |- <th> - Header cell (selection check) - uilcHeadSelectBox
     |\- <input> - Select all checkbox - uilcHeadSelect
     |- <th> - Header cell (header item) - uilcHeadItem
     |- ...
     \- <th> - Header scroll bar buffer (no content) - uilcHeadScrollBuffer
   <table> - Main element - uilcTable
   \- <tbody> - Main body - uilcBody
    \- <tr> - Display row - uilcRow
    ||- <th> - Selection cell - uilcSelectBox
    ||\- <input> - Selection checkbox - uilcSelect
    ||- <td> - Display cell - uilcCell
    |\- ...
    |- ...
    \- <tr> - Display row (highlighted) [alongside normal class] - uilcHighlight
 *************************************/
function ListViewControl(parent) {
    this.parent = parent;
    //TODO: handle indexes better once insertion and deletion are added
    // Create initial DOM framework
    this._generateDOMFramework();

    // Put a reference here so we can get to it from event handlers
    this.listElement.listControl = this;
    // Rows are stored as an array of DOM elements, with the values (visible
    //  data) and extra (associated data) as attributes on each
    this.rows = [];
    this.selectedRows = [];
    this.currentHighlight = null;
}
    ListViewControl.prototype.changeHeader = function(headers) {
        var headRow = document.createElement("tr");
        headRow.className = "uilcHeadRow";
        // Create the select-all checkbox
        var selectAllCheck = document.createElement("input");
        selectAllCheck.type = "checkbox";
        selectAllCheck.className = "uilcHeadSelect";
        selectAllCheck.addEventListener("click", this._allSelected, false);
        // Add a reference to the list control for the event handler to find
        selectAllCheck.listControl = this;
        // And a reference to the checkbox on the control for other code to find
        this.selectAllCheck = selectAllCheck;
        var selectAllCell = document.createElement("th");
        selectAllCell.appendChild(selectAllCheck);
        selectAllCell.className = "uilcHeadSelectBox";
        headRow.appendChild(selectAllCell);
        // Add the headers
        for (var i in headers) {
            var thisHead = document.createElement("th");
            thisHead.appendChild(document.createTextNode(headers[i].text));
            thisHead.className = "uilcHeadItem";
            thisHead.header = headers[i];
            headRow.appendChild(thisHead);
        }
        // Add one more for a scroll bar buffer
        var scrollBuffer = document.createElement("th");
        scrollBuffer.className = "uilcHeadScrollBuffer"
        headRow.appendChild(scrollBuffer);
        // Add it all to the DOM
        clearElement(this.listHead);
        this.listHead.appendChild(headRow);

        // Setup column info
        clearElement(this.listColgroup);
        // Empty column for checkbox
        this.listColgroup.appendChild(document.createElement("col"));
        // Create one for each data column
        this.cols = [];
        for (var i = 0; i < headers.length; i++) {
            var col = document.createElement("col");
            col.header = headers[i];
            this.listColgroup.appendChild(col);
            this.cols.push(col);
        }
        // Add one on the right for the scroll bar
        var scrollCol = document.createElement("col");
        //TODO: Number is a little arbitrary, calculate it somehow
        scrollCol.style.width = "20px";
        this.listColgroup.appendChild(scrollCol);
    }
    ListViewControl.prototype.appendRow = function(rowValues, rowExtra) {
        element = this._createRow(rowValues);
        // Add additional row data
        element.listIndex = this.rows.length;
        element.values = rowValues;
        element.extra = rowExtra;
        this.rows.push( element );
        // Done setting it up, stick it on the DOM
        this.listBody.appendChild(element);
        this._updateSelectAllBox();
        this._updateBlankMessage();
    }
    // Delete all the rows, reset it to before data was added
    ListViewControl.prototype.clear = function() {
        this.rows = [];
        clearElement(this.listBody);
        this._updateBlankMessage();
    }
    ListViewControl.prototype.getSelected = function() {
        var checkedList = new Array();
        for (i in this.rows) {
            var element = this.rows[i];
            // Checkbox will be the first input element in the row
            var checkbox = element.getElementsByTagName("input")[0];
            if (checkbox.checked) {
                checkedList.push(i);
            }
        }
        return checkedList;
    }
    ListViewControl.prototype.clearSelected = function() {
        selected = this.getSelected();
        for (i in selected) {
            var row = this.rows[selected[i]];
            var checkbox = row.getElementsByTagName("input")[0];
            checkbox.checked = false;
        }
    }
    ListViewControl.prototype.deleteItem = function(index) {
        removed = this.rows[index];
        this.listBody.removeChild(removed);
        this.rows.splice(index, 1);
        // Correct for an edge case - without this, removing all leaves the
        // 'select all' box status undefined when the the list is emptied
        this.selectAllCheck.checked = false;
        this._updateBlankMessage();
    }
    // Highlights a specific row
    ListViewControl.prototype.highlightRow = function(index) {
        // Only one row can be highlighted
        if (this.currentHighlight != null) {
            this.rows[this.currentHighlight].classList.remove("uilcHighlight");
        }
        // If no index was passed, highlight nothing
        if (index != undefined) {
            this.rows[index].classList.add("uilcHighlight");
            this.currentHighlight = index;
        }
    }
    ListViewControl.prototype.disable = function(message) {
        // Places an overlay on the control preventing input
        this.listElement.style.position = "relative";
        this.disabledOverlay.style.display = "block";
    }
    ListViewControl.prototype.enable = function() {
        this.disabledOverlay.style.display = "none";
    }
    // Resets column widths after a resize
    ListViewControl.prototype.fixWidths = function() {
        // usable width is the table width minus the checkbox and scroll bar
        var usableWidth = this.parent.offsetWidth -
                          this.listHeadElement.getElementsByClassName("uilcHeadSelectBox")[0].offsetWidth -
                          this.listHeadElement.getElementsByClassName("uilcHeadScrollBuffer")[0].offsetWidth;
        for (i in library.cols) {
            col = library.cols[i];
            col.style.width = Math.round(usableWidth * col.header.size) + "px";
        }
        // Now copy column data to the table body
        // First remove the old data, if any
        var oldCols = this.listElement.getElementsByTagName("colgroup")[0];
        if (oldCols != undefined) this.listElement.removeChild(oldCols);
        // Then add the new
        this.listElement.insertBefore(this.listColgroup.cloneNode(true), this.listElement.firstChild);
    }
    // -- Event handlers --------------
    ListViewControl.prototype._handleRowClick = function(e) {
        // Don't do anything if it was the checkbox that was clicked
        if (e.target.tagName != "INPUT") {
            rowEvent = document.createEvent("CustomEvent");
            rowEvent.initEvent("rowclick", true, true);
            rowEvent.row = e.currentTarget;
            // parent is <tbody>, and its parent is the <table> where we find the control
            rowEvent.listControl = e.currentTarget.parentNode.parentNode.listControl
            rowEvent.listControl.listElement.dispatchEvent(rowEvent);
        }
    }
    ListViewControl.prototype._rowSelected = function(e) {
        var row = e.target.parentElement.parentElement;
        var selectedIndex = e.target.listControl.selectedRows.indexOf(row);
        if (selectedIndex == -1) {
            e.target.listControl.selectedRows.push(row);
        } else {
            e.target.listControl.selectedRows.splice(selectedIndex, 1);
        }
        e.target.listControl._updateSelectAllBox();
    }
    ListViewControl.prototype._allSelected = function(e) {
        var selectedRows = e.target.listControl.selectedRows;
        var rows = e.target.listControl.rows;
        var control = e.target.listControl;
        // If all selected, deselect all rows
        if (e.target.listControl.selectedRows.length == e.target.listControl.rows.length) {
            for (var i = 0; i < rows.length; i++) {
                rows[i].firstChild.firstChild.checked = false;
                control.selectedRows = [];
            }
        // Otherwise select them all
        } else {
            for (var i = 0; i < rows.length; i++) {
                rows[i].firstChild.firstChild.checked = true;
                control.selectedRows = rows.slice(0);
            }
        }
    }
    // -- Private functions --------------
    // Generates initial DOM structure, called by the init code
    ListViewControl.prototype._generateDOMFramework = function() {
        // Header and body are seperate to allow for independant scrolling
        // Head
        this.listHeadElement = document.createElement("table");
        this.listColgroup = document.createElement("colgroup");
        this.listHeadElement.appendChild(this.listColgroup);
        this.listHead = document.createElement("thead");
        this.listHeadElement.appendChild(this.listHead);

        // Body
        this.listElement = document.createElement("table");
        this.listBody = document.createElement("tbody");
        this.listElement.appendChild(this.listBody);

        // Overlay for disabled controls
        this.disabledOverlay = document.createElement("div");
        // Note: If you encapsulate this control in another div, you may need to
        // move this element to the appropriate location in the DOM.
        this.listElement.appendChild(this.disabledOverlay);

        // Add CSS styles
        this.listHeadElement.className = "uilcHeadTable";
        this.listHead.className = "uilcHead";
        this.listElement.className = "uilcTable";
        this.listBody.className = "uilcBody";
        this.disabledOverlay.className = "disabledOverlay"
        // Put it all on the DOM
        this.parent.appendChild(this.listHeadElement);
        this.parent.appendChild(this.listElement);
    }
    // _createRow handles the DOM stuff, code should normally use appendRow
    ListViewControl.prototype._createRow = function(data) {
        rowElement = document.createElement("tr");
        rowElement.className = "uilcRow";

        // Selection checkbox
        rowSelect = document.createElement("input");
        rowSelect.className = "uilcSelect";
        rowSelect.type = "checkbox";
        rowSelect.addEventListener("click", this._rowSelected, false);
        // Place a reference to the control for the event handler
        rowSelect.listControl = this;
        rowSelectCell = document.createElement("th");
        rowSelectCell.className = "uilcSelectBox";
        rowSelectCell.appendChild(rowSelect);
        rowElement.appendChild(rowSelectCell);

        // Event handlers
        rowElement.addEventListener("click", this._handleRowClick, false);

        // Table data
        rowElement.values = data;
        for (var i = 0; i < data.length; i++) {
            var element = document.createElement("td");
            element.className = "uilcCell";
            element.appendChild(document.createTextNode(data[i]));
            rowElement.appendChild(element)
        }

        return rowElement;
    }
    ListViewControl.prototype._updateSelectAllBox = function() {
        if (this.selectedRows.length == this.rows.length) {
            this.selectAllCheck.checked = true;
        } else {
            this.selectAllCheck.checked = false;
        }
    }
    ListViewControl.prototype._updateBlankMessage = function(track) {
        if (this.rows.length == 0) {
            this.emptyMessage.style.display = "block";
        } else {
            this.emptyMessage.style.display = "none";
        }
    }
<commit_msg>Fixed a bug preventing columns from resizing properly<commit_after>/* ***************************************************************************
 * controls.js
 * ===========
 * Reusable complex UI controls implemented in Javascript are placed here.
 *
 * Dependencies: utils.js
 *****************************************************************************/

/* Classes
 **********/

/*************************************
 ToolbarControl
 --------------
 Used for creating a set of controls to issue commands to the application by
 the user.

 Parameters
  container
   The DOM element that controls are put in. Will be cleared at init.
 *************************************/
function ToolbarControl(container) {
    clearElement(container);
    this.element = container;
}
    ToolbarControl.prototype.addButton = function(label, callback) {
        button = document.createElement("button");
        button.type = "button";
        button.appendChild(document.createTextNode(label));
        button.addEventListener("click", callback, false);
        this.element.appendChild(button);
    }

/*************************************
 ListViewControl
 ---------------
 Manages a tabular data view, similar to the ListView controls you find in
 OS APIs.

 Control is implemented as two separate <table> elements. This allows the
 content to scroll independantly of the headers if needed. Early versions of
 the control contained both parts in the same table, but it eventually
 proved difficult to operate properly with CSS and JS.

 Parameters
  parent
   DOM element that will hold the control. New element will be appended to it.

 CSS styling
    Every element generated by the control is given a class name, so it can be
   styled with CSS. To prevent conflicts with other classes used on the page,
   all names are prefixed with uilc (UI List Control). Class tree follows:

   <table> - Head table - uilcHeadTable
   \- <thead> - Header container - uilcHead
    \- <tr> - Header row - uilcHeadRow
     |- <th> - Header cell (selection check) - uilcHeadSelectBox
     |\- <input> - Select all checkbox - uilcHeadSelect
     |- <th> - Header cell (header item) - uilcHeadItem
     |- ...
     \- <th> - Header scroll bar buffer (no content) - uilcHeadScrollBuffer
   <table> - Main element - uilcTable
   \- <tbody> - Main body - uilcBody
    \- <tr> - Display row - uilcRow
    ||- <th> - Selection cell - uilcSelectBox
    ||\- <input> - Selection checkbox - uilcSelect
    ||- <td> - Display cell - uilcCell
    |\- ...
    |- ...
    \- <tr> - Display row (highlighted) [alongside normal class] - uilcHighlight
 *************************************/
function ListViewControl(parent) {
    this.parent = parent;
    //TODO: handle indexes better once insertion and deletion are added
    // Create initial DOM framework
    this._generateDOMFramework();

    // Put a reference here so we can get to it from event handlers
    this.listElement.listControl = this;
    // Rows are stored as an array of DOM elements, with the values (visible
    //  data) and extra (associated data) as attributes on each
    this.rows = [];
    this.selectedRows = [];
    this.currentHighlight = null;
}
    ListViewControl.prototype.changeHeader = function(headers) {
        var headRow = document.createElement("tr");
        headRow.className = "uilcHeadRow";
        // Create the select-all checkbox
        var selectAllCheck = document.createElement("input");
        selectAllCheck.type = "checkbox";
        selectAllCheck.className = "uilcHeadSelect";
        selectAllCheck.addEventListener("click", this._allSelected, false);
        // Add a reference to the list control for the event handler to find
        selectAllCheck.listControl = this;
        // And a reference to the checkbox on the control for other code to find
        this.selectAllCheck = selectAllCheck;
        var selectAllCell = document.createElement("th");
        selectAllCell.appendChild(selectAllCheck);
        selectAllCell.className = "uilcHeadSelectBox";
        headRow.appendChild(selectAllCell);
        // Add the headers
        for (var i in headers) {
            var thisHead = document.createElement("th");
            thisHead.appendChild(document.createTextNode(headers[i].text));
            thisHead.className = "uilcHeadItem";
            thisHead.header = headers[i];
            headRow.appendChild(thisHead);
        }
        // Add one more for a scroll bar buffer
        var scrollBuffer = document.createElement("th");
        scrollBuffer.className = "uilcHeadScrollBuffer"
        headRow.appendChild(scrollBuffer);
        // Add it all to the DOM
        clearElement(this.listHead);
        this.listHead.appendChild(headRow);

        // Setup column info
        clearElement(this.listColgroup);
        // Empty column for checkbox
        this.listColgroup.appendChild(document.createElement("col"));
        // Create one for each data column
        this.cols = [];
        for (var i = 0; i < headers.length; i++) {
            var col = document.createElement("col");
            col.header = headers[i];
            this.listColgroup.appendChild(col);
            this.cols.push(col);
        }
        // Add one on the right for the scroll bar
        var scrollCol = document.createElement("col");
        //TODO: Number is a little arbitrary, calculate it somehow
        scrollCol.style.width = "20px";
        this.listColgroup.appendChild(scrollCol);
    }
    ListViewControl.prototype.appendRow = function(rowValues, rowExtra) {
        element = this._createRow(rowValues);
        // Add additional row data
        element.listIndex = this.rows.length;
        element.values = rowValues;
        element.extra = rowExtra;
        this.rows.push( element );
        // Done setting it up, stick it on the DOM
        this.listBody.appendChild(element);
        this._updateSelectAllBox();
        this._updateBlankMessage();
    }
    // Delete all the rows, reset it to before data was added
    ListViewControl.prototype.clear = function() {
        this.rows = [];
        clearElement(this.listBody);
        this._updateBlankMessage();
    }
    ListViewControl.prototype.getSelected = function() {
        var checkedList = new Array();
        for (i in this.rows) {
            var element = this.rows[i];
            // Checkbox will be the first input element in the row
            var checkbox = element.getElementsByTagName("input")[0];
            if (checkbox.checked) {
                checkedList.push(i);
            }
        }
        return checkedList;
    }
    ListViewControl.prototype.clearSelected = function() {
        selected = this.getSelected();
        for (i in selected) {
            var row = this.rows[selected[i]];
            var checkbox = row.getElementsByTagName("input")[0];
            checkbox.checked = false;
        }
    }
    ListViewControl.prototype.deleteItem = function(index) {
        removed = this.rows[index];
        this.listBody.removeChild(removed);
        this.rows.splice(index, 1);
        // Correct for an edge case - without this, removing all leaves the
        // 'select all' box status undefined when the the list is emptied
        this.selectAllCheck.checked = false;
        this._updateBlankMessage();
    }
    // Highlights a specific row
    ListViewControl.prototype.highlightRow = function(index) {
        // Only one row can be highlighted
        if (this.currentHighlight != null) {
            this.rows[this.currentHighlight].classList.remove("uilcHighlight");
        }
        // If no index was passed, highlight nothing
        if (index != undefined) {
            this.rows[index].classList.add("uilcHighlight");
            this.currentHighlight = index;
        }
    }
    ListViewControl.prototype.disable = function(message) {
        // Places an overlay on the control preventing input
        this.listElement.style.position = "relative";
        this.disabledOverlay.style.display = "block";
    }
    ListViewControl.prototype.enable = function() {
        this.disabledOverlay.style.display = "none";
    }
    // Resets column widths after a resize
    ListViewControl.prototype.fixWidths = function() {
        // usable width is the table width minus the checkbox and scroll bar
        var usableWidth = this.parent.offsetWidth -
                          this.listHeadElement.getElementsByClassName("uilcHeadSelectBox")[0].offsetWidth -
                          this.listHeadElement.getElementsByClassName("uilcHeadScrollBuffer")[0].offsetWidth;
        for (var i in this.cols) {
            var col = this.cols[i];
            col.style.width = Math.round(usableWidth * col.header.size) + "px";
        }
        // Now copy column data to the table body
        // First remove the old data, if any
        var oldCols = this.listElement.getElementsByTagName("colgroup")[0];
        if (oldCols != undefined) this.listElement.removeChild(oldCols);
        // Then add the new
        this.listElement.insertBefore(this.listColgroup.cloneNode(true), this.listElement.firstChild);
    }
    // -- Event handlers --------------
    ListViewControl.prototype._handleRowClick = function(e) {
        // Don't do anything if it was the checkbox that was clicked
        if (e.target.tagName != "INPUT") {
            rowEvent = document.createEvent("CustomEvent");
            rowEvent.initEvent("rowclick", true, true);
            rowEvent.row = e.currentTarget;
            // parent is <tbody>, and its parent is the <table> where we find the control
            rowEvent.listControl = e.currentTarget.parentNode.parentNode.listControl
            rowEvent.listControl.listElement.dispatchEvent(rowEvent);
        }
    }
    ListViewControl.prototype._rowSelected = function(e) {
        var row = e.target.parentElement.parentElement;
        var selectedIndex = e.target.listControl.selectedRows.indexOf(row);
        if (selectedIndex == -1) {
            e.target.listControl.selectedRows.push(row);
        } else {
            e.target.listControl.selectedRows.splice(selectedIndex, 1);
        }
        e.target.listControl._updateSelectAllBox();
    }
    ListViewControl.prototype._allSelected = function(e) {
        var selectedRows = e.target.listControl.selectedRows;
        var rows = e.target.listControl.rows;
        var control = e.target.listControl;
        // If all selected, deselect all rows
        if (e.target.listControl.selectedRows.length == e.target.listControl.rows.length) {
            for (var i = 0; i < rows.length; i++) {
                rows[i].firstChild.firstChild.checked = false;
                control.selectedRows = [];
            }
        // Otherwise select them all
        } else {
            for (var i = 0; i < rows.length; i++) {
                rows[i].firstChild.firstChild.checked = true;
                control.selectedRows = rows.slice(0);
            }
        }
    }
    // -- Private functions --------------
    // Generates initial DOM structure, called by the init code
    ListViewControl.prototype._generateDOMFramework = function() {
        // Header and body are seperate to allow for independant scrolling
        // Head
        this.listHeadElement = document.createElement("table");
        this.listColgroup = document.createElement("colgroup");
        this.listHeadElement.appendChild(this.listColgroup);
        this.listHead = document.createElement("thead");
        this.listHeadElement.appendChild(this.listHead);

        // Body
        this.listElement = document.createElement("table");
        this.listBody = document.createElement("tbody");
        this.listElement.appendChild(this.listBody);

        // Overlay for disabled controls
        this.disabledOverlay = document.createElement("div");
        // Note: If you encapsulate this control in another div, you may need to
        // move this element to the appropriate location in the DOM.
        this.listElement.appendChild(this.disabledOverlay);

        // Add CSS styles
        this.listHeadElement.className = "uilcHeadTable";
        this.listHead.className = "uilcHead";
        this.listElement.className = "uilcTable";
        this.listBody.className = "uilcBody";
        this.disabledOverlay.className = "disabledOverlay"
        // Put it all on the DOM
        this.parent.appendChild(this.listHeadElement);
        this.parent.appendChild(this.listElement);
    }
    // _createRow handles the DOM stuff, code should normally use appendRow
    ListViewControl.prototype._createRow = function(data) {
        rowElement = document.createElement("tr");
        rowElement.className = "uilcRow";

        // Selection checkbox
        rowSelect = document.createElement("input");
        rowSelect.className = "uilcSelect";
        rowSelect.type = "checkbox";
        rowSelect.addEventListener("click", this._rowSelected, false);
        // Place a reference to the control for the event handler
        rowSelect.listControl = this;
        rowSelectCell = document.createElement("th");
        rowSelectCell.className = "uilcSelectBox";
        rowSelectCell.appendChild(rowSelect);
        rowElement.appendChild(rowSelectCell);

        // Event handlers
        rowElement.addEventListener("click", this._handleRowClick, false);

        // Table data
        rowElement.values = data;
        for (var i = 0; i < data.length; i++) {
            var element = document.createElement("td");
            element.className = "uilcCell";
            element.appendChild(document.createTextNode(data[i]));
            rowElement.appendChild(element)
        }

        return rowElement;
    }
    ListViewControl.prototype._updateSelectAllBox = function() {
        if (this.selectedRows.length == this.rows.length) {
            this.selectAllCheck.checked = true;
        } else {
            this.selectAllCheck.checked = false;
        }
    }
    ListViewControl.prototype._updateBlankMessage = function(track) {
        if (this.rows.length == 0) {
            this.emptyMessage.style.display = "block";
        } else {
            this.emptyMessage.style.display = "none";
        }
    }
<|endoftext|>


<commit_before>jQuery(document).ready(function() {
    jQuery('html').removeClass('no-js');
    if (window.SONATA_CONFIG && window.SONATA_CONFIG.CONFIRM_EXIT) {
        jQuery('.sonata-ba-form form').confirmExit();
    }

    Admin.setup_select2(document);
    Admin.setup_xeditable(document);
    Admin.add_pretty_errors(document);
    Admin.add_filters(document);
    Admin.set_object_field_value(document);
    Admin.setup_collection_buttons(document);
    Admin.setup_per_page_switcher(document);
    Admin.setup_form_tabs_for_errors(document);
    Admin.setup_inline_form_errors(document);
});

jQuery(document).on('sonata-admin-append-form-element', function(e) {
    Admin.setup_select2(e.target);
});

var Admin = {

    setup_select2: function(subject) {
        if (window.SONATA_CONFIG && window.SONATA_CONFIG.USE_SELECT2 && window.Select2) {
            jQuery('select:not([data-sonata-select2="false"])', subject).each(function() {
                var select = $(this);

                var allowClearEnabled = false;

                if (select.find('option[value=""]').length) {
                    allowClearEnabled = true;
                }

                if (select.attr('data-sonata-select2-allow-clear')==='true') {
                    allowClearEnabled = true;
                } else if (select.attr('data-sonata-select2-allow-clear')==='false') {
                    allowClearEnabled = false;
                }

                select.select2({
                    width: 'resolve',
                    minimumResultsForSearch: 10,
                    allowClear: allowClearEnabled
                });

                var popover = select.data('popover');

                if (undefined !== popover) {
                    select
                        .select2('container')
                        .popover(popover.options)
                    ;
                }
            });
        }
    },

    setup_xeditable: function(subject) {
        jQuery('.x-editable', subject).editable({
            emptyclass: 'editable-empty btn btn-small',
            emptytext: '',
            success: function(response) {
                if('KO' === response.status) {
                    return response.message;
                }

                var html = jQuery(response.content);
                Admin.setup_xeditable(html);

                jQuery(this)
                    .closest('td')
                    .replaceWith(html)
                ;
            }
        });
    },

    /**
     * render log message
     * @param mixed
     */
    log: function() {
        var msg = '[Sonata.Admin] ' + Array.prototype.join.call(arguments,', ');
        if (window.console && window.console.log) {
            window.console.log(msg);
        } else if (window.opera && window.opera.postError) {
            window.opera.postError(msg);
        }
    },

    /**
     * display related errors messages
     *
     * @param subject
     */
    add_pretty_errors: function(subject) {

        Admin.setup_select2(subject);

        jQuery('div.sonata-ba-field-error', subject).each(function(index, element) {
            var input = jQuery(':input', element);

            if (!input.length) {
                return;
            }

            var message = jQuery('div.sonata-ba-field-error-messages', element).html();
            jQuery('div.sonata-ba-field-error-messages', element).remove();

            if (!message || message.length == 0) {
                return;
            }

            var target = input,
                fieldShortDescription = input.closest('.field-container').find('.field-short-description')
            ;

            if (fieldShortDescription.length) {
                target = fieldShortDescription;
            }

            target.popover({
                content: message,
                trigger: 'hover',
                html: true,
                placement: 'right',
                template: '

'
            });

        });
    },

    stopEvent: function(event) {
        // https://github.com/sonata-project/SonataAdminBundle/issues/151
        //if it is a standard browser use preventDefault otherwise it is IE then return false
        if(event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }

        //if it is a standard browser get target otherwise it is IE then adapt syntax and get target
        if (typeof event.target != 'undefined') {
            targetElement = event.target;
        } else {
            targetElement = event.srcElement;
        }

        return targetElement;
    },

    add_filters: function(subject) {
        jQuery('div.filter_container .sonata-filter-option', subject).hide();
        jQuery('fieldset.filter_legend', subject).click(function(event) {
            jQuery('div.filter_container .sonata-filter-option', jQuery(event.target).parent()).toggle();
        });
    },

    /**
     * Change object field value
     * @param subject
     */
    set_object_field_value: function(subject) {

        this.log(jQuery('a.sonata-ba-edit-inline', subject));
        jQuery('a.sonata-ba-edit-inline', subject).click(function(event) {
            Admin.stopEvent(event);

            var subject = jQuery(this);
            jQuery.ajax({
                url: subject.attr('href'),
                type: 'POST',
                success: function(json) {
                    if(json.status === "OK") {
                        var elm = jQuery(subject).parent();
                        elm.children().remove();
                        // fix issue with html comment ...
                        elm.html(jQuery(json.content.replace(//g, "")).html());
                        elm.effect("highlight", {'color' : '#57A957'}, 2000);
                        Admin.set_object_field_value(elm);
                    } else {
                        jQuery(subject).parent().effect("highlight", {'color' : '#C43C35'}, 2000);
                    }
                }
            });
        });
    },

    setup_collection_buttons: function(subject) {

        jQuery(subject).on('click', '.sonata-collection-add', function(event) {
            Admin.stopEvent(event);

            var container = jQuery(this).closest('[data-prototype]');
            var proto = container.attr('data-prototype');
            var protoName = container.attr('data-prototype-name') || '__name__';
            // Set field id
            var idRegexp = new RegExp(container.attr('id')+'_'+protoName,'g');
            proto = proto.replace(idRegexp, container.attr('id')+'_'+(container.children().length - 1));

            // Set field name
            var parts = container.attr('id').split('_');
            var nameRegexp = new RegExp(parts[parts.length-1]+'\\]\\['+protoName,'g');
            proto = proto.replace(nameRegexp, parts[parts.length-1]+']['+(container.children().length - 1));
            jQuery(proto)
                .insertBefore(jQuery(this).parent())
                .trigger('sonata-admin-append-form-element')
            ;

            jQuery(this).trigger('sonata-collection-item-added');
        });

        jQuery(subject).on('click', '.sonata-collection-delete', function(event) {
            Admin.stopEvent(event);

            jQuery(this).trigger('sonata-collection-item-deleted');

            jQuery(this).closest('.sonata-collection-row').remove();
        });
    },

    setup_per_page_switcher: function(subject) {
        jQuery('select.per-page').change(function(event) {
            jQuery('input[type=submit]').hide();

            window.top.location.href=this.options[this.selectedIndex].value;
        });
    },

    setup_form_tabs_for_errors: function(subject) {
        // Switch to first tab with server side validation errors on page load
        jQuery('form', subject).each(function() {
            Admin.show_form_first_tab_with_errors(jQuery(this), '.sonata-ba-field-error');
        });

        // Switch to first tab with HTML5 errors on form submit
        jQuery(subject)
            .on('click', 'form [type="submit"]', function() {
                Admin.show_form_first_tab_with_errors(jQuery(this).closest('form'), ':invalid');
            })
            .on('keypress', 'form [type="text"]', function(e) {
                if (13 === e.which) {
                    Admin.show_form_first_tab_with_errors(jQuery(this), ':invalid');
                }
            })
        ;
    },

    show_form_first_tab_with_errors: function(form, errorSelector) {
        var tabs = form.find('.nav-tabs a'),
            firstTabWithErrors;

        tabs.each(function() {
            var id = jQuery(this).attr('href'),
                tab = jQuery(this),
                icon = tab.find('.has-errors');

            if (jQuery(id).find(errorSelector).length > 0) {
                // Only show first tab with errors
                if (!firstTabWithErrors) {
                    tab.tab('show');
                    firstTabWithErrors = tab;
                }

                icon.removeClass('hide');
            } else {
                icon.addClass('hide');
            }
        });
    },

    setup_inline_form_errors: function(subject) {
        var deleteCheckboxSelector = '.sonata-ba-field-inline-table [id$="_delete"][type="checkbox"]';

        jQuery(deleteCheckboxSelector, subject).each(function() {
            Admin.switch_inline_form_errors(jQuery(this));
        });

        $(subject).on('change', deleteCheckboxSelector, function() {
            Admin.switch_inline_form_errors(jQuery(this));
        });
    },

    /**
     * Disable inline form errors when the row is marked for deletion
     */
    switch_inline_form_errors: function(deleteCheckbox) {
        var row = deleteCheckbox.closest('.sonata-ba-field-inline-table'),
            errors = row.find('.sonata-ba-field-error-messages')
        ;

        if (deleteCheckbox.is(':checked')) {
            row
                .find('[required]')
                .removeAttr('required')
                .attr('data-required', 'required')
            ;

            errors.hide();
        } else {
            row
                .find('[data-required]')
                .attr('required', 'required')
            ;

            errors.show();
        }
    }
};
<commit_msg>he confirm exit solution does not work correctly for multiple forms on one page because the serialized data are generated over an collection and not over the single forms.<commit_after>jQuery(document).ready(function() {
    jQuery('html').removeClass('no-js');
    if (window.SONATA_CONFIG && window.SONATA_CONFIG.CONFIRM_EXIT) {
        jQuery('.sonata-ba-form form').each(function () { $(this).confirmExit(); });
    }

    Admin.setup_select2(document);
    Admin.setup_xeditable(document);
    Admin.add_pretty_errors(document);
    Admin.add_filters(document);
    Admin.set_object_field_value(document);
    Admin.setup_collection_buttons(document);
    Admin.setup_per_page_switcher(document);
    Admin.setup_form_tabs_for_errors(document);
    Admin.setup_inline_form_errors(document);
});

jQuery(document).on('sonata-admin-append-form-element', function(e) {
    Admin.setup_select2(e.target);
});

var Admin = {

    setup_select2: function(subject) {
        if (window.SONATA_CONFIG && window.SONATA_CONFIG.USE_SELECT2 && window.Select2) {
            jQuery('select:not([data-sonata-select2="false"])', subject).each(function() {
                var select = $(this);

                var allowClearEnabled = false;

                if (select.find('option[value=""]').length) {
                    allowClearEnabled = true;
                }

                if (select.attr('data-sonata-select2-allow-clear')==='true') {
                    allowClearEnabled = true;
                } else if (select.attr('data-sonata-select2-allow-clear')==='false') {
                    allowClearEnabled = false;
                }

                select.select2({
                    width: 'resolve',
                    minimumResultsForSearch: 10,
                    allowClear: allowClearEnabled
                });

                var popover = select.data('popover');

                if (undefined !== popover) {
                    select
                        .select2('container')
                        .popover(popover.options)
                    ;
                }
            });
        }
    },

    setup_xeditable: function(subject) {
        jQuery('.x-editable', subject).editable({
            emptyclass: 'editable-empty btn btn-small',
            emptytext: '',
            success: function(response) {
                if('KO' === response.status) {
                    return response.message;
                }

                var html = jQuery(response.content);
                Admin.setup_xeditable(html);

                jQuery(this)
                    .closest('td')
                    .replaceWith(html)
                ;
            }
        });
    },

    /**
     * render log message
     * @param mixed
     */
    log: function() {
        var msg = '[Sonata.Admin] ' + Array.prototype.join.call(arguments,', ');
        if (window.console && window.console.log) {
            window.console.log(msg);
        } else if (window.opera && window.opera.postError) {
            window.opera.postError(msg);
        }
    },

    /**
     * display related errors messages
     *
     * @param subject
     */
    add_pretty_errors: function(subject) {

        Admin.setup_select2(subject);

        jQuery('div.sonata-ba-field-error', subject).each(function(index, element) {
            var input = jQuery(':input', element);

            if (!input.length) {
                return;
            }

            var message = jQuery('div.sonata-ba-field-error-messages', element).html();
            jQuery('div.sonata-ba-field-error-messages', element).remove();

            if (!message || message.length == 0) {
                return;
            }

            var target = input,
                fieldShortDescription = input.closest('.field-container').find('.field-short-description')
            ;

            if (fieldShortDescription.length) {
                target = fieldShortDescription;
            }

            target.popover({
                content: message,
                trigger: 'hover',
                html: true,
                placement: 'right',
                template: '

'
            });

        });
    },

    stopEvent: function(event) {
        // https://github.com/sonata-project/SonataAdminBundle/issues/151
        //if it is a standard browser use preventDefault otherwise it is IE then return false
        if(event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }

        //if it is a standard browser get target otherwise it is IE then adapt syntax and get target
        if (typeof event.target != 'undefined') {
            targetElement = event.target;
        } else {
            targetElement = event.srcElement;
        }

        return targetElement;
    },

    add_filters: function(subject) {
        jQuery('div.filter_container .sonata-filter-option', subject).hide();
        jQuery('fieldset.filter_legend', subject).click(function(event) {
            jQuery('div.filter_container .sonata-filter-option', jQuery(event.target).parent()).toggle();
        });
    },

    /**
     * Change object field value
     * @param subject
     */
    set_object_field_value: function(subject) {

        this.log(jQuery('a.sonata-ba-edit-inline', subject));
        jQuery('a.sonata-ba-edit-inline', subject).click(function(event) {
            Admin.stopEvent(event);

            var subject = jQuery(this);
            jQuery.ajax({
                url: subject.attr('href'),
                type: 'POST',
                success: function(json) {
                    if(json.status === "OK") {
                        var elm = jQuery(subject).parent();
                        elm.children().remove();
                        // fix issue with html comment ...
                        elm.html(jQuery(json.content.replace(//g, "")).html());
                        elm.effect("highlight", {'color' : '#57A957'}, 2000);
                        Admin.set_object_field_value(elm);
                    } else {
                        jQuery(subject).parent().effect("highlight", {'color' : '#C43C35'}, 2000);
                    }
                }
            });
        });
    },

    setup_collection_buttons: function(subject) {

        jQuery(subject).on('click', '.sonata-collection-add', function(event) {
            Admin.stopEvent(event);

            var container = jQuery(this).closest('[data-prototype]');
            var proto = container.attr('data-prototype');
            var protoName = container.attr('data-prototype-name') || '__name__';
            // Set field id
            var idRegexp = new RegExp(container.attr('id')+'_'+protoName,'g');
            proto = proto.replace(idRegexp, container.attr('id')+'_'+(container.children().length - 1));

            // Set field name
            var parts = container.attr('id').split('_');
            var nameRegexp = new RegExp(parts[parts.length-1]+'\\]\\['+protoName,'g');
            proto = proto.replace(nameRegexp, parts[parts.length-1]+']['+(container.children().length - 1));
            jQuery(proto)
                .insertBefore(jQuery(this).parent())
                .trigger('sonata-admin-append-form-element')
            ;

            jQuery(this).trigger('sonata-collection-item-added');
        });

        jQuery(subject).on('click', '.sonata-collection-delete', function(event) {
            Admin.stopEvent(event);

            jQuery(this).trigger('sonata-collection-item-deleted');

            jQuery(this).closest('.sonata-collection-row').remove();
        });
    },

    setup_per_page_switcher: function(subject) {
        jQuery('select.per-page').change(function(event) {
            jQuery('input[type=submit]').hide();

            window.top.location.href=this.options[this.selectedIndex].value;
        });
    },

    setup_form_tabs_for_errors: function(subject) {
        // Switch to first tab with server side validation errors on page load
        jQuery('form', subject).each(function() {
            Admin.show_form_first_tab_with_errors(jQuery(this), '.sonata-ba-field-error');
        });

        // Switch to first tab with HTML5 errors on form submit
        jQuery(subject)
            .on('click', 'form [type="submit"]', function() {
                Admin.show_form_first_tab_with_errors(jQuery(this).closest('form'), ':invalid');
            })
            .on('keypress', 'form [type="text"]', function(e) {
                if (13 === e.which) {
                    Admin.show_form_first_tab_with_errors(jQuery(this), ':invalid');
                }
            })
        ;
    },

    show_form_first_tab_with_errors: function(form, errorSelector) {
        var tabs = form.find('.nav-tabs a'),
            firstTabWithErrors;

        tabs.each(function() {
            var id = jQuery(this).attr('href'),
                tab = jQuery(this),
                icon = tab.find('.has-errors');

            if (jQuery(id).find(errorSelector).length > 0) {
                // Only show first tab with errors
                if (!firstTabWithErrors) {
                    tab.tab('show');
                    firstTabWithErrors = tab;
                }

                icon.removeClass('hide');
            } else {
                icon.addClass('hide');
            }
        });
    },

    setup_inline_form_errors: function(subject) {
        var deleteCheckboxSelector = '.sonata-ba-field-inline-table [id$="_delete"][type="checkbox"]';

        jQuery(deleteCheckboxSelector, subject).each(function() {
            Admin.switch_inline_form_errors(jQuery(this));
        });

        $(subject).on('change', deleteCheckboxSelector, function() {
            Admin.switch_inline_form_errors(jQuery(this));
        });
    },

    /**
     * Disable inline form errors when the row is marked for deletion
     */
    switch_inline_form_errors: function(deleteCheckbox) {
        var row = deleteCheckbox.closest('.sonata-ba-field-inline-table'),
            errors = row.find('.sonata-ba-field-error-messages')
        ;

        if (deleteCheckbox.is(':checked')) {
            row
                .find('[required]')
                .removeAttr('required')
                .attr('data-required', 'required')
            ;

            errors.hide();
        } else {
            row
                .find('[data-required]')
                .attr('required', 'required')
            ;

            errors.show();
        }
    }
};
<|endoftext|>


<commit_before>
describe('update()', function () {

	// dynalite: "ADD action is not supported for the type L", UpdateExpression
	it('.update( existing_item )', function(done) {
		// insert
		DynamoDB
			.table($tableName)
			.insert_or_replace({
				hash: 'test-update',
				range:1,
				old_number: 1,
				//old_array: [1,2,3],
				string: 'aaa',
				'ignore': 'me',
				'delete': 'me'
			}, function(err) {
				if (err)
					throw err

				DynamoDB
					.table($tableName)
					.where('hash').eq('test-update')
					.where('range').eq(1)
					.return(DynamoDB.ALL_NEW)
					.update({
						gsi_range: 'b',
						string: 'newstring',
						boolean: false,
						old_number: DynamoDB.add(9),
						null: null,
						//old_array: DynamoDB.add([ 1, 'a', null, { k1: 'v1', k2: 'v2', k3: 'v3' }, [] ]),
						object: { key1: 'value1', key2: 22 },
						delete: DynamoDB.del()
					}, function(err, data) {
						if (err)
							throw err

						assert.deepEqual(data, {
							hash: 'test-update',
							range: 1,
							old_number: 10,
							//old_array: [ 1,2,3, 1, 'a', null, { k3: 'v3', k1: 'v1', k2: 'v2' }, [] ],
							string: 'newstring',
							boolean: false,
							ignore: 'me',

							null: null,
							gsi_range: 'b',
							object: { key2: 22, key1: 'value1' },
						})
						done()
					})
			})
	})

	it('.return(DynamoDB.UPDATED_OLD).update( existing_item )', function(done) {

		DynamoDB
			.table($tableName)
			//.on('beforeRequest', function(op, payload) {
			//	console.log(op, JSON.stringify(payload,null,"\t"))
			//})
			.insert_or_replace({
				hash: 'test-updated-old',
				range: 1,

				number: 10,
				number2: 10,
				boolean: true,
			}, function(err) {
				if (err) throw err

				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-old')
					.where('range').eq(1)
					.return(DynamoDB.UPDATED_OLD)
					//.on('beforeRequest', function(op, payload) {
					//	console.log(op, JSON.stringify(payload,null,"\t"))
					//})
					.update({
						number: DynamoDB.add(20),
						number2: 30,
						boolean: false,
					}, function(err, data ) {

						if (err) throw err
						assert.deepEqual(data, { number: 10, number2: 10, boolean: true })
						done()
					})
			})
	})

	it('.update().then()', function(done) {
		DynamoDB
			.table($tableName)
			.return(DynamoDB.UPDATED_OLD)
			.where('hash').eq('test-updated-old')
			.where('range').eq(1)
			.update({
				number: 1,
			})
			.then(function(data) {
				done()
			})
	})
	it('.update() - unhandled', function(done) {
		DynamoDB
			.table($tableName)
			.where('hash').eq(1)
			.where('range_unexistent').eq(1)
			.update({})
		setTimeout(function() {
			done()
		},5000)
	})
	it('.update().catch()', function(done) {
		DynamoDB
			.table($tableName)
			.where('hash').eq(1)
			.where('range_unexistent').eq(1)
			.update({})
			.catch(function(err) {
				done()
			})
	})

	it('.update() - add() to List, StringSet, NumberSet', function(done) {
		async.waterfall([

			function(cb) {
				DynamoDB
					.table($tableName)
					.insert_or_replace({
						hash: 'test-updated-ss-add',
						range: 1,
						arr: ['x','y'],
						//obj: {number: 1},
						ss: DynamoDB.SS( ['bbb','ccc'] ),
						ns: DynamoDB.NS( [ 33,22] ),
					}, function(err) {
						if (err) throw err
						cb()
					})
			},

			function(cb) {
				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-ss-add')
					.where('range').eq(1)
					.update({
						arr: DynamoDB.add( ['x','y', false, null, {}] ),
						//obj: DynamoDB.add( { color: 'blue'} ),
						ss:  DynamoDB.add( DynamoDB.SS(['aaa','ddd']) ),
						ns:  DynamoDB.add( DynamoDB.NS([11,44]) ),

					}, function(err, data ) {
						if (err) throw err

						cb()
					})
			},

		],function(err) {
				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-ss-add')
					.where('range').eq(1)
					//.return(DynamoDB.UPDATED_OLD)
					//.on('beforeRequest', function(op, payload) {
					//	console.log(op, JSON.stringify(payload,null,"\t"))
					//})
					.get( function(err, data ) {
						if (err) throw err

						assert.deepEqual(data.arr, [ 'x', 'y', 'x', 'y', false, null, {} ] )
						assert.deepEqual(data.ss, [ 'bbb', 'ccc', 'aaa', 'ddd' ] )
						assert.deepEqual(data.ns, [ 33, 22, 11, 44 ] )

						done()
					})
		})
	})

	it('cleanup...', function(done) {
		DynamoDB
			.table($tableName)
			.scan(function(err, data) {
				if (err)
					throw err

				async.each(data, function(item,cb) {
					DynamoDB.table($tableName).where('hash').eq(item.hash).where('range').eq(item.range).delete(function(err) { cb(err) })
				}, function(err) {
					if (err)
						throw err

					done()
				})
			})
	})
})
<commit_msg>update<commit_after>
describe('update()', function () {

	// dynalite: "ADD action is not supported for the type L", UpdateExpression
	it('.update( existing_item )', function(done) {
		// insert
		DynamoDB
			.table($tableName)
			.insert_or_replace({
				hash: 'test-update',
				range:1,
				old_number: 1,
				//old_array: [1,2,3],
				string: 'aaa',
				'ignore': 'me',
				'delete': 'me'
			}, function(err) {
				if (err)
					throw err

				DynamoDB
					.table($tableName)
					.where('hash').eq('test-update')
					.where('range').eq(1)
					.return(DynamoDB.ALL_NEW)
					.update({
						gsi_range: 'b',
						string: 'newstring',
						boolean: false,
						old_number: DynamoDB.add(9),
						null: null,
						//old_array: DynamoDB.add([ 1, 'a', null, { k1: 'v1', k2: 'v2', k3: 'v3' }, [] ]),
						object: { key1: 'value1', key2: 22 },
						delete: DynamoDB.del()
					}, function(err, data) {
						if (err)
							throw err

						assert.deepEqual(data, {
							hash: 'test-update',
							range: 1,
							old_number: 10,
							//old_array: [ 1,2,3, 1, 'a', null, { k3: 'v3', k1: 'v1', k2: 'v2' }, [] ],
							string: 'newstring',
							boolean: false,
							ignore: 'me',

							null: null,
							gsi_range: 'b',
							object: { key2: 22, key1: 'value1' },
						})
						done()
					})
			})
	})

	it('.return(DynamoDB.UPDATED_OLD).update( existing_item )', function(done) {

		DynamoDB
			.table($tableName)
			//.on('beforeRequest', function(op, payload) {
			//	console.log(op, JSON.stringify(payload,null,"\t"))
			//})
			.insert_or_replace({
				hash: 'test-updated-old',
				range: 1,

				number: 10,
				number2: 10,
				boolean: true,
			}, function(err) {
				if (err) throw err

				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-old')
					.where('range').eq(1)
					.return(DynamoDB.UPDATED_OLD)
					//.on('beforeRequest', function(op, payload) {
					//	console.log(op, JSON.stringify(payload,null,"\t"))
					//})
					.update({
						number: DynamoDB.add(20),
						number2: 30,
						boolean: false,
					}, function(err, data ) {

						if (err) throw err
						assert.deepEqual(data, { number: 10, number2: 10, boolean: true })
						done()
					})
			})
	})

	it('.update().then()', function(done) {
		DynamoDB
			.table($tableName)
			.return(DynamoDB.UPDATED_OLD)
			.where('hash').eq('test-updated-old')
			.where('range').eq(1)
			.update({
				number: 1,
			})
			.then(function(data) {
				done()
			})
	})
	it('.update() - unhandled', function(done) {
		DynamoDB
			.table($tableName)
			.where('hash').eq(1)
			.where('range_unexistent').eq(1)
			.update({})
		setTimeout(function() {
			done()
		},5000)
	})
	it('.update().catch()', function(done) {
		DynamoDB
			.table($tableName)
			.where('hash').eq(1)
			.where('range_unexistent').eq(1)
			.update({})
			.catch(function(err) {
				done()
			})
	})

	it('.update() - add() to List, StringSet, NumberSet', function(done) {
		async.waterfall([

			function(cb) {
				DynamoDB
					.table($tableName)
					.insert_or_replace({
						hash: 'test-updated-ss-add',
						range: 1,
						arr: ['x','y'],
						//obj: {number: 1},
						ss: DynamoDB.SS( ['bbb','ccc'] ),
						ns: DynamoDB.NS( [ 33,22] ),
					}, function(err) {
						if (err) throw err
						cb()
					})
			},

			function(cb) {
				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-ss-add')
					.where('range').eq(1)
					.update({
						arr: DynamoDB.add( ['x','y', false, null, {}] ),
						//obj: DynamoDB.add( { color: 'blue'} ),
						ss:  DynamoDB.add( DynamoDB.SS(['aaa','ddd']) ),
						ns:  DynamoDB.add( DynamoDB.NS([11,44]) ),

					}, function(err, data ) {
						if (err) throw err

						cb()
					})
			},

		],function(err) {
				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-ss-add')
					.where('range').eq(1)
					//.return(DynamoDB.UPDATED_OLD)
					//.on('beforeRequest', function(op, payload) {
					//	console.log(op, JSON.stringify(payload,null,"\t"))
					//})
					.get( function(err, data ) {
						if (err) throw err

						assert.deepEqual(data.arr, [ 'x', 'y', 'x', 'y', false, null, {} ] )
						assert.deepEqual(data.ss, [ 'bbb', 'ccc', 'aaa', 'ddd' ] )
						assert.deepEqual(data.ns, [ 33, 22, 11, 44 ] )

						done()
					})
		})
	})

	it('.update() - del() from StringSet and NumberSet', function(done) {
		async.waterfall([

			function(cb) {
				DynamoDB
					.table($tableName)
					.insert_or_replace({
						hash: 'test-updated-ss-del',
						range: 1,
						//arr: ['x','y'],
						ss: DynamoDB.SS( ['bbb','ccc'] ),
						ns: DynamoDB.NS( [ 33,22] ),
					}, function(err) {
						if (err) throw err
						cb()
					})
			},

			function(cb) {
				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-ss-del')
					.where('range').eq(1)
					.update({

						ss:  DynamoDB.del( DynamoDB.SS(['bbb']) ),
						ns:  DynamoDB.del( DynamoDB.NS([22]) ),

					}, function(err, data ) {
						if (err) throw err

						cb()
					})
			},

		],function(err) {
				DynamoDB
					.table($tableName)
					.where('hash').eq('test-updated-ss-del')
					.where('range').eq(1)
					//.return(DynamoDB.UPDATED_OLD)
					//.on('beforeRequest', function(op, payload) {
					//	console.log(op, JSON.stringify(payload,null,"\t"))
					//})
					.get( function(err, data ) {
						if (err) throw err

						assert.deepEqual(data.ss, [ 'ccc' ] )
						assert.deepEqual(data.ns, [ 33 ] )

						done()
					})
		})
	})

	it('cleanup...', function(done) {
		DynamoDB
			.table($tableName)
			.scan(function(err, data) {
				if (err)
					throw err

				async.each(data, function(item,cb) {
					DynamoDB.table($tableName).where('hash').eq(item.hash).where('range').eq(item.range).delete(function(err) { cb(err) })
				}, function(err) {
					if (err)
						throw err

					done()
				})
			})
	})
})
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    if (counter + step >= length) step = length - counter
    process.stdout.write("\033[2K Writing " + counter + "/" + length + " bytes: " + message + "\r");
    fs.writeSync(outFD, data.slice(counter, counter+step), 0, step)
    child_process.execFileSync('/Applications/Xcode.app/Contents/Developer/usr/bin/git', args)
    var timeout = randomIntFromInterval(0, max_sleep)
    counter = counter + step
    if (process.env.FAKETIME) {
      t_offset = t_offset + timeout;
     <commit_msg>Fixing punctuation<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    if (counter + step >= length) step = length - counter
    process.stdout.write("\033[2K Writing " + counter + "/" + length + " bytes: " + message + "\r");
    fs.writeSync(outFD, data.slice(counter, counter+step), 0, step)
    child_process.execFileSync('/Applications/Xcode.app/Contents/Developer/usr/bin/git', args)
    var timeout = randomIntFromInterval(0, max_sleep)
    counter = counter + step
    if (process.env.FAKETIME) {
      t_offset = t_offset + timeout;
      <|endoftext|>


<commit_before>//By Rajeshwar Patlolla
//https://github.com/rajeshwarpatlolla

"use strict";
var app = angular.module('ionic-datepicker', ['ionic', 'ionic-datepicker.templates']);

app.service('DatepickerService', function () {

});

app.directive('ionicDatepicker', ['$ionicPopup', 'DatepickerService', function ($ionicPopup, DatepickerService) {
  return {
    restrict: 'AE',
    replace: true,
    scope: {
      ipDate: '=idate',
      disablePreviousDates: '=disablepreviousdates',
      disableFutureDates: '=disablefuturedates',
      callback: '=callback',
      title: '=title',
      disabledDates: '=?disableddates'
    },
    link: function (scope, element, attrs) {

      scope.datePickerTitle = scope.title || 'Select Date';
      var monthsList = [
        {
          id: 0, name: 'January'
        },
        {
          id: 1, name: 'February'
        },
        {
          id: 2, name: 'March'
        },
        {
          id: 3, name: 'April'
        },
        {
          id: 4, name: 'May'
        },
        {
          id: 5, name: 'June'
        },
        {
          id: 6, name: 'July'
        },
        {
          id: 7, name: 'August'
        },
        {
          id: 8, name: 'Sepetember'
        },
        {
          id: 9, name: 'October'
        },
        {
          id: 10, name: 'November'
        },
        {
          id: 11, name: 'December'
        }
      ];
      scope.monthsList = monthsList;
      var yearsList = [];
      for (i = 1901; i <= 2100; i++) {
        yearsList.push({ id: i, name: i });
      }

      scope.yearsList = yearsList;

      scope.currentMonth = '';
      scope.currentYear = '';

      if (!scope.ipDate) {
        scope.ipDate = new Date();
      }

      if (!angular.isDefined(scope.disabledDates)) {
        scope.disabledDates = [];
      } else {
        for (var i = 0; i < scope.disabledDates.length; i++) {
          scope.disabledDates[i] = scope.disabledDates[i].getTime();
        }
      }

      scope.previousDayEpoch = (+(new Date()) - 86400000);
      scope.nextDayEpoch = (+(new Date()));

      var currentDate = angular.copy(scope.ipDate);
      currentDate.setHours(0);
      currentDate.setMinutes(0);
      currentDate.setSeconds(0);
      currentDate.setMilliseconds(0);

      scope.selctedDateString = currentDate.toString();
      scope.weekNames = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
      scope.today = {};

      var getDateObject = function (date) {
        var tempDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
        return {
          dateObj: date,
          date: tempDate.getDate(),
          month: tempDate.getMonth(),
          year: tempDate.getFullYear(),
          day: tempDate.getDay(),
          dateString: tempDate.toString(),
          epochLocal: tempDate.getTime(),
          epochUTC: (tempDate.getTime() + (tempDate.getTimezoneOffset() * 60 * 1000))
        };
      };

      scope.today = getDateObject(new Date());

      var refreshDateList = function (current_date) {
        current_date.setHours(0);
        current_date.setMinutes(0);
        current_date.setSeconds(0);
        current_date.setMilliseconds(0);

        currentDate = angular.copy(current_date);

        var firstDay = new Date(current_date.getFullYear(), current_date.getMonth(), 1).getDate();
        var lastDay = new Date(current_date.getFullYear(), current_date.getMonth() + 1, 0).getDate();

        scope.dayList = [];

        for (var i = firstDay; i <= lastDay; i++) {
          var tempDate = new Date(current_date.getFullYear(), current_date.getMonth(), i);
          scope.dayList.push({
            date: tempDate.getDate(),
            month: tempDate.getMonth(),
            year: tempDate.getFullYear(),
            day: tempDate.getDay(),
            dateString: tempDate.toString(),
            epochLocal: tempDate.getTime(),
            epochUTC: (tempDate.getTime() + (tempDate.getTimezoneOffset() * 60 * 1000))
          });
        }

        var firstDay = scope.dayList[0].day;

        scope.currentMonthFirstDayEpoch = scope.dayList[0].epochLocal;
        scope.currentMonthLastDayEpoch = scope.dayList[scope.dayList.length - 1].epochLocal;

        for (var j = 0; j < firstDay; j++) {
          scope.dayList.unshift({});
        }

        scope.rows = [];
        scope.cols = [];

        scope.currentMonth = currentDate.getMonth();
        scope.currentYear = current_date.getFullYear();
        scope.currentMonthSelected = scope.currentMonth;
        scope.currentYearSelected = scope.currentYear;

        scope.numColumns = 7;
        scope.rows.length = 6;
        scope.cols.length = scope.numColumns;
      };

      scope.monthChanged = function () {
        currentDate.setDate(3); // setting to arbitrary day in the middle of month. i.e. previous month if we're on the 31st
        currentDate.setMonth(scope.currentMonth);
        scope.currentYear = currentDate.getFullYear();
        refreshDateList(currentDate);
      };

      scope.yearChanged = function () {
        currentDate.setFullYear(scope.currentYear);
        refreshDateList(currentDate);
      };

      scope.prevMonth = function () {
        if (currentDate.getMonth() === 0) {
          currentDate.setMonth(11);
          currentDate.setFullYear(currentDate.getFullYear() - 1);
        }
        else {
          currentDate.setMonth(currentDate.getMonth() - 1);
        }
        scope.currentMonth = currentDate.getMonth();
        scope.currentYear = currentDate.getFullYear();

        refreshDateList(currentDate);
      };

      scope.nextMonth = function () {
        if (currentDate.getMonth() === 11) {
          currentDate.setFullYear(currentDate.getFullYear());
        }
        currentDate.setMonth(currentDate.getMonth() + 1);
        scope.currentMonth = currentDate.getMonth();
        scope.currentYear = currentDate.getFullYear();
        refreshDateList(currentDate);
      };

      scope.date_selection = {selected: false, selectedDate: '', submitted: false};

      scope.dateSelected = function (date) {
        scope.selctedDateString = date.dateString;
        scope.date_selection.selected = true;
        scope.date_selection.selectedDate = new Date(date.dateString);
        currentDate = new Date(date.dateString);
      };

      element.on("click", function () {
        var defaultDate = new Date();
        if (!scope.ipDate) {
          refreshDateList(defaultDate);
        } else {
          defaultDate = angular.copy(scope.ipDate);
          refreshDateList(defaultDate);
        }

        // set the current date if not selected
        if (!scope.date_selection.selected) {
          scope.dateSelected(getDateObject(defaultDate));
        }

        $ionicPopup.show({
          templateUrl: 'date-picker-modal.html',
          title: scope.datePickerTitle,
          subTitle: '',
          scope: scope,
          buttons: [
            {
              text: 'Close',
              onTap: function (e) {
                scope.callback(undefined);
              }
            },
            {
              text: 'Today',
              onTap: function (e) {

                var today = new Date();
                today.setHours(0);
                today.setMinutes(0);
                today.setSeconds(0);
                today.setMilliseconds(0);

                var tempEpoch = new Date(today.getFullYear(), today.getMonth(), today.getDate());
                var todayObj = {
                  date: today.getDate(),
                  month: today.getMonth(),
                  year: today.getFullYear(),
                  day: today.getDay(),
                  dateString: today.toString(),
                  epochLocal: tempEpoch.getTime(),
                  epochUTC: (tempEpoch.getTime() + (tempEpoch.getTimezoneOffset() * 60 * 1000))
                };

                scope.selctedDateString = todayObj.dateString;
                scope.date_selection.selected = true;
                scope.date_selection.selectedDate = new Date(todayObj.dateString);
                refreshDateList(new Date());
                e.preventDefault();
              }
            },
            {
              text: 'Set',
              type: 'button-positive',
              onTap: function (e) {
                scope.date_selection.submitted = true;

                if (scope.date_selection.selected === true) {
                  scope.ipDate = angular.copy(scope.date_selection.selectedDate);
                  scope.callback(scope.ipDate);
                } else {
                  e.preventDefault();
                }
              }
            }
          ]
        })
      })
    }
  }
}]);<commit_msg>Added rudimentary timezone support.<commit_after>//By Rajeshwar Patlolla
//https://github.com/rajeshwarpatlolla

"use strict";
var app = angular.module('ionic-datepicker', ['ionic', 'ionic-datepicker.templates']);

app.service('DatepickerService', function () {

});

app.directive('ionicDatepicker', ['$ionicPopup', '$injector', function ($ionicPopup, $injector) {
  return {
    restrict: 'AE',
    replace: true,
    scope: {
      ipDate: '=idate',
      disablePreviousDates: '=disablepreviousdates',
      disableFutureDates: '=disablefuturedates',
      callback: '=callback',
      title: '=title',
      disabledDates: '=?disableddates',
      timezone: '=timezone'
    },
    link: function (scope, element) {

      scope.datePickerTitle = scope.title || 'Select Date';
      var monthsList = [
        {
          id: 0, name: 'January'
        },
        {
          id: 1, name: 'February'
        },
        {
          id: 2, name: 'March'
        },
        {
          id: 3, name: 'April'
        },
        {
          id: 4, name: 'May'
        },
        {
          id: 5, name: 'June'
        },
        {
          id: 6, name: 'July'
        },
        {
          id: 7, name: 'August'
        },
        {
          id: 8, name: 'Sepetember'
        },
        {
          id: 9, name: 'October'
        },
        {
          id: 10, name: 'November'
        },
        {
          id: 11, name: 'December'
        }
      ];
      scope.monthsList = monthsList;
      var yearsList = [];
      for (i = 1901; i <= 2100; i++) {
        yearsList.push({ id: i, name: i });
      }

      scope.yearsList = yearsList;

      scope.currentMonth = '';
      scope.currentYear = '';

      if (!scope.ipDate) {
        scope.ipDate = new Date();
      }

      if (!angular.isDefined(scope.disabledDates)) {
        scope.disabledDates = [];
      } else {
        for (var i = 0; i < scope.disabledDates.length; i++) {
          scope.disabledDates[i] = scope.disabledDates[i].getTime();
        }
      }

      scope.previousDayEpoch = (+(new Date()) - 86400000);
      scope.nextDayEpoch = (+(new Date()));

      var currentDate = angular.copy(scope.ipDate);
      currentDate.setHours(0);
      currentDate.setMinutes(0);
      currentDate.setSeconds(0);
      currentDate.setMilliseconds(0);

      scope.selctedDateString = currentDate.toString();
      scope.weekNames = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
      scope.today = {};

      var getDateObject = function (date) {
        var tempDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
        return {
          dateObj: date,
          date: tempDate.getDate(),
          month: tempDate.getMonth(),
          year: tempDate.getFullYear(),
          day: tempDate.getDay(),
          dateString: tempDate.toString(),
          epochLocal: tempDate.getTime(),
          epochUTC: (tempDate.getTime() + (tempDate.getTimezoneOffset() * 60 * 1000))
        };
      };

      if (scope.timezone && $injector.has('moment')) {
        var moment = $injector.get('moment');
        var dt = moment().tz(scope.timezone);
        scope.today = getDateObject(new Date(dt.year(), dt.month(), dt.date()));
      } else {
        scope.today = getDateObject(new Date());
      }

      var refreshDateList = function (current_date) {
        current_date.setHours(0);
        current_date.setMinutes(0);
        current_date.setSeconds(0);
        current_date.setMilliseconds(0);

        currentDate = angular.copy(current_date);

        var firstDay = new Date(current_date.getFullYear(), current_date.getMonth(), 1).getDate();
        var lastDay = new Date(current_date.getFullYear(), current_date.getMonth() + 1, 0).getDate();

        scope.dayList = [];

        for (var i = firstDay; i <= lastDay; i++) {
          var tempDate = new Date(current_date.getFullYear(), current_date.getMonth(), i);
          scope.dayList.push({
            date: tempDate.getDate(),
            month: tempDate.getMonth(),
            year: tempDate.getFullYear(),
            day: tempDate.getDay(),
            dateString: tempDate.toString(),
            epochLocal: tempDate.getTime(),
            epochUTC: (tempDate.getTime() + (tempDate.getTimezoneOffset() * 60 * 1000))
          });
        }

        var firstDay = scope.dayList[0].day;

        scope.currentMonthFirstDayEpoch = scope.dayList[0].epochLocal;
        scope.currentMonthLastDayEpoch = scope.dayList[scope.dayList.length - 1].epochLocal;

        for (var j = 0; j < firstDay; j++) {
          scope.dayList.unshift({});
        }

        scope.rows = [];
        scope.cols = [];

        scope.currentMonth = currentDate.getMonth();
        scope.currentYear = current_date.getFullYear();
        scope.currentMonthSelected = scope.currentMonth;
        scope.currentYearSelected = scope.currentYear;

        scope.numColumns = 7;
        scope.rows.length = 6;
        scope.cols.length = scope.numColumns;
      };

      scope.monthChanged = function () {
        currentDate.setDate(3); // setting to arbitrary day in the middle of month. i.e. previous month if we're on the 31st
        currentDate.setMonth(scope.currentMonth);
        scope.currentYear = currentDate.getFullYear();
        refreshDateList(currentDate);
      };

      scope.yearChanged = function () {
        currentDate.setFullYear(scope.currentYear);
        refreshDateList(currentDate);
      };

      scope.prevMonth = function () {
        if (currentDate.getMonth() === 0) {
          currentDate.setMonth(11);
          currentDate.setFullYear(currentDate.getFullYear() - 1);
        }
        else {
          currentDate.setMonth(currentDate.getMonth() - 1);
        }
        scope.currentMonth = currentDate.getMonth();
        scope.currentYear = currentDate.getFullYear();

        refreshDateList(currentDate);
      };

      scope.nextMonth = function () {
        if (currentDate.getMonth() === 11) {
          currentDate.setFullYear(currentDate.getFullYear());
        }
        currentDate.setMonth(currentDate.getMonth() + 1);
        scope.currentMonth = currentDate.getMonth();
        scope.currentYear = currentDate.getFullYear();
        refreshDateList(currentDate);
      };

      scope.date_selection = {selected: false, selectedDate: '', submitted: false};

      scope.dateSelected = function (date) {
        scope.selctedDateString = date.dateString;
        scope.date_selection.selected = true;
        scope.date_selection.selectedDate = new Date(date.dateString);
        currentDate = new Date(date.dateString);
      };

      element.on("click", function () {
        var defaultDate = new Date();
        if (!scope.ipDate) {
          refreshDateList(defaultDate);
        } else {
          defaultDate = angular.copy(scope.ipDate);
          refreshDateList(defaultDate);
        }

        // set the current date if not selected
        if (!scope.date_selection.selected) {
          scope.dateSelected(getDateObject(defaultDate));
        }

        $ionicPopup.show({
          templateUrl: 'date-picker-modal.html',
          title: scope.datePickerTitle,
          subTitle: '',
          scope: scope,
          buttons: [
            {
              text: 'Close',
              onTap: function (e) {
                scope.callback(undefined);
              }
            },
            {
              text: 'Today',
              onTap: function (e) {

                var today;
                if (scope.timezone && $injector.has('moment')) {
                  var moment = $injector.get('moment');
                  var dt = moment().tz(scope.timezone);
                  today = new Date(dt.year(), dt.month(), dt.date());
                } else {
                  today = new Date();
                }
                today.setHours(0);
                today.setMinutes(0);
                today.setSeconds(0);
                today.setMilliseconds(0);

                var tempEpoch = new Date(today.getFullYear(), today.getMonth(), today.getDate());
                var todayObj = {
                  date: today.getDate(),
                  month: today.getMonth(),
                  year: today.getFullYear(),
                  day: today.getDay(),
                  dateString: today.toString(),
                  epochLocal: tempEpoch.getTime(),
                  epochUTC: (tempEpoch.getTime() + (tempEpoch.getTimezoneOffset() * 60 * 1000))
                };

                scope.selctedDateString = todayObj.dateString;
                scope.date_selection.selected = true;
                scope.date_selection.selectedDate = new Date(todayObj.dateString);
                refreshDateList(new Date());
                e.preventDefault();
              }
            },
            {
              text: 'Set',
              type: 'button-positive',
              onTap: function (e) {
                scope.date_selection.submitted = true;

                if (scope.date_selection.selected === true) {
                  scope.ipDate = angular.copy(scope.date_selection.selectedDate);
                  scope.callback(scope.ipDate);
                } else {
                  e.preventDefault();
                }
              }
            }
          ]
        })
      })
    }
  }
}]);
<|endoftext|>


<commit_before>const express = require('express');
// const h5bp = require('h5bp');
const path = require('path');
const favicon = require('serve-favicon');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');

// Define Routes
const index = require('./routes/index');

// Create express app with html5 boilerplate
const app = express();
// app.use(h5bp({
//     root: path.join(__dirname, 'public'),
//     processor: 'commonjs'
// }));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// Middleware
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// Use routes
app.use('/', index);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handler
app.use(function(err, req, res) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;
<commit_msg>extend index path<commit_after>const express = require('express');
// const h5bp = require('h5bp');
const path = require('path');
const favicon = require('serve-favicon');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');

// Define Routes
const index = require('./routes/index');

// Create express app with html5 boilerplate
const app = express();
// app.use(h5bp({
//     root: path.join(__dirname, 'public'),
//     processor: 'commonjs'
// }));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// Middleware
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// Use routes
app.use('/projects/CareForce-Lumber-Calculator', index);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handler
app.use(function(err, req, res) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;
<|endoftext|>