diff --git a/LICENSE.TXT b/LICENSE.TXT index f8d7956..62319f3 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,4 +1,4 @@ -Copyright (c) 2006-2024, Peter Borissow +Copyright (c) 2006-2025, Peter Borissow Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/button/Button.js b/src/button/Button.js index 4949514..7209e8e 100644 --- a/src/button/Button.js +++ b/src/button/Button.js @@ -201,7 +201,7 @@ javaxt.dhtml.Button = function(parent, config) { //Create outer div used to hold the button, mask, and menu var outerDiv = createElement('div', parent); - outerDiv.setAttribute("desc", me.className); + outerDiv.className = "javaxt-button"; outerDiv.style.display = config.display; if (config.width){ if (typeof config.width === "string"){ diff --git a/src/carousel/Carousel.js b/src/carousel/Carousel.js index ab2298f..20b358d 100644 --- a/src/carousel/Carousel.js +++ b/src/carousel/Carousel.js @@ -9,6 +9,42 @@ if(!javaxt.dhtml) javaxt.dhtml={}; * can cycle through the panels using the back() and next() functions. The * carousel can store a fixed set of panels or you can create the illusion * of having infinite panels by updating panels when they are out of view. + * Example: +
+ var carousel = new javaxt.dhtml.Carousel(parent,{ + loop: true, + animate: true + }); ++ * Once the carousel is instantiated you can call any of the public methods. + * The first thing to do is to add panels. Example: +
+ var p1 = document.createElement('div'); + p1.style.background = "#f0f8ff"; + p1.style.height = "100%"; + carousel.add(p1); + + var p2 = document.createElement('div'); + p2.style.background = "#96a5b2"; + p2.style.height = "100%"; + carousel.add(p2); + + var p3 = document.createElement('div'); + p3.style.background = "#ffd8d6"; + p3.style.height = "100%"; + carousel.add(p3); ++ * After panels have been added to the carousel, you can call the back() and + * next() methods to switch panels. Typically these methods are called from + * "onclick" events fired from other DOM elements (e.g. button). + * + * Finally, you can also add event listeners by overriding any of the public + * "on" or "before" methods like this: +
+ carousel.onChange = function(currPanel, prevPanel){ + console.log("currPanel", currPanel); + }; +* ******************************************************************************/ @@ -140,7 +176,7 @@ javaxt.dhtml.Carousel = function(parent, config) { height: "100%", position: "relative" }); - outerDiv.setAttribute("desc", me.className); + outerDiv.className = "javaxt-carousel"; me.el = outerDiv; @@ -337,6 +373,8 @@ javaxt.dhtml.Carousel = function(parent, config) { //************************************************************************** //** resize //************************************************************************** + /** Used to force the component to resize to fit the parent container + */ this.resize = function(){ var w = outerDiv.offsetWidth; if (w===0 || isNaN(w)){ @@ -528,7 +566,7 @@ javaxt.dhtml.Carousel = function(parent, config) { nextDiv = nextPanel.childNodes[0].childNodes[0]; - me.beforeChange(currDiv, nextDiv); + me.beforeChange(currDiv, nextDiv, "next"); var onChange = function(){ me.onChange(nextDiv, currDiv); @@ -574,7 +612,7 @@ javaxt.dhtml.Carousel = function(parent, config) { nextDiv = clone.childNodes[0].childNodes[0]; - me.beforeChange(currDiv, nextDiv); + me.beforeChange(currDiv, nextDiv, "next"); var onChange = function(){ innerDiv.style.left = start + "px"; @@ -682,7 +720,7 @@ javaxt.dhtml.Carousel = function(parent, config) { nextDiv = nextPanel.childNodes[0].childNodes[0]; - me.beforeChange(currDiv, nextDiv); + me.beforeChange(currDiv, nextDiv, "back"); var onChange = function(){ me.onChange(nextDiv, currDiv); @@ -729,7 +767,7 @@ javaxt.dhtml.Carousel = function(parent, config) { nextDiv = clone.childNodes[0].childNodes[0]; - me.beforeChange(currDiv, nextDiv); + me.beforeChange(currDiv, nextDiv, "back"); var onChange = function(){ me.onChange(nextDiv, currDiv); @@ -801,8 +839,9 @@ javaxt.dhtml.Carousel = function(parent, config) { /** Called before the carousel switches panels. * @param currPanel Content of the active panel * @param prevPanel Content of the next active panel + * @param direction "back" or "next" */ - this.beforeChange = function(currPanel, nextPanel){}; + this.beforeChange = function(currPanel, nextPanel, direction){}; //************************************************************************** diff --git a/src/combobox/ComboBox.js b/src/combobox/ComboBox.js index 0668246..34fbb42 100644 --- a/src/combobox/ComboBox.js +++ b/src/combobox/ComboBox.js @@ -199,7 +199,7 @@ javaxt.dhtml.ComboBox = function(parent, config) { //Create main div var mainDiv = createElement("div", parent); - mainDiv.setAttribute("desc", me.className); + mainDiv.className = "javaxt-combobox"; mainDiv.style.width = config.style.width; mainDiv.style.position = "relative"; me.el = mainDiv; @@ -501,6 +501,7 @@ javaxt.dhtml.ComboBox = function(parent, config) { * dropdown menu. */ this.reset = function(){ + me.hideMenu(); //Remove everything that's not an input var a = []; @@ -515,7 +516,8 @@ javaxt.dhtml.ComboBox = function(parent, config) { //Ensure the input is visible input.show(); - + + input.blur(); }; diff --git a/src/datagrid/DataGrid.js b/src/datagrid/DataGrid.js index 27fa0b7..8bccdf4 100644 --- a/src/datagrid/DataGrid.js +++ b/src/datagrid/DataGrid.js @@ -1,1725 +1,1796 @@ -if(!javaxt) var javaxt={}; -if(!javaxt.dhtml) javaxt.dhtml={}; - -//****************************************************************************** -//** DataGrid -//****************************************************************************** -/** - * Custom grid control based on javaxt.dhtml.Table. Supports remote loading, - * sorting, and infinite scroll. - *
- var grid = new javaxt.dhtml.DataGrid(parent, { - style: config.style.table, - url: "/manage/users", - parseResponse: function(request){ - return JSON.parse(request.responseText); - }, - columns: [ - {header: 'ID', hidden:true}, - {header: 'Name', width:'100%'}, - {header: 'Role', width:'240'}, - {header: 'Enabled', width:'75', align:'center'}, - {header: 'Last Active', width:'175', align:'right'} - ], - update: function(row, user){ - row.set('Name', user.fullname); - row.set('Role', user.role); - var status = user.status; - if (status===1){ - row.set('Enabled', createElement("i", "fas fa-check")); - } - }, - autoload: true - }); -- * Once the grid is instantiated you can call any of the public methods. You - * can also add event listeners by overriding any of the public "on" or - * "before" methods like this: -
- grid.onRowClick = function(row, e){ - console.log(row.record); - }; -- * - ******************************************************************************/ - -javaxt.dhtml.DataGrid = function(parent, config) { - this.className = "javaxt.dhtml.DataGrid"; - - var me = this; - var table; - var mask; - - var currPage = 1; - var eof = false; - var pageRequests = {}; - var loading = false; - - var checkboxHeader; - var columns; - var rowHeight; //<-- Assumes all the rows are the same height! - - - //Legacy config parameters - var filterName, filter; - - - - //Create default style - var defaultStyle = {}; - if (javaxt.dhtml.style){ - if (javaxt.dhtml.style.default){ - var tableStyle = javaxt.dhtml.style.default.table; - if (tableStyle){ - defaultStyle = tableStyle; - var checkboxStyle = javaxt.dhtml.style.default.checkbox; - defaultStyle.checkbox = checkboxStyle; - } - } - } - - - - //Set default config - var defaultConfig = { - - - /** Style config. See default styles in javaxt.dhtml.Table for a list of - * options. In addition to the table styles, you can also specify a - * checkbox style - */ - style: defaultStyle, - - /** The URL endpoint that this component uses to fetch records - */ - url: "", - - /** JSON object with key/value pairs that are appended to the URL - */ - params: null, - - /** Data to send in the body of the request. This parameter is optional. - * If payload is not null, the component executes a POST request. - */ - payload: null, - - /** If true, and if the payload is empty, will sent params as a URL - * encoded string in a POST request. Otherwise the params will be - * appended to the query string in the request URL. - */ - post: false, - - /** Used to specify the page size (i.e. the maximum number records to - * fetch from the server at a time) - */ - limit: 50, - - /** If true, the server will be asked to return a total record count. - * This is a legacy feature and is NOT required for pagination. - */ - count: false, - - /** If true, the grid will automatically fetch records from the server - * on start-up - */ - autoload: false, - - /** If true, the grid will sort values in the grid locally using whatever - * data is available. If fetching data from a remote server, recommend - * setting localSort to false (default) - */ - localSort: false, - - /** Optional list of field names used to specify which database fields - * should be returned from the server. If not provided, uses the "field" - * attributes in the column definition. If both are provided, the list - * of fields are merged into a unique list. - */ - fields: [], - - /** If true, will hide the header row. Default is false. - */ - hideHeader: false, - - /** Default method used to get responses from the server. Typically, you - * do not need to override this method. - */ - getResponse: function(url, payload, callback){ - - - //Transform GET request into POST request if possible. This will - //tidy up the URLs and reduce log size - var contentType; - if (!payload && config.post==true){ - contentType = "application/x-www-form-urlencoded"; - var idx = url.indexOf("?"); - if (idx>-1){ - payload = url.substring(idx+1); - url = url.substring(0, idx); - } - } - - - //Get response - javaxt.dhtml.utils.get(url, { - payload: payload, - contentType: contentType, - success: function(text, xml, url, request){ - callback.apply(me, [request]); - }, - failure: function(request){ - callback.apply(me, [request]); - } - }); - }, - - /** Default method used to parse responses from the server. Should return - * an array of rows with an array of values in each row. Example: - * [["Bob","12/30","$5.25"],["Jim","10/28","$7.33"]] - */ - parseResponse: function(request){ - return []; - }, - - /** Default method used to update a row with values. This method can be - * overridden to render values in a variety of different ways (e.g. - * different fonts, links, icons, etc). The row.set() method accepts - * strings, numbers, and DOM elements. - */ - update: function(row, record){ - for (var i=0; i
+ var grid = new javaxt.dhtml.DataGrid(parent, { + + //Set style + style: config.style.table, + + //Define columns + columns: [ + {header: 'ID', hidden:true}, + {header: 'Name', width:'100%'}, + {header: 'Role', width:'240'}, + {header: 'Enabled', width:'75', align:'center'}, + {header: 'Last Active', width:'175', align:'right'} + ], + + //Set path to REST endpoint to get list of users + url: "/manage/users", + + //Define function used to parse the response + parseResponse: function(request){ + return JSON.parse(request.responseText); + }, + + //Define function used to render data for individual rows + update: function(row, user){ + row.set('Name', user.fullname); + row.set('Role', user.role); + var status = user.status; + if (status===1){ + row.set('Enabled', createElement("i", "fas fa-check")); + } + }, + + //Set flag to automatically load data once the component is rendered + autoload: true + }); ++ * Once the grid is instantiated you can call any of the public methods. You + * can also add event listeners by overriding any of the public "on" or + * "before" methods like this: +
+ grid.onRowClick = function(row, e){ + console.log(row.record); + }; ++ * + ******************************************************************************/ + +javaxt.dhtml.DataGrid = function(parent, config) { + this.className = "javaxt.dhtml.DataGrid"; + + var me = this; + var table; + var mask; + + var currPage = 1; + var eof = false; + var pageRequests = {}; + var loading = false; + + var checkboxHeader; + var columns; + var rowHeight; //<-- Assumes all the rows are the same height! + + + //Legacy config parameters + var filterName, filter; + + + + //Create default style + var defaultStyle = {}; + if (javaxt.dhtml.style){ + if (javaxt.dhtml.style.default){ + var tableStyle = javaxt.dhtml.style.default.table; + if (tableStyle){ + defaultStyle = tableStyle; + var checkboxStyle = javaxt.dhtml.style.default.checkbox; + defaultStyle.checkbox = checkboxStyle; + } + } + } + + + + //Set default config + var defaultConfig = { + + + /** Style config. See default styles in javaxt.dhtml.Table for a list of + * options. In addition to the table styles, you can also specify a + * checkbox style. + */ + style: defaultStyle, + + /** Used to define columns to display. Each entry in the array should + * include a "header" label (see example above) along with a "width". + * Note that one of the columns should have a width of 100%. Additional + * options include "align" and "field". If a "field" is provided it will + * be used to construct a "fields" parameter to that is sent to the + * server (see "fields" config). Fially, you can specify a checkbox + * column by setting the "header" to "x" (e.g. header: 'x'). If a + * checkbox column is defined, a checkbox will be created in the header + * and in individual rows. The checkbox is typically used to support + * multi-select operations. + */ + columns: [], + + /** The URL endpoint that this component uses to fetch records + */ + url: "", + + /** JSON object with key/value pairs that are appended to the URL + */ + params: null, + + /** Data to send in the body of the request. This parameter is optional. + * If payload is not null, the component executes a POST request. + */ + payload: null, + + /** If true, and if the payload is empty, will sent params as a URL + * encoded string in a POST request. Otherwise the params will be + * appended to the query string in the request URL. Default is false. + */ + post: false, + + /** Used to specify the page size (i.e. the maximum number records to + * fetch from the server at a time). Default is 50. + */ + limit: 50, + + /** If true, the server will be asked to return a total record count by + * setting the "count" parameter to true when requesting the first page. + * Otherwise, the count parameter is set to false. Note that the count + * is NOT required for pagination and is not used internally in any way. + * Rather it is for informational purposes only. Default is false. + */ + count: false, + + /** If true, the grid will automatically fetch records from the server + * on start-up. Default is false. + */ + autoload: false, + + /** If true, the grid will sort values in the grid locally using whatever + * data is available. If fetching data from a remote server, recommend + * setting localSort to false (default) + */ + localSort: false, + + /** Optional list of field names used to specify which database fields + * should be returned from the server. If not provided, uses the "field" + * attributes in the column definition. If both are provided, the list + * of fields are merged into a unique list. + */ + fields: [], + + /** If true, will hide the header row. Default is false. + */ + hideHeader: false, + + /** If true, the table will allow users to select multiple rows using + * control or shift key. Default is false (only one row is selected at + * a time). + */ + multiselect: false, + + /** Default method used to get responses from the server. Typically, you + * do not need to override this method. + */ + getResponse: function(url, payload, callback){ + + + //Transform GET request into POST request if possible. This will + //tidy up the URLs and reduce log size + var contentType; + if (!payload && config.post==true){ + contentType = "application/x-www-form-urlencoded"; + var idx = url.indexOf("?"); + if (idx>-1){ + payload = url.substring(idx+1); + url = url.substring(0, idx); + } + } + + + //Get response + javaxt.dhtml.utils.get(url, { + payload: payload, + contentType: contentType, + success: function(text, xml, url, request){ + callback.apply(me, [request]); + }, + failure: function(request){ + callback.apply(me, [request]); + } + }); + }, + + /** Default method used to parse responses from the server. Should return + * an array of rows with an array of values in each row. Example: + * [["Bob","12/30","$5.25"],["Jim","10/28","$7.33"]] + */ + parseResponse: function(request){ + return []; + }, + + /** Default method used to update a row with values. This method can be + * overridden to render values in a variety of different ways (e.g. + * different fonts, links, icons, etc). The row.set() method accepts + * strings, numbers, and DOM elements. + */ + update: function(row, record){ + for (var i=0; i
+ grid.forEachRow(function(row, content){ + //Do something with the row + + //Stop iterating once some contition is met + if (1>0) return true; + }); ++ */ + this.forEachRow = function(callback){ + table.forEachRow(callback); + }; + + + //************************************************************************** + //** select + //************************************************************************** + /** Used to select a given row in the grid + */ + this.select = function(row){ + table.select(row); + }; + + + //************************************************************************** + //** selectAll + //************************************************************************** + /** Selects all the rows in the grid + */ + this.selectAll = function(){ + table.selectAll(); + }; + + + //************************************************************************** + //** deselectAll + //************************************************************************** + /** Deselects all the rows in the grid + */ + this.deselectAll = function(){ + table.deselectAll(); + }; + + + //************************************************************************** + //** clear + //************************************************************************** + /** Removes all the rows from the grid + */ + this.clear = function(){ + table.clear(); + currPage = 1; + pageRequests = {}; + if (checkboxHeader) checkboxHeader.uncheck(); + }; + + + //************************************************************************** + //** remove + //************************************************************************** + /** Removes a row from the grid + */ + this.remove = function(row){ + table.removeRow(row); + }; + + + //************************************************************************** + //** show + //************************************************************************** + /** Used to unhide the grid if it is hidden + */ + this.show = function(){ + table.show(); + }; + + + //************************************************************************** + //** hide + //************************************************************************** + /** Used to hide the grid + */ + this.hide = function(){ + table.hide(); + }; + + + //************************************************************************** + //** focus + //************************************************************************** + /** Used to set browser focus on the table. + */ + this.focus = function(){ + table.focus(); + }; + + + //************************************************************************** + //** refresh + //************************************************************************** + /** Used to clear the grid and reload the first page. + * @param callback Optional callback function called after the grid has + * been refreshed and loaded with data. + */ + this.refresh = function(callback){ + me.clear(); + //eof = false; + setPage(1); + load(1, callback); + }; + + + //************************************************************************** + //** load + //************************************************************************** + /** Used to load records from the remote store. Optionally, you can pass an + * array of records, along with a page number, to append rows to the table. + */ + this.load = function(){ + + if (arguments.length>0){ + + var records = arguments[0]; + var page = 1; + if (arguments.length>1) page = parseInt(arguments[1]); + if (isNaN(page) || page<1) page = 1; + + + if (isArray(records) || records instanceof javaxt.dhtml.DataStore){ + me.beforeLoad(page); + table.load(records, page>1); + setPage(page); + calculateRowHeight(); + + + if (arguments.length===1){ + eof = true; + } + else{ //caller provided a page number + if (records.length
- columns: [ - {header: 'ID', hidden:true}, - {header: 'Name', width:'100%'}, - {header: 'Username', width:'150'}, - {header: 'Role', width:'100'}, - {header: 'Enabled', width:'80', align:'center'}, - {header: 'Last Active', width:'150', align:'right'} - ] -- Column headers are used as labels in the header row. They are also - used as column identifiers using the get and set methods for a row. - - Column widths can be defined using percentages (e.g. '100%') or in - pixels (e.g. '100px' or '100' or 100). Normally, there should be one - column with a width of '100%'. This will allow the column fill all - available area not occupied by columns with fixed column widths. The - only exception is to define multiple columns with percentages as long - as all the percentages add up to 100%. - - Column alignment is used to set the alignment of the cells associated - with the column. Options include 'left', 'right', and 'center'. - */ - columns: [], - - - /** If true, the table will allow users to select multiple rows using - * control or shift key. Default is false (only one row is selected at - * a time). - */ - multiselect: false, - - - /** If true, the table will render a vertical scrollbar, allowing users - * to scroll up/down and see rows that are out of view. If false, the - * scrollbar is hidden from view. Default is true. - */ - overflow: true, - - - /** If true, will hide the header row. Default is false. - */ - hideHeader: false, - - - /** If true, will set browser focus on the table when the mouse is - * detected over the table. Default is false. - */ - focusOnMouseover: false, - - - /** Style for individual elements within the component. Note that you can - * provide CSS class names instead of individual style definitions. - */ - style: { - - table: { - width: "100%", - height: "100%", - margin: 0, - padding: 0, - borderCollapse: "collapse" - }, - - headerRow: { - height: "35px", - borderBottom: "1px solid #8f8f8f", - background: "#eaeaea" - }, - - headerColumn: { - lineHeight: "35px", - borderLeft: "1px solid #cccccc", - borderRight: "1px solid #cccccc", - padding: "0 5px", - color: "#272727", - cursor: "pointer", - whiteSpace: "nowrap" - }, - - row: { - height: "35px", - borderBottom: "1px solid #cccccc" - }, - - column: { - height: "35px", - lineHeight: "35px", - borderLeft: "1px solid #cccccc", - borderRight: "1px solid #cccccc", - padding: "0 5px", - color: "#272727", - cursor: "default", - whiteSpace: "nowrap" - }, - - selectedRow: { - height: "35px", - borderBottom: "1px solid #cccccc", - backgroundColor: "#FFFFB1" - }, - - resizeHandle: { - width: "5px", - cursor: "col-resize", - marginRight: "-2px" - }, - - mask: { - backgroundColor: "rgba(0,0,0,0.5)" - }, - - /** Style for iScroll (if present). If the style is set to null or - * false, uses inline style. If a "custom" keyword is given, will - * use "iScrollHorizontalScrollbar", "iScrollVerticalScrollbar", - * and "iScrollIndicator" classes defined in your css. You can also - * define custom class names by providing a style map like this: -
- iscroll: { - horizontalScrollbar: "my-iScrollHorizontalScrollbar", - verticalScrollbar: "my-iScrollVerticalScrollbar", - indicator: "my-iScrollIndicator", - columnWidth: "15px" - } -- */ - iscroll: null - } - }; - - - //************************************************************************** - //** Constructor - //************************************************************************** - /** Creates a new instance of this class. */ - - var init = function(){ - - if (typeof parent === "string"){ - parent = document.getElementById(parent); - } - if (!parent) return; - - - - //Clone the config so we don't modify the original config object - var clone = {}; - merge(clone, config); - - - //Merge clone with default config - merge(clone, defaultConfig); - config = clone; - - - //Parse config - if (!config.columns || config.columns.length===0) return; - if (typeof IScroll !== 'undefined'){ - var columnWidth = config.style.iscroll ? config.style.iscroll.columnWidth : null; - if (!columnWidth) columnWidth = "15px"; - - if (columnWidth<=0 || columnWidth==="0px" || columnWidth==="0%"){ - //Allow users to not have a spacer for iScroll - } - else{ - config.columns.push({header: '', width: columnWidth}); - } - } - - - //Create main table - var table, tr, td; - table = createTable(parent); - table.setAttribute("desc", me.className); - setStyle(table, "table"); - me.el = table; - addShowHide(me); - - addMask(parent); - - - //Create header - tr = table.addRow(); - tr.setAttribute("desc", "Header Row"); - setStyle(tr, "headerRow"); - td = tr.addColumn(); - td.style.width = "100%"; - td.style.height = "inherit"; - header = createTable(td); - if (config.hideHeader===true){ - tr.style.visibility = 'hidden'; - tr.style.display = 'none'; - } - - - - //Create body - tr = table.addRow(); - tr.setAttribute("desc", "Body Row"); - td = tr.addColumn({ - width: "100%", - height: "100%" - }); - - - bodyDiv = createElement('div', td, { - width: "100%", - height: "100%", - position: "relative" - }); - bodyDiv.setAttribute("desc", "body-div"); - bodyDiv.tabIndex = -1; //allows the div to have focus - bodyDiv.onmouseover = function(){ - if (config.focusOnMouseover===true){ - var x = window.scrollX, y = window.scrollY; - this.focus(); - window.scrollTo(x, y); - } - }; - bodyDiv.addEventListener("keydown", function(e){ - if (e.keyCode===16){ - shiftIsPressed = true; - } - - if (e.keyCode===17){ - cntrlIsPressed = true; - } - - if (e.keyCode===18){ - altIsPressed = true; - } - - - //Prevent window from scrolling - if (e.keyCode===38 || e.keyCode===40){ - e.preventDefault(); - e.stopPropagation(); - } - - }); - bodyDiv.addEventListener("keyup", function(e){ - if (e.keyCode===16){ - shiftIsPressed = false; - } - - if (e.keyCode===17){ - cntrlIsPressed = false; - } - - if (e.keyCode===18){ - altIsPressed = false; - } - - if (e.keyCode===38 || e.keyCode===40){ - - var lastSelectedRow, lastRow; - me.forEachRow(function (row) { - if (row.selected){ - lastSelectedRow = row; - } - lastRow = row; - }); - - - if (lastSelectedRow){ - var row; - if (e.keyCode===40){ //down arrow - row = lastSelectedRow.nextSibling; - } - else{ //up arrow - row = lastSelectedRow.previousSibling; - } - - if (row){ - me.scrollTo(row); - row.click(); - } - } - - } - - me.onKeyEvent(e.keyCode, { - shift: shiftIsPressed, - ctrl: cntrlIsPressed, - alt: altIsPressed - }); - }); - - - - bodyDiv = createElement('div', bodyDiv, { - width: "100%", - height: "100%", - position: "absolute", - overflow: "scroll", - overflowX: "hidden" - }); - body = createTable(bodyDiv); - body.style.height = ''; - - - - //Populate header - tr = createPhantomRow(header, 1); - var spacerUR = createElement('div', tr.addColumn()); - - - tr = header.addRow(); - for (var i=0; i
- table.addRow(["Bob","12/30","$5.25"]); -- */ - this.addRow = function(){ - - var data = arguments; - - - //Check if the first argument is an array. If so, use it. - //Otherwise, we'll use all the arguments as data. - if (isArray(data[0])) data = data[0]; - - - //Create row - var row = body.addRow(); - row.selected = false; - setStyle(row, "row"); - - - //Add custom functions to the row - row.get = getRowContent; - row.set = setRowContent; - row.onclick = selectRows; - - - //Create template as needed. The template is a collection of cells that - //are cloned whenever a new row is added. This approach results in faster - //row rendering. - if (!template){ - template = []; - for (var i=0; i
- table.onSelectionChange = function(rows){ - for (var i=0; i+ Column headers are used as labels in the header row. They are also + used as column identifiers using the get and set methods for a row. + + Column widths can be defined using percentages (e.g. '100%') or in + pixels (e.g. '100px' or '100' or 100). Normally, there should be one + column with a width of '100%'. This will allow the column fill all + available area not occupied by columns with fixed column widths. The + only exception is to define multiple columns with percentages as long + as all the percentages add up to 100%. + + Column alignment is used to set the alignment of the cells associated + with the column. Options include 'left', 'right', and 'center'. + */ + columns: [], + + + /** If true, the table will allow users to select multiple rows using + * control or shift key. Default is false (only one row is selected at + * a time). + */ + multiselect: false, + + + /** If true, the table will render a vertical scrollbar, allowing users + * to scroll up/down and see rows that are out of view. If false, the + * scrollbar is hidden from view. Default is true. + */ + overflow: true, + + + /** If true, will hide the header row. Default is false. + */ + hideHeader: false, + + + /** If true, will set browser focus on the table when the mouse is + * detected over the table. Default is false. + */ + focusOnMouseover: false, + + + /** Style for individual elements within the component. Note that you can + * provide CSS class names instead of individual style definitions. + */ + style: { + + table: { + width: "100%", + height: "100%", + margin: 0, + padding: 0, + borderCollapse: "collapse" + }, + + headerRow: { + height: "35px", + borderBottom: "1px solid #8f8f8f", + background: "#eaeaea" + }, + + headerColumn: { + lineHeight: "35px", + borderLeft: "1px solid #cccccc", + borderRight: "1px solid #cccccc", + padding: "0 5px", + color: "#272727", + cursor: "pointer", + whiteSpace: "nowrap" + }, + + row: { + height: "35px", + borderBottom: "1px solid #cccccc" + }, + + column: { + height: "35px", + lineHeight: "35px", + borderLeft: "1px solid #cccccc", + borderRight: "1px solid #cccccc", + padding: "0 5px", + color: "#272727", + cursor: "default", + whiteSpace: "nowrap" + }, + + selectedRow: { + height: "35px", + borderBottom: "1px solid #cccccc", + backgroundColor: "#FFFFB1" + }, + + resizeHandle: { + width: "5px", + cursor: "col-resize", + marginRight: "-2px" + }, + + mask: { + backgroundColor: "rgba(0,0,0,0.5)" + }, + + /** Style for iScroll (if present). If the style is set to null or + * false, uses inline style. If a "custom" keyword is given, will + * use "iScrollHorizontalScrollbar", "iScrollVerticalScrollbar", + * and "iScrollIndicator" classes defined in your css. You can also + * define custom class names by providing a style map like this: +- @param rows An array of rows that have had thier selection changed - */ - this.onSelectionChange = function(rows){}; - - - - //************************************************************************** - //** onRowClick - //************************************************************************** - /** Called whenever a row in the table is clicked. Use the onSelectionChange - * event listener to determine whether selection has changed. - */ - this.onRowClick = function(row, e){}; - - - //************************************************************************** - //** onHeaderClick - //************************************************************************** - /** Called whenever a header cell is clicked. - */ - this.onHeaderClick = function(idx, colConfig, cell, event){}; - - - //************************************************************************** - //** onKeyEvent - //************************************************************************** - /** Called whenever a keyboard event is initiated from the table. - */ - this.onKeyEvent = function(keyCode, modifiers){}; - - - //************************************************************************** - //** focus - //************************************************************************** - /** Used to set browser focus on the table. - */ - this.focus = function(){ - var x = window.scrollX, y = window.scrollY; - bodyDiv.parentNode.focus(); - window.scrollTo(x, y); - }; - - - //************************************************************************** - //** clear - //************************************************************************** - /** Removes all the rows from the table - */ - this.clear = function(){ - if (!body) return; - me.deselectAll(); - var childNodes = body.getRows(); - while (childNodes.length>1){ - body.removeRow(childNodes[1]); - childNodes = body.getRows(); - } - me.update(); - }; - - - //************************************************************************** - //** update - //************************************************************************** - /** Used to refresh the scroll bars. This method is called internally - * whenever rows are added or removed from the table. - */ - this.update = function(){ - if (me.iScroll) me.iScroll.refresh(); - me.onOverflow(me.hasOverflow()); - }; - - - //************************************************************************** - //** hasOverflow - //************************************************************************** - /** Returns true if the table is overflowing. - */ - this.hasOverflow = function(){ - return (bodyDiv.offsetHeight < bodyDiv.scrollHeight || - bodyDiv.offsetWidth < bodyDiv.scrollWidth); - }; - - - //************************************************************************** - //** onOverflow - //************************************************************************** - /** Called whenever the table overflow status changes. - */ - this.onOverflow = function(hasOverflow){}; - - - //************************************************************************** - //** onScroll - //************************************************************************** - /** Called whenever the table is scrolled. Implementations of this method - * can be used, for example, to load records when a client scrolls to the - * bottom of the page. - */ - this.onScroll = function(y, maxY, h){}; - - - //************************************************************************** - //** scrollTo - //************************************************************************** - /** Used to scroll to a specific x/y location when the table has an - * overflow. - * @param x Accepts an x position (integer) or a row in the table - * @param y Accepts a y position. Ignored if x is a row. - */ - this.scrollTo = function(x, y){ - - var bodyRect = javaxt.dhtml.utils.getRect(bodyDiv); - - - //If x is a row, compute the y offset - if (isElement(x)){ - - var rowRect = javaxt.dhtml.utils.getRect(x); - var padding = rowRect.height/2; - var padRect = { - left: bodyRect.left, - right: bodyRect.right, - top: bodyRect.top+padding, - bottom: bodyRect.bottom-padding - }; - - - if (!javaxt.dhtml.utils.intersects(padRect, rowRect)){ - - var scrollInfo = me.getScrollInfo(); - var ry = rowRect.top + scrollInfo.y; - - if (ry>bodyRect.bottom){ - - //console.log("scroll down!"); - y = ry+rowRect.height-bodyRect.bottom; - - } - else if (ry+rowRect.height>bodyRect.top){ - - //console.log("scroll up!"); - y = ry-bodyRect.top; - - } - else{ - //console.log("scroll?"); - } - } - } - - - if (!isNumber(y)) return; - - - //Update the scroll position - if (me.iScroll){ - me.iScroll.scrollTo(0, -y); - } - else{ - bodyDiv.scrollTop = y; - } - - - //Fire the onScroll event - var maxY = bodyDiv.scrollHeight - bodyDiv.clientHeight; - me.onScroll(y, maxY, bodyRect.height); - }; - - - //************************************************************************** - //** getScrollInfo - //************************************************************************** - /** Returns scroll position and dimenstions for the visible area. - */ - this.getScrollInfo = function(){ - return { - x: me.iScroll ? -me.iScroll.x : bodyDiv.scrollLeft, - y: me.iScroll ? -me.iScroll.y : bodyDiv.scrollTop, - w: bodyDiv.offsetWidth, - h: bodyDiv.offsetHeight, - maxY: bodyDiv.scrollHeight - bodyDiv.clientHeight, - enabled: scrollEnabled - }; - }; - - - //************************************************************************** - //** enableScroll - //************************************************************************** - /** Used to enable scrolling. - */ - this.enableScroll = function(){ - scrollEnabled = true; - }; - - - //************************************************************************** - //** disableScroll - //************************************************************************** - /** Used to disable scrolling. - */ - this.disableScroll = function(){ - scrollEnabled = false; - }; - - - //************************************************************************** - //** isScrollEnabled - //************************************************************************** - /** Returns true if scrolling is enabled. - */ - this.isScrollEnabled = function(){ - return scrollEnabled; - }; - - - //************************************************************************** - //** getRowCount - //************************************************************************** - /** Returns the total number of rows in the table. - */ - this.getRowCount = function(){ - return body.getRows().length-1; //skip phantom row! - }; - - - //************************************************************************** - //** forEachRow - //************************************************************************** - /** Used to traverse all the rows in the table and extract contents of each - * cell. Example: - - table.forEachRow(function (row, content) { - console.log(content); - }); -- * - * Optional: return true in the callback function if you wish to stop - * processing rows. - */ - this.forEachRow = function(callback){ - if (callback==null) return; - - var childNodes = body.getRows(); - for (var i=1; i=numColumns) return; - var childNodes = body.getRows(); - //if (readerRows[0].childNodes[idx].style.display!="none") return; - var rows = nodeListToArray(headerRows); - rows = rows.concat(nodeListToArray(childNodes)); - for (var i=0; i =numColumns) return; - var childNodes = body.getRows(); - if (childNodes[0].childNodes[idx].style.display=="none") return; - var rows = nodeListToArray(headerRows); - rows = rows.concat(nodeListToArray(childNodes)); - for (var i=0; i + columns: [ + {header: 'ID', hidden:true}, + {header: 'Name', width:'100%'}, + {header: 'Username', width:'150'}, + {header: 'Role', width:'100'}, + {header: 'Enabled', width:'80', align:'center'}, + {header: 'Last Active', width:'150', align:'right'} + ] +
+ iscroll: { + horizontalScrollbar: "my-iScrollHorizontalScrollbar", + verticalScrollbar: "my-iScrollVerticalScrollbar", + indicator: "my-iScrollIndicator", + columnWidth: "15px" + } ++ */ + iscroll: null + } + }; + + + //************************************************************************** + //** Constructor + //************************************************************************** + /** Creates a new instance of this class. */ + + var init = function(){ + + if (typeof parent === "string"){ + parent = document.getElementById(parent); + } + if (!parent) return; + + + + //Clone the config so we don't modify the original config object + var clone = {}; + merge(clone, config); + + + //Merge clone with default config + merge(clone, defaultConfig); + config = clone; + + + //Parse config + if (!config.columns || config.columns.length===0) return; + if (typeof IScroll !== 'undefined'){ + var columnWidth = config.style.iscroll ? config.style.iscroll.columnWidth : null; + if (!columnWidth) columnWidth = "15px"; + + if (columnWidth<=0 || columnWidth==="0px" || columnWidth==="0%"){ + //Allow users to not have a spacer for iScroll + } + else{ + config.columns.push({header: '', width: columnWidth}); + } + } + + + //Create main table + var table, tr, td; + table = createTable(parent); + table.className = "javaxt-table"; + setStyle(table, "table"); + me.el = table; + addShowHide(me); + + addMask(parent); + + + //Create header + tr = table.addRow(); + tr.setAttribute("desc", "Header Row"); + setStyle(tr, "headerRow"); + td = tr.addColumn(); + td.style.width = "100%"; + td.style.height = "inherit"; + header = createTable(td); + if (config.hideHeader===true){ + tr.style.visibility = 'hidden'; + tr.style.display = 'none'; + } + + + + //Create body + tr = table.addRow(); + tr.setAttribute("desc", "Body Row"); + td = tr.addColumn({ + width: "100%", + height: "100%" + }); + + + bodyDiv = createElement('div', td, { + width: "100%", + height: "100%", + position: "relative" + }); + bodyDiv.setAttribute("desc", "body-div"); + bodyDiv.tabIndex = -1; //allows the div to have focus + bodyDiv.onmouseover = function(){ + if (config.focusOnMouseover===true){ + var x = window.scrollX, y = window.scrollY; + this.focus(); + window.scrollTo(x, y); + } + }; + bodyDiv.addEventListener("keydown", function(e){ + if (e.keyCode===16){ + shiftIsPressed = true; + } + + if (e.keyCode===17){ + cntrlIsPressed = true; + } + + if (e.keyCode===18){ + altIsPressed = true; + } + + + //Prevent window from scrolling + if (e.keyCode===38 || e.keyCode===40){ + e.preventDefault(); + e.stopPropagation(); + } + + }); + bodyDiv.addEventListener("keyup", function(e){ + if (e.keyCode===16){ + shiftIsPressed = false; + } + + if (e.keyCode===17){ + cntrlIsPressed = false; + } + + if (e.keyCode===18){ + altIsPressed = false; + } + + if (e.keyCode===38 || e.keyCode===40){ + + var lastSelectedRow, lastRow; + me.forEachRow(function (row) { + if (row.selected){ + lastSelectedRow = row; + } + lastRow = row; + }); + + + if (lastSelectedRow){ + var row; + if (e.keyCode===40){ //down arrow + row = lastSelectedRow.nextSibling; + } + else{ //up arrow + row = lastSelectedRow.previousSibling; + } + + if (row){ + me.scrollTo(row); + row.click(); + } + } + + } + + me.onKeyEvent(e.keyCode, { + shift: shiftIsPressed, + ctrl: cntrlIsPressed, + alt: altIsPressed + }); + }); + + + + bodyDiv = createElement('div', bodyDiv, { + width: "100%", + height: "100%", + position: "absolute", + overflow: "scroll", + overflowX: "hidden" + }); + body = createTable(bodyDiv); + body.style.height = ''; + + + + //Populate header + tr = createPhantomRow(header, 1); + var spacerUR = createElement('div', tr.addColumn()); + + + tr = header.addRow(); + for (var i=0; i
+ table.addRow(["Bob","12/30","$5.25"]); ++ */ + this.addRow = function(){ + + var data = arguments; + + + //Check if the first argument is an array. If so, use it. + //Otherwise, we'll use all the arguments as data. + if (isArray(data[0])) data = data[0]; + + + //Create row + var row = body.addRow(); + row.selected = false; + setStyle(row, "row"); + + + //Add custom functions to the row + row.get = getRowContent; + row.set = setRowContent; + row.onclick = selectRows; + row.oncontextmenu = function(e){ + if (this.selected) this.selected = false; + selectRows.apply(this, [e]); + }; + + + //Create template as needed. The template is a collection of cells that + //are cloned whenever a new row is added. This approach results in faster + //row rendering. + if (!template){ + template = []; + for (var i=0; i
+ table.onSelectionChange = function(rows){ + for (var i=0; i+ @param rows An array of rows that have had thier selection changed + */ + this.onSelectionChange = function(rows){}; + + + + //************************************************************************** + //** onRowClick + //************************************************************************** + /** Called whenever a row in the table is clicked. Use the onSelectionChange + * event listener to determine whether selection has changed. + */ + this.onRowClick = function(row, e){}; + + + //************************************************************************** + //** onHeaderClick + //************************************************************************** + /** Called whenever a header cell is clicked. + */ + this.onHeaderClick = function(idx, colConfig, cell, event){}; + + + //************************************************************************** + //** onKeyEvent + //************************************************************************** + /** Called whenever a keyboard event is initiated from the table. + */ + this.onKeyEvent = function(keyCode, modifiers){}; + + + //************************************************************************** + //** focus + //************************************************************************** + /** Used to set browser focus on the table. + */ + this.focus = function(){ + var x = window.scrollX, y = window.scrollY; + bodyDiv.parentNode.focus(); + window.scrollTo(x, y); + }; + + + //************************************************************************** + //** clear + //************************************************************************** + /** Removes all the rows from the table + */ + this.clear = function(){ + if (!body) return; + me.deselectAll(); + var childNodes = body.getRows(); + while (childNodes.length>1){ + body.removeRow(childNodes[1]); + childNodes = body.getRows(); + } + me.update(); + }; + + + //************************************************************************** + //** update + //************************************************************************** + /** Used to refresh the scroll bars. This method is called internally + * whenever rows are added or removed from the table. + */ + this.update = function(){ + if (me.iScroll) me.iScroll.refresh(); + me.onOverflow(me.hasOverflow()); + }; + + + //************************************************************************** + //** hasOverflow + //************************************************************************** + /** Returns true if the table is overflowing. + */ + this.hasOverflow = function(){ + return (bodyDiv.offsetHeight < bodyDiv.scrollHeight || + bodyDiv.offsetWidth < bodyDiv.scrollWidth); + }; + + + //************************************************************************** + //** onOverflow + //************************************************************************** + /** Called whenever the table overflow status changes. + */ + this.onOverflow = function(hasOverflow){}; + + + //************************************************************************** + //** onScroll + //************************************************************************** + /** Called whenever the table is scrolled. Implementations of this method + * can be used, for example, to load records when a client scrolls to the + * bottom of the page. + */ + this.onScroll = function(y, maxY, h){}; + + + //************************************************************************** + //** scrollTo + //************************************************************************** + /** Used to scroll to a specific x/y location when the table has an + * overflow. + * @param x Accepts an x position (integer) or a row in the table + * @param y Accepts a y position. Ignored if x is a row. + */ + this.scrollTo = function(x, y){ + + var bodyRect = javaxt.dhtml.utils.getRect(bodyDiv); + + + //If x is a row, compute the y offset + if (isElement(x)){ + + var rowRect = javaxt.dhtml.utils.getRect(x); + var padding = rowRect.height/2; + var padRect = { + left: bodyRect.left, + right: bodyRect.right, + top: bodyRect.top+padding, + bottom: bodyRect.bottom-padding + }; + + + if (!javaxt.dhtml.utils.intersects(padRect, rowRect)){ + + var scrollInfo = me.getScrollInfo(); + var ry = rowRect.top + scrollInfo.y; + + if (ry>bodyRect.bottom){ + + //console.log("scroll down!"); + y = ry+rowRect.height-bodyRect.bottom; + + } + else if (ry+rowRect.height>bodyRect.top){ + + //console.log("scroll up!"); + y = ry-bodyRect.top; + + } + else{ + //console.log("scroll?"); + } + } + } + + + if (!isNumber(y)) return; + + + //Update the scroll position + if (me.iScroll){ + me.iScroll.scrollTo(0, -y); + } + else{ + bodyDiv.scrollTop = y; + } + + + //Fire the onScroll event + var maxY = bodyDiv.scrollHeight - bodyDiv.clientHeight; + me.onScroll(y, maxY, bodyRect.height); + }; + + + //************************************************************************** + //** getScrollInfo + //************************************************************************** + /** Returns scroll position and dimenstions for the visible area. + */ + this.getScrollInfo = function(){ + return { + x: me.iScroll ? -me.iScroll.x : bodyDiv.scrollLeft, + y: me.iScroll ? -me.iScroll.y : bodyDiv.scrollTop, + w: bodyDiv.offsetWidth, + h: bodyDiv.offsetHeight, + maxY: bodyDiv.scrollHeight - bodyDiv.clientHeight, + enabled: scrollEnabled + }; + }; + + + //************************************************************************** + //** enableScroll + //************************************************************************** + /** Used to enable scrolling. + */ + this.enableScroll = function(){ + scrollEnabled = true; + }; + + + //************************************************************************** + //** disableScroll + //************************************************************************** + /** Used to disable scrolling. + */ + this.disableScroll = function(){ + scrollEnabled = false; + }; + + + //************************************************************************** + //** isScrollEnabled + //************************************************************************** + /** Returns true if scrolling is enabled. + */ + this.isScrollEnabled = function(){ + return scrollEnabled; + }; + + + //************************************************************************** + //** getRowCount + //************************************************************************** + /** Returns the total number of rows in the table. + */ + this.getRowCount = function(){ + return body.getRows().length-1; //skip phantom row! + }; + + + //************************************************************************** + //** forEachRow + //************************************************************************** + /** Used to traverse all the rows in the table and extract contents of each + * cell. Example: + + table.forEachRow(function (row, content) { + console.log(content); + }); ++ * + * Note that you can return true in the callback function if you wish to + * stop processing rows. Example: ++ grid.forEachRow(function(row, content){ + //Do something with the row + + //Stop iterating once some contition is met + if (1>0) return true; + }); ++ */ + this.forEachRow = function(callback){ + if (callback==null) return; + + var childNodes = body.getRows(); + for (var i=1; i=numColumns) return; + var childNodes = body.getRows(); + //if (readerRows[0].childNodes[idx].style.display!="none") return; + var rows = nodeListToArray(headerRows); + rows = rows.concat(nodeListToArray(childNodes)); + for (var i=0; i =numColumns) return; + var childNodes = body.getRows(); + if (childNodes[0].childNodes[idx].style.display=="none") return; + var rows = nodeListToArray(headerRows); + rows = rows.concat(nodeListToArray(childNodes)); + for (var i=0; i + * zIndex: Number representing the highest z-index + *elements: An array of DOM elements at the highest z-index + *contains: Function that can be used to test whether a DOM object is + * at the highest z-index + * + * */ getHighestElements: function(obj){ var arr = []; diff --git a/themes/dark.css b/themes/dark.css index d12ca2b..778f432 100644 --- a/themes/dark.css +++ b/themes/dark.css @@ -1,978 +1,982 @@ -/****************************************************************************** -* Dark Theme Stylesheet -******************************************************************************* -* -* Common style definitions for JavaXT components and applications. This -* stylesheet renders components in a dark-gray theme with dark-blue accents. -* -******************************************************************************/ - -html, body { - height:100%; - margin:0; -} - -body { - background: #272a31; /*Gray*/ - color: #bfc0c3; -} - -body, textarea, input, select, td, th { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Text', - helvetica,arial,verdana,sans-serif; - font-size:13px; -} - -input, select, textarea { /* Allows overriding native style of form elements on iPad */ - -webkit-appearance: none; - -webkit-border-radius:0; - border-radius: 0; -} - -*:focus, select:focus, textarea:focus, input:focus{ - outline:0; -} - -.middle { - position: relative; - top: 50%; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - transform: translateY(-50%); -} - -.center { - margin: 0 auto; -} - - -.noselect, .javaxt-noselect { - -webkit-user-select: none; - -moz-user-select: none; - -o-user-select: none; - -ms-user-select: none; - -khtml-user-select: none; - user-select: none; -} - - -/**************************************************************************/ -/** Triangles -/**************************************************************************/ -/** Used in menus and grids */ - -.triangleDown, .descendingSortIcon { - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid #272727; -} - -.triangleUp, .ascendingSortIcon { - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid #272727; -} - -.triangleLeft { - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: 5px solid #272727; -} - -.triangleRight { - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid #272727; -} - - -/**************************************************************************/ -/** Panel -/**************************************************************************/ -/** The following classes are used to define the style for a panel. Panels - * consist of a header, toolbar, body, and footer. - */ -.panel-toolbar { - height: 36px; - background-color: #33363f; -} - - -/**************************************************************************/ -/** Toolbar Items -/**************************************************************************/ -/** The following classes are used to define the style for items rendered - * in a panel toolbar. - */ - -.toolbar-button, .toolbar-button-hover, .toolbar-button-selected { - width: 72px; - height: 26px; - cursor: pointer; - padding: 0px 7px; - margin: 0 0 0 5px; - - background-color: #353a46; - border: 1px solid #4c5258; - border-radius: 3px; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); - - color: #8e8f92; -} - -.toolbar-button-label { - white-space: nowrap; - color: inherit; -} - -.toolbar-button-hover { - color: #d2d2d2; - background-color: #335177; - border-color: #2e588d; -} - -.toolbar-button-selected { - color: #d2d2d2; - background-color: #335177; - border-color: #2e588d; -} - -/* Padding for button icons */ -.toolbar-button-icon { - margin: 0 6px 0 0px; -} - -.toolbar-spacer { - display: inline-block; - position: relative; - width: 0px; - height: 25px; - margin: 0 2px 1px 8px; - border-left: 1px solid #4c5258; - border-right: 1px solid #232323; -} - - -/**************************************************************************/ -/** Form Inputs -/**************************************************************************/ -/** The following classes are used to define the style for form inputs - * defined in the javaxt.dhtml.Form control. - */ - -.form-input { - - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - - - color: #97989c; /*#7e7f84;*/ - display: inline-block; - height: 28px; - line-height: 28px; - padding: 2px 4px; - vertical-align: middle; - - - transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s; - -webkit-transition: all 0.20s ease-in-out; - -moz-transition: all 0.20s ease-in-out; - -ms-transition: all 0.20s ease-in-out; - -o-transition: all 0.20s ease-in-out; - - - background-color: #353a46; - border: 1px solid #4c5258; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; - - box-sizing: border-box; -} - - -.form-input:focus { - border-color: rgba(82, 168, 236, 0.8); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); - outline: 0 none; -} - -.form-label { - color: #bfc0c3; - white-space: nowrap; - cursor: default; - vertical-align: top; - padding: 5px 10px 0 0; -} - - -/**************************************************************************/ -/** Form Radio -/**************************************************************************/ -/** The following classes are used to define the style for radio inputs - */ -.form-radio { - -moz-appearance: none; - -webkit-appearance: none; - padding: 0px; - margin: 4px 5px 4px 1px; - width: 16px; - height: 16px; - border: 1px solid #6a7179; - border-radius: 100%; - background: #353a46; -} - -.form-radio:checked:before { - display: block; - height: 8px; - width: 8px; - position: relative; - left: 3px; - top: 3px; - background: #2a79bf; - border-radius: 100%; - content: ''; -} - -.form-radio:focus { - border-color: rgba(82, 168, 236, 0.8); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); - outline: 0 none; -} - -/**************************************************************************/ -/** Form Checkbox -/**************************************************************************/ -/** The following classes are used to define the style for checkbox inputs - */ -.form-checkbox { - -moz-appearance: none; - -webkit-appearance: none; - padding: 0px; - margin: 4px 5px 4px 1px; - width: 18px; - height: 18px; - border: 1px solid #4c5258; - background: #353a46; -} - -.form-checkbox:checked:before { - content: ''; - display: block; - width: 3px; - height: 9px; - border: solid #2a79bf; - border-width: 0 2px 2px 0; - transform: rotate(45deg); - margin: 2px 0px 0px 6px; -} - -.form-checkbox:focus { - border-color: rgba(82, 168, 236, 0.8); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); - outline: 0 none; -} - - -/**************************************************************************/ -/** Form Buttons -/**************************************************************************/ -/** The following classes are used to define the style for buttons in a - * form (e.g. "Submit", "OK", "Cancel", etc). - */ -.form-button { - border-radius: 3px; - color: #97989c; - display: inline-block; - width: 80px; - height: 26px; - /*line-height: 24px;*/ - vertical-align: middle; - background-color: #353a46; - border: 1px solid #4c5258; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); - /*text-shadow: 1px 1px 0px rgb(255, 255, 255);*/ - cursor: pointer; - margin-left: 10px; -} - -.form-button:hover { - color: #d2d2d2; - background-color: #335177; - border-color: #2e588d; -} - -.form-button:active { - box-shadow: none; -} -.form-button:focus { - outline:0; -} - -.form-button:disabled, -.form-button[disabled]{ - opacity: 0.4; -} - -.form-button:disabled:hover, -.form-button[disabled]:hover { - color: #97989c; - background-color: #353a46; - border: 1px solid #4c5258; -} - - -/**************************************************************************/ -/** Form Input With Button -/**************************************************************************/ -/** The following classes are used define form inputs with buttons (e.g. - * DatePicker, ComboBox, etc.) - */ -.form-input-with-button { /* used in conjunction with form-input */ - border-radius: 5px 0 0 5px; - -moz-border-radius: 5px 0 0 5px; - -webkit-border-radius: 5px 0 0 5px; - border-right: 0 none; -} - -.form-input-button { /* used in conjunction with form-button */ - border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - -webkit-border-radius: 0 3px 3px 0; - box-shadow: none; - width: 28px; - height: 28px; - padding: 0; - margin: 0; - background: #335177; /* Dark blue */ - border: 1px solid #525252; /* Light gray */ - border-left: 0; - - - /*Add 5px inner glow to mask neighbors in the sprite*/ - -webkit-box-shadow: inset -5px 5px 5px 0px #335177, inset 5px -5px 5px 0px #335177; - -moz-box-shadow: inset -5px 5px 5px 0px #335177, inset 5px -5px 5px 0px #335177; - box-shadow: inset -5px 5px 5px 0px #335177, inset 5px -5px 5px 0px #335177; -} - -/* Preserve 5px inner glow */ -.form-input-button:hover, .form-input-button:focus { - background-color: #2e588d; - box-shadow: inset -5px 5px 5px 0px #2e588d, inset 5px -5px 5px 0px #2e588d /*5px inner mask*/ - /*,0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); /*blue outer glow*/ -} - - - -/**************************************************************************/ -/** Form Menu -/**************************************************************************/ -/** The following classes are used to define the style for menus in a - * javaxt.dhtml.ComboBox. - */ -.form-input-menu { - /*border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - -webkit-border-radius: 0 0 4px 4px;*/ - background-color: #3e4453; - /*border: 1px solid #4d5361;*/ - /*box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);*/ - box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.3); - margin-top: -1px; - overflow: hidden; -} - -.form-input-menu-item { - color: #b3b3b3; - height: 28px; - line-height: 28px; - padding: 0px 6px; - vertical-align: middle; - white-space: nowrap; - cursor: default; -} - -.form-input-menu-item:hover { - background-color: #415175; - color: #d2d2d2; -} -.form-input-menu-item:focus { - background-color: #415175; -} -.form-input-menu-item:focused { - background-color: #415175; -} - -.form-input-menu-item-new { /* For a "new" menu option in a combobox menu. Used in conjuction */ - border-top: 1px solid #4d5361; -} - - -/**************************************************************************/ -/** Form Error -/**************************************************************************/ - -.form-input-error { - background: #4e3434; - border-color: #8c0000; -} - - -/**************************************************************************/ -/** Form placeholder -/**************************************************************************/ - -.form-input::placeholder { - color: #757575; - font-style: italic; -} - - -/**************************************************************************/ -/** Form Group -/**************************************************************************/ -/** The following classes are used to define the style for group boxes in - * forms. - */ - -.form-groupbox { - border: 1px solid #626a71; - border-radius: 3px; - padding: 16px 8px 12px 13px; -} - -.form-grouplabel { - margin: 8px 0 0 7px; - background-color: #3e4453; - padding: 0 5px 0 5px; - color: #eaeaea; -} - - -/**************************************************************************/ -/** Callout -/**************************************************************************/ - -.callout-panel, .callout-arrow { - border: 1px solid #383b41; - background: #3e4453; /*same as window*/ -} -.callout-panel { - border-radius: 4px; - box-shadow: 0 12px 14px 0 rgba(0, 0, 0, 0.2), 0 13px 20px 0 rgba(0, 0, 0, 0.2) -} -.callout-arrow { - width: 10px; - height: 10px; - padding: 10px; -} - - -/**************************************************************************/ -/** Error Popup -/**************************************************************************/ -/** The following classes are used to define the style for pop-up callouts - * generated using the javaxt.dhtml.Callout class. - */ - -.error-callout-panel, .error-callout-arrow { - border: 1px solid #8c0000; - background: #921d1d; - color: #fff; - cursor: pointer; -} - -.error-callout-panel { - border-radius: 3px; - padding: 5px !important; - box-shadow: 0 12px 14px 0 rgba(0, 0, 0, 0.2), 0 13px 20px 0 rgba(0, 0, 0, 0.2); -} - -.error-callout-arrow { - width: 7px; - height: 7px; - padding: 12px; -} - - -/**************************************************************************/ -/** Window -/**************************************************************************/ - -.window { - background: #3e4453; /*#36373e*/ - border-radius: 5px; - display: inline-block; - box-shadow: 0 12px 14px 0 rgba(0, 0, 0, 0.2), 0 13px 20px 0 rgba(0, 0, 0, 0.2); - min-width: 150px; - min-height: 75px; -} - -.window-header { - background: #335177; - height: 36px; - cursor: default; - - position: relative; - border-radius: 4px 4px 0px 0px; - border: 1px solid #2e588d; - box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px; - cursor: default; - overflow: hidden; -} - -.window-title { - color: #bdbdbd; - text-align: center; - white-space: nowrap; - text-transform: uppercase; - line-height: 36px; /*Should match window-header height*/ - - position: absolute; - text-align: left; - cursor: default; - padding-left: 9px; -} - -.window-header-button-bar { - position: absolute; - right: 0; - padding: 6px 7px 0 0; -} - -.window-header-button { - font-size: 18px; - border: 0; - color: #bdbdbd; - cursor: pointer; - padding: 5px; - -} - -.window-header-button:hover { - background-color: #3e70af; - transition: 0.1s; - border-radius: 3px; - color: #ccc; -} - -.window-body { - padding: 7px; - vertical-align: top; -} - -.alert-header { /* used in conjunction with window-header */ - background-color: #6f6235; - border: 1px solid #6f6235; - border-bottom: 1px solid #a28317; -} - -.alert-header .window-header-button:hover { - background-color: #a28317; -} - -.alert { /* used in conjunction with window */ - background-color: #383727; -} - -.alert-body, .confirm-body { - padding: 10px 10px 15px 15px; - line-height: 18px; -} - - -/**************************************************************************/ -/** Tab Panel -/**************************************************************************/ -/** The following classes are used to define the style for the tab panel. - */ - -.tab-panel { - padding: 0 5px; -} - -.tab-bar { - background-color: #335177; /* same as windows header */ - height: 30px; - color: #fff; - border: 1px solid #2e588d; - border-width: 0 1px; - color: #bdbdbd; -} - -.tab-active, .tab-inactive { - padding: 0 12px; - line-height: 30px; - cursor: default; -} - -.tab-active { - background-color: #256d95; - color: #fff; -} - -.tab-inactive { - background: none; -} - -.tab-inactive:hover { - background-color: #3387b7; - color: #fff; -} - -.tab-body { - padding: 7px; - vertical-align: top; - background-color: #3e4453; - border: 1px solid #4f5669; -} - - - -/** Special case when tab is the first component inside a window **/ - -.window-body table:first-child .tab-bar { - background-color: #4c5468; -} - -.window-body table:first-child .tab-active { - border-top: 2px solid #4a84b7; - margin-top: -2px; -} - -.window-body table:first-child .tab-body { - border: 0 none; - border-radius: 0 0 8px 8px; -} - - - -/**************************************************************************/ -/** Checkbox -/**************************************************************************/ -/** The following classes are used to define the style for checkboxes - * generated using the javaxt.dhtml.Checkbox class. - */ -.checkbox-box { - width: 18px; - height: 18px; - border: 1px solid #4c5258; - border-radius: 3px; - background-color: #353a46; - cursor: pointer; - margin: 0px; - color: #2b2b2b; -} - -.checkbox-label { - color: #bfc0c3; - white-space: nowrap; - cursor: default; - vertical-align: top; - padding: 0 0 0 5px; -} - -.checkbox-check { - content: ""; - display: block; - width: 4px; - height: 9px; - border: solid #ffffff; - border-width: 0 2px 2px 0; - transform: rotate(45deg); - margin: 2px 0 0 6px; -} - -.checkbox-select { - background-color: #345994; - border: 1px solid #33363f; - color: #FFFFFF; -} - -.checkbox-disable { - background-color: #353a46; - border: 1px solid #ffffff; - border-radius: 3px; - cursor: pointer; - opacity: 0.5; -} - -.checkbox-hover { - /*background-color: #ededed;*/ - border-color: rgba(82, 168, 236, 0.8); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); - outline: 0 none; -} - - -/**************************************************************************/ -/** Table -/**************************************************************************/ -/** Default style for grid controls - */ -.table-header { - border-bottom: 1px solid #383b41; - /*background: #3e414a; /*#33363f; #353a46 */ - background: #3e414a; - /* - background-image: none; - background-image: linear-gradient(to bottom, #f9f9f9, #e4e5e7); - */ - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 3px 10px 0 rgba(0, 0, 0, 0.19); -} - - -.table-row, .table-row-selected { - border-bottom: 1px solid #383b41; - background-color: #23252b; - color: #97989c; -} - -/* -.table-row:nth-child(odd) {background: #272a31} -*/ - -.table-row:hover{ - background-color:#212939; -} - -.table-row-selected{ - /*border-bottom-style:dotted;*/ - /*border-color:#a3bae9;*/ - background-color:#25334f; - color: #e2e3e7; - transition: 0.2s; -} - -.table-col, .table-header-col { - - white-space: nowrap; - - height: 35px; - line-height: 35px; - - - border-left: 1px solid #383b41; - border-right: 1px solid #383b41; - padding: 0 5px; - - - /* - text-overflow: ellipsis; - -o-text-overflow: ellipsis; - -webkit-text-overflow: ellipsis; - */ -} - -.table-header-col { - cursor: pointer; - color: #bfc0c3; -} - -.table-header-col:hover{ - color: #d2d2d2; - background-color: #335177; - border-color: #2e588d; - transition: 0.2s; -} - -.table-col { - border-left: 0; - border-right: 0; - color: inherit; -} - -.table-resizeHandle { - width: 5px; - height: 100%; - cursor: col-resize; - margin: 0 -7px 0 0px; -} - - -/**************************************************************************/ -/** Tree -/**************************************************************************/ - -.tree-node { - color: #97989c; - cursor: pointer; -} - -.tree-node:hover { - background-color:#364156 !important; -} - - -/**************************************************************************/ -/** Switch -/**************************************************************************/ - -.switch-groove{ - background-color: #727272; - width: 40px; - height: 24px; - border-radius: 12px; - position: relative; -} -.switch-handle { - width: 20px; - height: 20px; - background-color: #e0e0e2; - border-radius: 10px; - position: absolute; - margin: 2px; - box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.2); -} -.switch-groove-active { - background-color: #379748; - width: 40px; - height: 24px; - border-radius: 12px; - position: relative; -} -.switch-handle-active { - width: 20px; - height: 20px; - background-color: #e0e0e2; - border-radius: 10px; - position: absolute; - margin: 2px; - box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.2); -} - - -/**************************************************************************/ -/** Slider -/**************************************************************************/ - -.slider-groove { - display: inline-block; - -webkit-box-sizing: border-box; - -moz-box-sizing: padding-box; - box-sizing: padding-box; - height: 11px; - padding: 1px; - border: 1px solid #383d42; - border-radius: 3px; - background-image: - -webkit-gradient(linear, left top ,left bottom, - from(#345994), - color-stop(.5, #345994), - to(#345994)), - -webkit-gradient(linear, left top ,left bottom, - from(#282b32), - color-stop(.5, #282b32), - to(#282b32)); - background-image: - -moz-linear-gradient(top, - #345994, - #345994 50%, - #345994), - -moz-linear-gradient(top, - #282b32, - #282b32 50%, - #282b32); - background-repeat: no-repeat, repeat-x; -} - -.slider-handle { - position:relative; - height:20px; - width:20px; - left: 0px; - top: -8px; - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - border-radius: 10px; - background-image: - -webkit-gradient(linear, left top, left bottom, - from(#aaa), - color-stop(.5, #ddd), - to(#ccc)); - background-image: - -moz-linear-gradient(top, - #aaa, - #ddd 50%, - #ccc); - cursor: pointer; - -webkit-tap-highlight-color: transparent; -} - - -.slider-handle:hover, .slider-handle.hover { - background-image: - -webkit-gradient(linear, left top, left bottom, - from(#6297f2), - color-stop(.5, #0251ae), - to(#6297f2)); - background-image: - -moz-linear-gradient(top, - #6297f2, - #0251ae 50%, - #6297f2); -} - - - -/**************************************************************************/ -/** iScroll -/**************************************************************************/ -/** Custom style for iScroll */ - -.iScrollHorizontalScrollbar, -.iScrollVerticalScrollbar { - position: absolute; - z-index: 1; - overflow: hidden; -} - -.iScrollHorizontalScrollbar { - height: 8px; - left: 2px; - right: 2px; - bottom: 4px; -} - -.iScrollVerticalScrollbar { - width: 8px; - bottom: 2px; - top: 2px; - right: 4px; -} - -.iScrollHorizontalScrollbar.iScrollBothScrollbars { - right: 18px; -} - -.iScrollVerticalScrollbar.iScrollBothScrollbars { - bottom: 18px; -} - -.iScrollIndicator { - position: absolute; - background: #3e4453; - border: 0 none; - border-radius: 4px; -} - -.iScrollHorizontalScrollbar .iScrollIndicator { - height: 100%; -} - -.iScrollVerticalScrollbar .iScrollIndicator { - width: 100%; -} - - -.form-input-menu .iScrollIndicator { - background: #4f5565; +/****************************************************************************** +* Dark Theme Stylesheet +******************************************************************************* +* +* Common style definitions for JavaXT components and applications. This +* stylesheet renders components in a dark-gray theme with dark-blue accents. +* +******************************************************************************/ + +html, body { + height:100%; + margin:0; +} + +body { + background: #272a31; /*Gray*/ + color: #bfc0c3; +} + +body, textarea, input, select, td, th { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Text', + helvetica,arial,verdana,sans-serif; + font-size:13px; +} + +input, select, textarea { /* Allows overriding native style of form elements on iPad */ + -webkit-appearance: none; + -webkit-border-radius:0; + border-radius: 0; +} + +*:focus, select:focus, textarea:focus, input:focus{ + outline:0; +} + +.middle { + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} + +.center { + margin: 0 auto; +} + + +.noselect, .javaxt-noselect { + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + -ms-user-select: none; + -khtml-user-select: none; + user-select: none; +} + + +/**************************************************************************/ +/** Triangles +/**************************************************************************/ +/** Used in menus and grids */ + +.triangleDown, .descendingSortIcon { + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #272727; +} + +.triangleUp, .ascendingSortIcon { + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #272727; +} + +.triangleLeft { + width: 0; + height: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #272727; +} + +.triangleRight { + width: 0; + height: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #272727; +} + + +/**************************************************************************/ +/** Panel +/**************************************************************************/ +/** The following classes are used to define the style for a panel. Panels + * consist of a header, toolbar, body, and footer. + */ +.panel-toolbar { + height: 36px; + background-color: #33363f; + background-image: none; +} + + +/**************************************************************************/ +/** Toolbar Items +/**************************************************************************/ +/** The following classes are used to define the style for items rendered + * in a panel toolbar. + */ + +.toolbar-button, .toolbar-button-hover, .toolbar-button-selected { + width: 72px; + height: 26px; + cursor: pointer; + padding: 0px 7px; + margin: 0 0 0 5px; + + background-color: #353a46; + border: 1px solid #4c5258; + border-radius: 3px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); + + color: #8e8f92; +} + +.toolbar-button-label { + white-space: nowrap; + color: inherit; +} + +.toolbar-button-hover { + color: #d2d2d2; + background-color: #335177; + border-color: #2e588d; +} + +.toolbar-button-selected { + color: #d2d2d2; + background-color: #335177; + border-color: #2e588d; +} + +/* Padding for button icons */ +.toolbar-button-icon { + margin: 0 6px 0 0px; +} + +.toolbar-spacer { + display: inline-block; + position: relative; + width: 0px; + height: 25px; + margin: 0 2px 1px 8px; + border-left: 1px solid #4c5258; + border-right: 1px solid #232323; +} + + +/**************************************************************************/ +/** Form Inputs +/**************************************************************************/ +/** The following classes are used to define the style for form inputs + * defined in the javaxt.dhtml.Form control. + */ + +.form-input { + + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + + + color: #97989c; /*#7e7f84;*/ + display: inline-block; + height: 28px; + line-height: 28px; + padding: 2px 4px; + vertical-align: middle; + + + transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s; + -webkit-transition: all 0.20s ease-in-out; + -moz-transition: all 0.20s ease-in-out; + -ms-transition: all 0.20s ease-in-out; + -o-transition: all 0.20s ease-in-out; + + + background-color: #353a46; + border: 1px solid #4c5258; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; + + box-sizing: border-box; +} + + +.form-input:focus { + border-color: rgba(82, 168, 236, 0.8); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); + outline: 0 none; +} + +.form-label { + color: #bfc0c3; + white-space: nowrap; + cursor: default; + vertical-align: top; + padding: 5px 10px 0 0; +} + + +/**************************************************************************/ +/** Form Radio +/**************************************************************************/ +/** The following classes are used to define the style for radio inputs + */ +.form-radio { + -moz-appearance: none; + -webkit-appearance: none; + padding: 0px; + margin: 4px 5px 4px 1px; + width: 16px; + height: 16px; + border: 1px solid #6a7179; + border-radius: 100%; + background: #353a46; +} + +.form-radio:checked:before { + display: block; + height: 8px; + width: 8px; + position: relative; + left: 3px; + top: 3px; + background: #2a79bf; + border-radius: 100%; + content: ''; +} + +.form-radio:focus { + border-color: rgba(82, 168, 236, 0.8); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); + outline: 0 none; +} + +/**************************************************************************/ +/** Form Checkbox +/**************************************************************************/ +/** The following classes are used to define the style for checkbox inputs + */ +.form-checkbox { + -moz-appearance: none; + -webkit-appearance: none; + padding: 0px; + margin: 4px 5px 4px 1px; + width: 18px; + height: 18px; + border: 1px solid #4c5258; + background: #353a46; +} + +.form-checkbox:checked:before { + content: ''; + display: block; + width: 3px; + height: 9px; + border: solid #2a79bf; + border-width: 0 2px 2px 0; + transform: rotate(45deg); + margin: 2px 0px 0px 6px; +} + +.form-checkbox:focus { + border-color: rgba(82, 168, 236, 0.8); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); + outline: 0 none; +} + + +/**************************************************************************/ +/** Form Buttons +/**************************************************************************/ +/** The following classes are used to define the style for buttons in a + * form (e.g. "Submit", "OK", "Cancel", etc). + */ +.form-button { + border-radius: 3px; + color: #97989c; + display: inline-block; + width: 80px; + height: 26px; + /*line-height: 24px;*/ + vertical-align: middle; + background-color: #353a46; + border: 1px solid #4c5258; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); + text-shadow: none; + cursor: pointer; + margin-left: 10px; +} + +.form-button:hover { + color: #d2d2d2; + background-color: #335177; + border-color: #2e588d; +} + +.form-button:active { + box-shadow: none; +} +.form-button:focus { + outline:0; +} + +.form-button:disabled, +.form-button[disabled]{ + opacity: 0.4; +} + +.form-button:disabled:hover, +.form-button[disabled]:hover { + color: #97989c; + background-color: #353a46; + border: 1px solid #4c5258; +} + + +/**************************************************************************/ +/** Form Input With Button +/**************************************************************************/ +/** The following classes are used define form inputs with buttons (e.g. + * DatePicker, ComboBox, etc.) + */ +.form-input-with-button { /* used in conjunction with form-input */ + border-radius: 5px 0 0 5px; + -moz-border-radius: 5px 0 0 5px; + -webkit-border-radius: 5px 0 0 5px; + border-right: 0 none; +} + +.form-input-button { /* used in conjunction with form-button */ + border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + -webkit-border-radius: 0 3px 3px 0; + box-shadow: none; + width: 28px; + height: 28px; + padding: 0; + margin: 0; + background: #335177; /* Dark blue */ + border: 1px solid #525252; /* Light gray */ + border-left: 0; + + + /*Add 5px inner glow to mask neighbors in the sprite*/ + -webkit-box-shadow: inset -5px 5px 5px 0px #335177, inset 5px -5px 5px 0px #335177; + -moz-box-shadow: inset -5px 5px 5px 0px #335177, inset 5px -5px 5px 0px #335177; + box-shadow: inset -5px 5px 5px 0px #335177, inset 5px -5px 5px 0px #335177; +} + +/* Preserve 5px inner glow */ +.form-input-button:hover, .form-input-button:focus { + background-color: #2e588d; + box-shadow: inset -5px 5px 5px 0px #2e588d, inset 5px -5px 5px 0px #2e588d /*5px inner mask*/ + /*,0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); /*blue outer glow*/ +} + + + +/**************************************************************************/ +/** Form Menu +/**************************************************************************/ +/** The following classes are used to define the style for menus in a + * javaxt.dhtml.ComboBox. + */ +.form-input-menu { + /*border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px;*/ + background-color: #3e4453; + /*border: 1px solid #4d5361;*/ + /*box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);*/ + box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.3); + margin-top: -1px; + overflow: hidden; +} + +.form-input-menu-item { + color: #b3b3b3; + height: 28px; + line-height: 28px; + padding: 0px 6px; + vertical-align: middle; + white-space: nowrap; + cursor: default; +} + +.form-input-menu-item:hover { + background-color: #415175; + color: #d2d2d2; +} +.form-input-menu-item:focus { + background-color: #415175; +} +.form-input-menu-item:focused { + background-color: #415175; +} + +.form-input-menu-item-new { /* For a "new" menu option in a combobox menu. Used in conjuction */ + border-top: 1px solid #4d5361; +} + + +/**************************************************************************/ +/** Form Error +/**************************************************************************/ + +.form-input-error { + background: #4e3434; + border-color: #8c0000; +} + + +/**************************************************************************/ +/** Form placeholder +/**************************************************************************/ + +.form-input::placeholder { + color: #757575; + font-style: italic; +} + + +/**************************************************************************/ +/** Form Group +/**************************************************************************/ +/** The following classes are used to define the style for group boxes in + * forms. + */ + +.form-groupbox { + border: 1px solid #626a71; + border-radius: 3px; + padding: 16px 8px 12px 13px; +} + +.form-grouplabel { + margin: 8px 0 0 7px; + background-color: #3e4453; + padding: 0 5px 0 5px; + color: #eaeaea; +} + + +/**************************************************************************/ +/** Callout +/**************************************************************************/ + +.callout-panel, .callout-arrow { + border: 1px solid #383b41; + background: #3e4453; /*same as window*/ +} +.callout-panel { + border-radius: 4px; + box-shadow: 0 12px 14px 0 rgba(0, 0, 0, 0.2), 0 13px 20px 0 rgba(0, 0, 0, 0.2) +} +.callout-arrow { + width: 10px; + height: 10px; + padding: 10px; +} + + +/**************************************************************************/ +/** Error Popup +/**************************************************************************/ +/** The following classes are used to define the style for pop-up callouts + * generated using the javaxt.dhtml.Callout class. + */ + +.error-callout-panel, .error-callout-arrow { + border: 1px solid #8c0000; + background: #921d1d; + color: #fff; + cursor: pointer; +} + +.error-callout-panel { + border-radius: 3px; + padding: 5px !important; + box-shadow: 0 12px 14px 0 rgba(0, 0, 0, 0.2), 0 13px 20px 0 rgba(0, 0, 0, 0.2); +} + +.error-callout-arrow { + width: 7px; + height: 7px; + padding: 12px; +} + + +/**************************************************************************/ +/** Window +/**************************************************************************/ + +.window { + background: #3e4453; /*#36373e*/ + border-radius: 5px; + display: inline-block; + box-shadow: 0 12px 14px 0 rgba(0, 0, 0, 0.2), 0 13px 20px 0 rgba(0, 0, 0, 0.2); + min-width: 150px; + min-height: 75px; +} + +.window-header { + background: #335177; + height: 36px; + cursor: default; + + position: relative; + border-radius: 4px 4px 0px 0px; + border: 1px solid #2e588d; + box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px; + cursor: default; + overflow: hidden; +} + +.window-title { + color: #bdbdbd; + text-align: center; + white-space: nowrap; + text-transform: uppercase; + line-height: 36px; /*Should match window-header height*/ + + position: absolute; + text-align: left; + cursor: default; + padding-left: 9px; +} + +.window-header-button-bar { + position: absolute; + right: 0; + padding: 6px 7px 0 0; +} + +.window-header-button { + font-size: 18px; + border: 0; + color: #bdbdbd; + cursor: pointer; + padding: 5px; + +} + +.window-header-button:hover { + background-color: #3e70af; + transition: 0.1s; + border-radius: 3px; + color: #ccc; +} + +.window-body { + padding: 7px; + vertical-align: top; + color: inherit; +} + +.alert-header { /* used in conjunction with window-header */ + background-color: #6f6235; + border: 1px solid #6f6235; + border-bottom: 1px solid #a28317; +} + +.alert-header .window-header-button:hover { + background-color: #a28317; +} + +.alert { /* used in conjunction with window */ + background-color: #383727; +} + +.alert-body, .confirm-body { + padding: 10px 10px 15px 15px; + line-height: 18px; +} + + +/**************************************************************************/ +/** Tab Panel +/**************************************************************************/ +/** The following classes are used to define the style for the tab panel. + */ + +.tab-panel { + padding: 0 5px; +} + +.tab-bar { + background-color: #335177; /* same as windows header */ + height: 30px; + color: #fff; + border: 1px solid #2e588d; + border-width: 0 1px; + color: #bdbdbd; +} + +.tab-active, .tab-inactive { + padding: 0 12px; + line-height: 30px; + cursor: default; +} + +.tab-active { + background-color: #256d95; + color: #fff; +} + +.tab-inactive { + background: none; +} + +.tab-inactive:hover { + background-color: #3387b7; + color: #fff; +} + +.tab-body { + padding: 7px; + vertical-align: top; + background-color: #3e4453; + border: 1px solid #4f5669; +} + + + +/** Special case when tab is the first component inside a window **/ + +.window-body table:first-child .tab-bar { + background-color: #4c5468; +} + +.window-body table:first-child .tab-active { + border-top: 2px solid #4a84b7; + margin-top: -2px; +} + +.window-body table:first-child .tab-body { + border: 0 none; + border-radius: 0 0 8px 8px; +} + + + +/**************************************************************************/ +/** Checkbox +/**************************************************************************/ +/** The following classes are used to define the style for checkboxes + * generated using the javaxt.dhtml.Checkbox class. + */ +.checkbox-box { + width: 18px; + height: 18px; + border: 1px solid #4c5258; + border-radius: 3px; + background-color: #353a46; + cursor: pointer; + margin: 0px; + color: #2b2b2b; +} + +.checkbox-label { + color: #bfc0c3; + white-space: nowrap; + cursor: default; + vertical-align: top; + padding: 0 0 0 5px; +} + +.checkbox-check { + content: ""; + display: block; + width: 4px; + height: 9px; + border: solid #ffffff; + border-width: 0 2px 2px 0; + transform: rotate(45deg); + margin: 2px 0 0 6px; +} + +.checkbox-select { + background-color: #345994; + border: 1px solid #33363f; + color: #FFFFFF; +} + +.checkbox-disable { + background-color: #353a46; + border: 1px solid #ffffff; + border-radius: 3px; + cursor: pointer; + opacity: 0.5; +} + +.checkbox-hover { + /*background-color: #ededed;*/ + border-color: rgba(82, 168, 236, 0.8); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(82, 168, 236, 0.6); + outline: 0 none; +} + + +/**************************************************************************/ +/** Table +/**************************************************************************/ +/** Default style for grid controls + */ +.table-header { + border-bottom: 1px solid #383b41; + /*background: #3e414a; /*#33363f; #353a46 */ + background-color: #3e414a; + background-image: none; + /* + background-image: linear-gradient(to bottom, #f9f9f9, #e4e5e7); + */ + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 3px 10px 0 rgba(0, 0, 0, 0.19); +} + + +.table-row, .table-row-selected { + border-bottom: 1px solid #383b41; + background-color: #23252b; + color: #97989c; +} + + +.table-row:nth-child(odd) { + background-color: #23252b; /*#272a31*/ +} + + +.table-row:hover{ + background-color:#212939; +} + +.table-row-selected{ + /*border-bottom-style:dotted;*/ + /*border-color:#a3bae9;*/ + background-color:#25334f; + color: #e2e3e7; + transition: 0.2s; +} + +.table-col, .table-header-col { + + white-space: nowrap; + + height: 35px; + line-height: 35px; + + + border-left: 1px solid #383b41; + border-right: 1px solid #383b41; + padding: 0 5px; + + + /* + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -webkit-text-overflow: ellipsis; + */ +} + +.table-header-col { + cursor: pointer; + color: #bfc0c3; +} + +.table-header-col:hover{ + color: #d2d2d2; + background-color: #335177; + border-color: #2e588d; + transition: 0.2s; +} + +.table-col { + border-left: 0; + border-right: 0; + color: inherit; +} + +.table-resizeHandle { + width: 5px; + height: 100%; + cursor: col-resize; + margin: 0 -7px 0 0px; +} + + +/**************************************************************************/ +/** Tree +/**************************************************************************/ + +.tree-node { + color: #97989c; + cursor: pointer; +} + +.tree-node:hover { + background-color:#364156 !important; +} + + +/**************************************************************************/ +/** Switch +/**************************************************************************/ + +.switch-groove{ + background-color: #727272; + width: 40px; + height: 24px; + border-radius: 12px; + position: relative; +} +.switch-handle { + width: 20px; + height: 20px; + background-color: #e0e0e2; + border-radius: 10px; + position: absolute; + margin: 2px; + box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.2); +} +.switch-groove-active { + background-color: #379748; + width: 40px; + height: 24px; + border-radius: 12px; + position: relative; +} +.switch-handle-active { + width: 20px; + height: 20px; + background-color: #e0e0e2; + border-radius: 10px; + position: absolute; + margin: 2px; + box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.2); +} + + +/**************************************************************************/ +/** Slider +/**************************************************************************/ + +.slider-groove { + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: padding-box; + box-sizing: padding-box; + height: 11px; + padding: 1px; + border: 1px solid #383d42; + border-radius: 3px; + background-image: + -webkit-gradient(linear, left top ,left bottom, + from(#345994), + color-stop(.5, #345994), + to(#345994)), + -webkit-gradient(linear, left top ,left bottom, + from(#282b32), + color-stop(.5, #282b32), + to(#282b32)); + background-image: + -moz-linear-gradient(top, + #345994, + #345994 50%, + #345994), + -moz-linear-gradient(top, + #282b32, + #282b32 50%, + #282b32); + background-repeat: no-repeat, repeat-x; +} + +.slider-handle { + position:relative; + height:20px; + width:20px; + left: 0px; + top: -8px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + background-image: + -webkit-gradient(linear, left top, left bottom, + from(#aaa), + color-stop(.5, #ddd), + to(#ccc)); + background-image: + -moz-linear-gradient(top, + #aaa, + #ddd 50%, + #ccc); + cursor: pointer; + -webkit-tap-highlight-color: transparent; +} + + +.slider-handle:hover, .slider-handle.hover { + background-image: + -webkit-gradient(linear, left top, left bottom, + from(#6297f2), + color-stop(.5, #0251ae), + to(#6297f2)); + background-image: + -moz-linear-gradient(top, + #6297f2, + #0251ae 50%, + #6297f2); +} + + + +/**************************************************************************/ +/** iScroll +/**************************************************************************/ +/** Custom style for iScroll */ + +.iScrollHorizontalScrollbar, +.iScrollVerticalScrollbar { + position: absolute; + z-index: 1; + overflow: hidden; +} + +.iScrollHorizontalScrollbar { + height: 8px; + left: 2px; + right: 2px; + bottom: 4px; +} + +.iScrollVerticalScrollbar { + width: 8px; + bottom: 2px; + top: 2px; + right: 4px; +} + +.iScrollHorizontalScrollbar.iScrollBothScrollbars { + right: 18px; +} + +.iScrollVerticalScrollbar.iScrollBothScrollbars { + bottom: 18px; +} + +.iScrollIndicator { + position: absolute; + background: #3e4453; + border: 0 none; + border-radius: 4px; +} + +.iScrollHorizontalScrollbar .iScrollIndicator { + height: 100%; +} + +.iScrollVerticalScrollbar .iScrollIndicator { + width: 100%; +} + + +.form-input-menu .iScrollIndicator { + background: #4f5565; } \ No newline at end of file diff --git a/themes/default.js b/themes/default.js index 31206a0..4fc74b8 100644 --- a/themes/default.js +++ b/themes/default.js @@ -1,142 +1,145 @@ -if(!javaxt) var javaxt={}; -if(!javaxt.dhtml) javaxt.dhtml={}; -if(!javaxt.dhtml.style) javaxt.dhtml.style={}; - -//****************************************************************************** -//** Default Style -//****************************************************************************** -/** - * Common style definitions for JavaXT components. - * - ******************************************************************************/ - -javaxt.dhtml.style.default = { - - window : { - panel: "window", - header: "panel-header window-header", - title: "window-title", - button: "window-header-button", - buttonBar: "window-header-button-bar", - footerButton: "form-button noselect", - body: "window-body", - mask: "window-mask" - }, - - - callout : { - panel: "callout-panel", - arrow: "callout-arrow" - }, - - - form : { - label: "form-label noselect", - input: "form-input", - icon: { - padding: "0 8px 6px 0" - }, - button: "form-button noselect", - radio: "form-radio noselect", - checkbox: "form-checkbox", - groupbox: "form-groupbox", - grouplabel: "form-grouplabel noselect", - error: { - input: "form-input-error", - callout: { - panel: "error-callout-panel", - arrow: "error-callout-arrow" - } - } - }, - - - combobox : { - input: "form-input form-input-with-button", - button: "form-button form-input-button pulldown-button-icon", - menu: "form-input-menu", - option: "form-input-menu-item", - newOption: "form-input-menu-item form-input-menu-item-new" - }, - - - checkbox : { - panel: "checkbox-panel", - box: "checkbox-box", - label: "checkbox-label", - check: "checkbox-check", - select: "checkbox-select", - disable: "checkbox-disable", - hover: "checkbox-hover" - }, - - - button: { - button: "button", - select: "button-selected", - label: "button-label" - }, - - - toolbarButton : { - button: "toolbar-button", - select: "toolbar-button-selected", - hover: "toolbar-button-hover", - label: "toolbar-button-label" - }, - - - table: { - headerRow: "table-header", - headerColumn : "table-header-col", - row: "table-row", - column: "table-col", - selectedRow: "table-row-selected", - resizeHandle: "table-resizeHandle", - ascendingSortIcon: "table-icon-sort-asc", - descendingSortIcon: "table-icon-sort-desc", - iscroll: { - horizontalScrollbar: "iScrollHorizontalScrollbar", - verticalScrollbar: "iScrollVerticalScrollbar", - indicator: "iScrollIndicator" - } - }, - - tabPanel: { - tabBar: "tab-bar", - activeTab: "tab-active", - inactiveTab: "tab-inactive", - tabBody: "tab-body" - }, - - switch: { - groove: "switch-groove", - handle: "switch-handle", - grooveActive: "switch-groove-active", - handleActive: "switch-handle-active" - }, - - slider: { - groove: "slider-groove", - handle: "slider-handle" - }, - - datePicker: { - panel: "date-picker-panel", - header: "date-picker-header", - title: "date-picker-title", - cell: "date-picker-cell", - cellHeader: "date-picker-cell-header", - today: "date-picker-cell-today", - selectedRow: "date-picker-row-selected", - selectedCell: "date-picker-cell-selected", - next: "date-picker-next", - back: "date-picker-back" - }, - - - merge : function(settings, defaults) { - javaxt.dhtml.utils.merge(settings, defaults); - return settings; - } -}; \ No newline at end of file +if(!javaxt) var javaxt={}; +if(!javaxt.dhtml) javaxt.dhtml={}; +if(!javaxt.dhtml.style) javaxt.dhtml.style={}; + +//****************************************************************************** +//** Default Style +//****************************************************************************** +/** + * Common style definitions for JavaXT components. + * + ******************************************************************************/ + +javaxt.dhtml.style.default = { + + window : { + panel: "window", + header: "panel-header window-header", + title: "window-title", + button: "window-header-button", + buttonBar: "window-header-button-bar", + footerButton: "form-button noselect", + body: "window-body", + mask: "window-mask" + }, + + + callout : { + panel: "callout-panel", + arrow: "callout-arrow" + }, + + + form : { + label: "form-label noselect", + input: "form-input", + icon: { + padding: "0 8px 6px 0" + }, + button: "form-button noselect", + radio: "form-radio noselect", + checkbox: "form-checkbox", + groupbox: "form-groupbox", + grouplabel: "form-grouplabel noselect", + error: { + input: "form-input-error", + callout: { + panel: "error-callout-panel", + arrow: "error-callout-arrow" + } + } + }, + + + combobox : { + input: "form-input form-input-with-button", + button: "form-button form-input-button pulldown-button-icon", + menu: "form-input-menu", + option: "form-input-menu-item", + newOption: "form-input-menu-item form-input-menu-item-new" + }, + + + checkbox : { + panel: "checkbox-panel", + box: "checkbox-box", + label: "checkbox-label", + check: "checkbox-check", + select: "checkbox-select", + disable: "checkbox-disable", + hover: "checkbox-hover" + }, + + + button: { + button: "button", + select: "button-selected", + label: "button-label" + }, + + + toolbarButton : { + button: "toolbar-button", + select: "toolbar-button-selected", + hover: "toolbar-button-hover", + label: "toolbar-button-label" + }, + + iscroll: { + horizontalScrollbar: "iScrollHorizontalScrollbar", + verticalScrollbar: "iScrollVerticalScrollbar", + indicator: "iScrollIndicator" + }, + + table: { + headerRow: "table-header", + headerColumn : "table-header-col", + row: "table-row", + column: "table-col", + selectedRow: "table-row-selected", + resizeHandle: "table-resizeHandle", + ascendingSortIcon: "table-icon-sort-asc", + descendingSortIcon: "table-icon-sort-desc", + iscroll: null //updated below + }, + + tabPanel: { + tabBar: "tab-bar", + activeTab: "tab-active", + inactiveTab: "tab-inactive", + tabBody: "tab-body" + }, + + switch: { + groove: "switch-groove", + handle: "switch-handle", + grooveActive: "switch-groove-active", + handleActive: "switch-handle-active" + }, + + slider: { + groove: "slider-groove", + handle: "slider-handle" + }, + + datePicker: { + panel: "date-picker-panel", + header: "date-picker-header", + title: "date-picker-title", + cell: "date-picker-cell", + cellHeader: "date-picker-cell-header", + today: "date-picker-cell-today", + selectedRow: "date-picker-row-selected", + selectedCell: "date-picker-cell-selected", + next: "date-picker-next", + back: "date-picker-back" + }, + + + merge : function(settings, defaults) { + javaxt.dhtml.utils.merge(settings, defaults); + return settings; + } +}; + +javaxt.dhtml.style.default.table.iscroll = javaxt.dhtml.style.default.iscroll; \ No newline at end of file