From 7bfeeb578fe6c27b5fa4be5350465bdbad163b8c Mon Sep 17 00:00:00 2001 From: LUCASTUCIOUS Date: Sun, 5 Mar 2023 23:58:21 +0100 Subject: [PATCH] add w2ui lib --- .gitignore | 1 + README => README.md | 0 css/water.css | 1691 +++ index.html | 22 +- js/spells.js | 83 +- lib/jquery.localize-dev.js | 106 +- lib/w2ui/w2ui-1.5.css | 3720 ++++++ lib/w2ui/w2ui-1.5.js | 21501 +++++++++++++++++++++++++++++++++ lib/w2ui/w2ui-1.5.js.map | 1 + lib/w2ui/w2ui-1.5.min.css | 2 + lib/w2ui/w2ui-1.5.min.js | 2 + lib/w2ui/w2ui.css | 3714 ++++++ lib/w2ui/w2ui.es6.js | 22158 ++++++++++++++++++++++++++++++++++ lib/w2ui/w2ui.es6.min.js | 486 + lib/w2ui/w2ui.js | 22349 +++++++++++++++++++++++++++++++++++ lib/w2ui/w2ui.min.css | 2 + lib/w2ui/w2ui.min.js | 486 + spells.html | 69 +- 18 files changed, 76297 insertions(+), 96 deletions(-) rename README => README.md (100%) create mode 100644 css/water.css create mode 100644 lib/w2ui/w2ui-1.5.css create mode 100644 lib/w2ui/w2ui-1.5.js create mode 100644 lib/w2ui/w2ui-1.5.js.map create mode 100644 lib/w2ui/w2ui-1.5.min.css create mode 100644 lib/w2ui/w2ui-1.5.min.js create mode 100644 lib/w2ui/w2ui.css create mode 100644 lib/w2ui/w2ui.es6.js create mode 100644 lib/w2ui/w2ui.es6.min.js create mode 100644 lib/w2ui/w2ui.js create mode 100644 lib/w2ui/w2ui.min.css create mode 100644 lib/w2ui/w2ui.min.js diff --git a/.gitignore b/.gitignore index c3b59cd..8cefcb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.psd +*.pdf diff --git a/README b/README.md similarity index 100% rename from README rename to README.md diff --git a/css/water.css b/css/water.css new file mode 100644 index 0000000..a2090c1 --- /dev/null +++ b/css/water.css @@ -0,0 +1,1691 @@ +/** + * Water.css by kognise + * https://github.com/kognise/water.css + * Automatic version: + * Uses light theme by default but switches to dark theme + * if a system-wide theme preference is set on the user's device. + */ + + :root { + --background-body: #fff; + --background: #efefef; + --background-alt: #f7f7f7; + --selection: #9e9e9e; + --text-main: #363636; + --text-bright: #000; + --text-muted: #70777f; + --links: #0076d1; + --focus: #0096bfab; + --border: #dbdbdb; + --code: #000; + --animation-duration: 0.1s; + --button-base: #d0cfcf; + --button-hover: #9b9b9b; + --scrollbar-thumb: rgb(170, 170, 170); + --scrollbar-thumb-hover: var(--button-hover); + --form-placeholder: #949494; + --form-text: #1d1d1d; + --variable: #39a33c; + --highlight: #ff0; + --select-arrow: url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23161f27'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"); + } + + @media (prefers-color-scheme: dark) { + :root { + --background-body: #202b38; + --background: #161f27; + --background-alt: #1a242f; + --selection: #1c76c5; + --text-main: #dbdbdb; + --text-bright: #fff; + --text-muted: #a9b1ba; + --links: #41adff; + --focus: #0096bfab; + --border: #526980; + --code: #ffbe85; + --animation-duration: 0.1s; + --button-base: #0c151c; + --button-hover: #040a0f; + --scrollbar-thumb: var(--button-hover); + --scrollbar-thumb-hover: rgb(0, 0, 0); + --form-placeholder: #a9a9a9; + --form-text: #fff; + --variable: #d941e2; + --highlight: #efdb43; + --select-arrow: url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"); + } + } + + html { + scrollbar-color: rgb(170, 170, 170) #fff; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + scrollbar-width: thin; + } + + @media (prefers-color-scheme: dark) { + + html { + scrollbar-color: #040a0f #202b38; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + } + } + + @media (prefers-color-scheme: dark) { + + html { + scrollbar-color: #040a0f #202b38; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + } + } + + @media (prefers-color-scheme: dark) { + + html { + scrollbar-color: #040a0f #202b38; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + } + } + + @media (prefers-color-scheme: dark) { + + html { + scrollbar-color: #040a0f #202b38; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + } + } + + @media (prefers-color-scheme: dark) { + + html { + scrollbar-color: #040a0f #202b38; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + } + } + + @media (prefers-color-scheme: dark) { + + html { + scrollbar-color: #040a0f #202b38; + scrollbar-color: var(--scrollbar-thumb) var(--background-body); + } + } + + body { + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif; + line-height: 1.4; + max-width: 800px; + margin: 20px auto; + padding: 0 10px; + word-wrap: break-word; + color: #363636; + color: var(--text-main); + background: #fff; + background: var(--background-body); + text-rendering: optimizeLegibility; + } + + @media (prefers-color-scheme: dark) { + + body { + background: #202b38; + background: var(--background-body); + } + } + + @media (prefers-color-scheme: dark) { + + body { + color: #dbdbdb; + color: var(--text-main); + } + } + + button { + transition: + background-color 0.1s linear, + border-color 0.1s linear, + color 0.1s linear, + box-shadow 0.1s linear, + transform 0.1s ease; + transition: + background-color var(--animation-duration) linear, + border-color var(--animation-duration) linear, + color var(--animation-duration) linear, + box-shadow var(--animation-duration) linear, + transform var(--animation-duration) ease; + } + + @media (prefers-color-scheme: dark) { + + button { + transition: + background-color 0.1s linear, + border-color 0.1s linear, + color 0.1s linear, + box-shadow 0.1s linear, + transform 0.1s ease; + transition: + background-color var(--animation-duration) linear, + border-color var(--animation-duration) linear, + color var(--animation-duration) linear, + box-shadow var(--animation-duration) linear, + transform var(--animation-duration) ease; + } + } + + input { + transition: + background-color 0.1s linear, + border-color 0.1s linear, + color 0.1s linear, + box-shadow 0.1s linear, + transform 0.1s ease; + transition: + background-color var(--animation-duration) linear, + border-color var(--animation-duration) linear, + color var(--animation-duration) linear, + box-shadow var(--animation-duration) linear, + transform var(--animation-duration) ease; + } + + @media (prefers-color-scheme: dark) { + + input { + transition: + background-color 0.1s linear, + border-color 0.1s linear, + color 0.1s linear, + box-shadow 0.1s linear, + transform 0.1s ease; + transition: + background-color var(--animation-duration) linear, + border-color var(--animation-duration) linear, + color var(--animation-duration) linear, + box-shadow var(--animation-duration) linear, + transform var(--animation-duration) ease; + } + } + + textarea { + transition: + background-color 0.1s linear, + border-color 0.1s linear, + color 0.1s linear, + box-shadow 0.1s linear, + transform 0.1s ease; + transition: + background-color var(--animation-duration) linear, + border-color var(--animation-duration) linear, + color var(--animation-duration) linear, + box-shadow var(--animation-duration) linear, + transform var(--animation-duration) ease; + } + + @media (prefers-color-scheme: dark) { + + textarea { + transition: + background-color 0.1s linear, + border-color 0.1s linear, + color 0.1s linear, + box-shadow 0.1s linear, + transform 0.1s ease; + transition: + background-color var(--animation-duration) linear, + border-color var(--animation-duration) linear, + color var(--animation-duration) linear, + box-shadow var(--animation-duration) linear, + transform var(--animation-duration) ease; + } + } + + h1 { + font-size: 2.2em; + margin-top: 0; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin-bottom: 12px; + margin-top: 24px; + } + + h1 { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + h1 { + color: #fff; + color: var(--text-bright); + } + } + + h2 { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + h2 { + color: #fff; + color: var(--text-bright); + } + } + + h3 { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + h3 { + color: #fff; + color: var(--text-bright); + } + } + + h4 { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + h4 { + color: #fff; + color: var(--text-bright); + } + } + + h5 { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + h5 { + color: #fff; + color: var(--text-bright); + } + } + + h6 { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + h6 { + color: #fff; + color: var(--text-bright); + } + } + + strong { + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + strong { + color: #fff; + color: var(--text-bright); + } + } + + h1, + h2, + h3, + h4, + h5, + h6, + b, + strong, + th { + font-weight: 600; + } + + q::before { + content: none; + } + + q::after { + content: none; + } + + blockquote { + border-left: 4px solid #0096bfab; + border-left: 4px solid var(--focus); + margin: 1.5em 0; + padding: 0.5em 1em; + font-style: italic; + } + + @media (prefers-color-scheme: dark) { + + blockquote { + border-left: 4px solid #0096bfab; + border-left: 4px solid var(--focus); + } + } + + q { + border-left: 4px solid #0096bfab; + border-left: 4px solid var(--focus); + margin: 1.5em 0; + padding: 0.5em 1em; + font-style: italic; + } + + @media (prefers-color-scheme: dark) { + + q { + border-left: 4px solid #0096bfab; + border-left: 4px solid var(--focus); + } + } + + blockquote > footer { + font-style: normal; + border: 0; + } + + blockquote cite { + font-style: normal; + } + + address { + font-style: normal; + } + + a[href^='mailto\:']::before { + content: '📧 '; + } + + a[href^='tel\:']::before { + content: '📞 '; + } + + a[href^='sms\:']::before { + content: '💬 '; + } + + mark { + background-color: #ff0; + background-color: var(--highlight); + border-radius: 2px; + padding: 0 2px 0 2px; + color: #000; + } + + @media (prefers-color-scheme: dark) { + + mark { + background-color: #efdb43; + background-color: var(--highlight); + } + } + + a > code, + a > strong { + color: inherit; + } + + button, + select, + input[type='submit'], + input[type='reset'], + input[type='button'], + input[type='checkbox'], + input[type='range'], + input[type='radio'] { + cursor: pointer; + } + + input, + select { + display: block; + } + + [type='checkbox'], + [type='radio'] { + display: initial; + } + + input { + color: #1d1d1d; + color: var(--form-text); + background-color: #efefef; + background-color: var(--background); + font-family: inherit; + font-size: inherit; + margin-right: 6px; + margin-bottom: 6px; + padding: 10px; + border: none; + border-radius: 6px; + outline: none; + } + + @media (prefers-color-scheme: dark) { + + input { + background-color: #161f27; + background-color: var(--background); + } + } + + @media (prefers-color-scheme: dark) { + + input { + color: #fff; + color: var(--form-text); + } + } + + button { + color: #1d1d1d; + color: var(--form-text); + background-color: #efefef; + background-color: var(--background); + font-family: inherit; + font-size: inherit; + margin-right: 6px; + margin-bottom: 6px; + padding: 10px; + border: none; + border-radius: 6px; + outline: none; + } + + @media (prefers-color-scheme: dark) { + + button { + background-color: #161f27; + background-color: var(--background); + } + } + + @media (prefers-color-scheme: dark) { + + button { + color: #fff; + color: var(--form-text); + } + } + + textarea { + color: #1d1d1d; + color: var(--form-text); + background-color: #efefef; + background-color: var(--background); + font-family: inherit; + font-size: inherit; + margin-right: 6px; + margin-bottom: 6px; + padding: 10px; + border: none; + border-radius: 6px; + outline: none; + } + + @media (prefers-color-scheme: dark) { + + textarea { + background-color: #161f27; + background-color: var(--background); + } + } + + @media (prefers-color-scheme: dark) { + + textarea { + color: #fff; + color: var(--form-text); + } + } + + select { + color: #1d1d1d; + color: var(--form-text); + background-color: #efefef; + background-color: var(--background); + font-family: inherit; + font-size: inherit; + margin-right: 6px; + margin-bottom: 6px; + padding: 10px; + border: none; + border-radius: 6px; + outline: none; + } + + @media (prefers-color-scheme: dark) { + + select { + background-color: #161f27; + background-color: var(--background); + } + } + + @media (prefers-color-scheme: dark) { + + select { + color: #fff; + color: var(--form-text); + } + } + + button { + background-color: #d0cfcf; + background-color: var(--button-base); + padding-right: 30px; + padding-left: 30px; + } + + @media (prefers-color-scheme: dark) { + + button { + background-color: #0c151c; + background-color: var(--button-base); + } + } + + input[type='submit'] { + background-color: #d0cfcf; + background-color: var(--button-base); + padding-right: 30px; + padding-left: 30px; + } + + @media (prefers-color-scheme: dark) { + + input[type='submit'] { + background-color: #0c151c; + background-color: var(--button-base); + } + } + + input[type='reset'] { + background-color: #d0cfcf; + background-color: var(--button-base); + padding-right: 30px; + padding-left: 30px; + } + + @media (prefers-color-scheme: dark) { + + input[type='reset'] { + background-color: #0c151c; + background-color: var(--button-base); + } + } + + input[type='button'] { + background-color: #d0cfcf; + background-color: var(--button-base); + padding-right: 30px; + padding-left: 30px; + } + + @media (prefers-color-scheme: dark) { + + input[type='button'] { + background-color: #0c151c; + background-color: var(--button-base); + } + } + + button:hover { + background: #9b9b9b; + background: var(--button-hover); + } + + @media (prefers-color-scheme: dark) { + + button:hover { + background: #040a0f; + background: var(--button-hover); + } + } + + input[type='submit']:hover { + background: #9b9b9b; + background: var(--button-hover); + } + + @media (prefers-color-scheme: dark) { + + input[type='submit']:hover { + background: #040a0f; + background: var(--button-hover); + } + } + + input[type='reset']:hover { + background: #9b9b9b; + background: var(--button-hover); + } + + @media (prefers-color-scheme: dark) { + + input[type='reset']:hover { + background: #040a0f; + background: var(--button-hover); + } + } + + input[type='button']:hover { + background: #9b9b9b; + background: var(--button-hover); + } + + @media (prefers-color-scheme: dark) { + + input[type='button']:hover { + background: #040a0f; + background: var(--button-hover); + } + } + + input[type='color'] { + min-height: 2rem; + padding: 8px; + cursor: pointer; + } + + input[type='checkbox'], + input[type='radio'] { + height: 1em; + width: 1em; + } + + input[type='radio'] { + border-radius: 100%; + } + + input { + vertical-align: top; + } + + label { + vertical-align: middle; + margin-bottom: 4px; + display: inline-block; + } + + input:not([type='checkbox']):not([type='radio']), + input[type='range'], + select, + button, + textarea { + -webkit-appearance: none; + } + + textarea { + display: block; + margin-right: 0; + box-sizing: border-box; + resize: vertical; + } + + textarea:not([cols]) { + width: 100%; + } + + textarea:not([rows]) { + min-height: 40px; + height: 140px; + } + + select { + background: #efefef url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23161f27'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; + background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; + padding-right: 35px; + } + + @media (prefers-color-scheme: dark) { + + select { + background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; + background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; + } + } + + @media (prefers-color-scheme: dark) { + + select { + background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; + background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; + } + } + + @media (prefers-color-scheme: dark) { + + select { + background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; + background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; + } + } + + @media (prefers-color-scheme: dark) { + + select { + background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; + background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; + } + } + + select::-ms-expand { + display: none; + } + + select[multiple] { + padding-right: 10px; + background-image: none; + overflow-y: auto; + } + + input:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + + @media (prefers-color-scheme: dark) { + + input:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + } + + select:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + + @media (prefers-color-scheme: dark) { + + select:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + } + + button:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + + @media (prefers-color-scheme: dark) { + + button:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + } + + textarea:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + + @media (prefers-color-scheme: dark) { + + textarea:focus { + box-shadow: 0 0 0 2px #0096bfab; + box-shadow: 0 0 0 2px var(--focus); + } + } + + input[type='checkbox']:active, + input[type='radio']:active, + input[type='submit']:active, + input[type='reset']:active, + input[type='button']:active, + input[type='range']:active, + button:active { + transform: translateY(2px); + } + + input:disabled, + select:disabled, + button:disabled, + textarea:disabled { + cursor: not-allowed; + opacity: 0.5; + } + + ::-moz-placeholder { + color: #949494; + color: var(--form-placeholder); + } + + :-ms-input-placeholder { + color: #949494; + color: var(--form-placeholder); + } + + ::-ms-input-placeholder { + color: #949494; + color: var(--form-placeholder); + } + + ::placeholder { + color: #949494; + color: var(--form-placeholder); + } + + @media (prefers-color-scheme: dark) { + + ::-moz-placeholder { + color: #a9a9a9; + color: var(--form-placeholder); + } + + :-ms-input-placeholder { + color: #a9a9a9; + color: var(--form-placeholder); + } + + ::-ms-input-placeholder { + color: #a9a9a9; + color: var(--form-placeholder); + } + + ::placeholder { + color: #a9a9a9; + color: var(--form-placeholder); + } + } + + fieldset { + border: 1px #0096bfab solid; + border: 1px var(--focus) solid; + border-radius: 6px; + margin: 0; + margin-bottom: 12px; + padding: 10px; + } + + @media (prefers-color-scheme: dark) { + + fieldset { + border: 1px #0096bfab solid; + border: 1px var(--focus) solid; + } + } + + legend { + font-size: 0.9em; + font-weight: 600; + } + + input[type='range'] { + margin: 10px 0; + padding: 10px 0; + background: transparent; + } + + input[type='range']:focus { + outline: none; + } + + input[type='range']::-webkit-slider-runnable-track { + width: 100%; + height: 9.5px; + -webkit-transition: 0.2s; + transition: 0.2s; + background: #efefef; + background: var(--background); + border-radius: 3px; + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-webkit-slider-runnable-track { + background: #161f27; + background: var(--background); + } + } + + input[type='range']::-webkit-slider-thumb { + box-shadow: 0 1px 1px #000, 0 0 1px #0d0d0d; + height: 20px; + width: 20px; + border-radius: 50%; + background: #dbdbdb; + background: var(--border); + -webkit-appearance: none; + margin-top: -7px; + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-webkit-slider-thumb { + background: #526980; + background: var(--border); + } + } + + input[type='range']:focus::-webkit-slider-runnable-track { + background: #efefef; + background: var(--background); + } + + @media (prefers-color-scheme: dark) { + + input[type='range']:focus::-webkit-slider-runnable-track { + background: #161f27; + background: var(--background); + } + } + + input[type='range']::-moz-range-track { + width: 100%; + height: 9.5px; + -moz-transition: 0.2s; + transition: 0.2s; + background: #efefef; + background: var(--background); + border-radius: 3px; + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-moz-range-track { + background: #161f27; + background: var(--background); + } + } + + input[type='range']::-moz-range-thumb { + box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; + height: 20px; + width: 20px; + border-radius: 50%; + background: #dbdbdb; + background: var(--border); + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-moz-range-thumb { + background: #526980; + background: var(--border); + } + } + + input[type='range']::-ms-track { + width: 100%; + height: 9.5px; + background: transparent; + border-color: transparent; + border-width: 16px 0; + color: transparent; + } + + input[type='range']::-ms-fill-lower { + background: #efefef; + background: var(--background); + border: 0.2px solid #010101; + border-radius: 3px; + box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-ms-fill-lower { + background: #161f27; + background: var(--background); + } + } + + input[type='range']::-ms-fill-upper { + background: #efefef; + background: var(--background); + border: 0.2px solid #010101; + border-radius: 3px; + box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-ms-fill-upper { + background: #161f27; + background: var(--background); + } + } + + input[type='range']::-ms-thumb { + box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; + border: 1px solid #000; + height: 20px; + width: 20px; + border-radius: 50%; + background: #dbdbdb; + background: var(--border); + } + + @media (prefers-color-scheme: dark) { + + input[type='range']::-ms-thumb { + background: #526980; + background: var(--border); + } + } + + input[type='range']:focus::-ms-fill-lower { + background: #efefef; + background: var(--background); + } + + @media (prefers-color-scheme: dark) { + + input[type='range']:focus::-ms-fill-lower { + background: #161f27; + background: var(--background); + } + } + + input[type='range']:focus::-ms-fill-upper { + background: #efefef; + background: var(--background); + } + + @media (prefers-color-scheme: dark) { + + input[type='range']:focus::-ms-fill-upper { + background: #161f27; + background: var(--background); + } + } + + a { + text-decoration: none; + color: #0076d1; + color: var(--links); + } + + @media (prefers-color-scheme: dark) { + + a { + color: #41adff; + color: var(--links); + } + } + + a:hover { + text-decoration: underline; + } + + code { + background: #efefef; + background: var(--background); + color: #000; + color: var(--code); + padding: 2.5px 5px; + border-radius: 6px; + font-size: 1em; + } + + @media (prefers-color-scheme: dark) { + + code { + color: #ffbe85; + color: var(--code); + } + } + + @media (prefers-color-scheme: dark) { + + code { + background: #161f27; + background: var(--background); + } + } + + samp { + background: #efefef; + background: var(--background); + color: #000; + color: var(--code); + padding: 2.5px 5px; + border-radius: 6px; + font-size: 1em; + } + + @media (prefers-color-scheme: dark) { + + samp { + color: #ffbe85; + color: var(--code); + } + } + + @media (prefers-color-scheme: dark) { + + samp { + background: #161f27; + background: var(--background); + } + } + + time { + background: #efefef; + background: var(--background); + color: #000; + color: var(--code); + padding: 2.5px 5px; + border-radius: 6px; + font-size: 1em; + } + + @media (prefers-color-scheme: dark) { + + time { + color: #ffbe85; + color: var(--code); + } + } + + @media (prefers-color-scheme: dark) { + + time { + background: #161f27; + background: var(--background); + } + } + + pre > code { + padding: 10px; + display: block; + overflow-x: auto; + } + + var { + color: #39a33c; + color: var(--variable); + font-style: normal; + font-family: monospace; + } + + @media (prefers-color-scheme: dark) { + + var { + color: #d941e2; + color: var(--variable); + } + } + + kbd { + background: #efefef; + background: var(--background); + border: 1px solid #dbdbdb; + border: 1px solid var(--border); + border-radius: 2px; + color: #363636; + color: var(--text-main); + padding: 2px 4px 2px 4px; + } + + @media (prefers-color-scheme: dark) { + + kbd { + color: #dbdbdb; + color: var(--text-main); + } + } + + @media (prefers-color-scheme: dark) { + + kbd { + border: 1px solid #526980; + border: 1px solid var(--border); + } + } + + @media (prefers-color-scheme: dark) { + + kbd { + background: #161f27; + background: var(--background); + } + } + + img, + video { + max-width: 100%; + height: auto; + } + + hr { + border: none; + border-top: 1px solid #dbdbdb; + border-top: 1px solid var(--border); + } + + @media (prefers-color-scheme: dark) { + + hr { + border-top: 1px solid #526980; + border-top: 1px solid var(--border); + } + } + + table { + border-collapse: collapse; + margin-bottom: 10px; + width: 100%; + table-layout: fixed; + } + + table caption { + text-align: left; + } + + td, + th { + padding: 6px; + text-align: left; + vertical-align: top; + word-wrap: break-word; + } + + thead { + border-bottom: 1px solid #dbdbdb; + border-bottom: 1px solid var(--border); + } + + @media (prefers-color-scheme: dark) { + + thead { + border-bottom: 1px solid #526980; + border-bottom: 1px solid var(--border); + } + } + + tfoot { + border-top: 1px solid #dbdbdb; + border-top: 1px solid var(--border); + } + + @media (prefers-color-scheme: dark) { + + tfoot { + border-top: 1px solid #526980; + border-top: 1px solid var(--border); + } + } + + tbody tr:nth-child(even) { + background-color: #efefef; + background-color: var(--background); + } + + @media (prefers-color-scheme: dark) { + + tbody tr:nth-child(even) { + background-color: #161f27; + background-color: var(--background); + } + } + + tbody tr:nth-child(even) button { + background-color: #f7f7f7; + background-color: var(--background-alt); + } + + @media (prefers-color-scheme: dark) { + + tbody tr:nth-child(even) button { + background-color: #1a242f; + background-color: var(--background-alt); + } + } + + tbody tr:nth-child(even) button:hover { + background-color: #fff; + background-color: var(--background-body); + } + + @media (prefers-color-scheme: dark) { + + tbody tr:nth-child(even) button:hover { + background-color: #202b38; + background-color: var(--background-body); + } + } + + ::-webkit-scrollbar { + height: 10px; + width: 10px; + } + + ::-webkit-scrollbar-track { + background: #efefef; + background: var(--background); + border-radius: 6px; + } + + @media (prefers-color-scheme: dark) { + + ::-webkit-scrollbar-track { + background: #161f27; + background: var(--background); + } + } + + ::-webkit-scrollbar-thumb { + background: rgb(170, 170, 170); + background: var(--scrollbar-thumb); + border-radius: 6px; + } + + @media (prefers-color-scheme: dark) { + + ::-webkit-scrollbar-thumb { + background: #040a0f; + background: var(--scrollbar-thumb); + } + } + + @media (prefers-color-scheme: dark) { + + ::-webkit-scrollbar-thumb { + background: #040a0f; + background: var(--scrollbar-thumb); + } + } + + ::-webkit-scrollbar-thumb:hover { + background: #9b9b9b; + background: var(--scrollbar-thumb-hover); + } + + @media (prefers-color-scheme: dark) { + + ::-webkit-scrollbar-thumb:hover { + background: rgb(0, 0, 0); + background: var(--scrollbar-thumb-hover); + } + } + + @media (prefers-color-scheme: dark) { + + ::-webkit-scrollbar-thumb:hover { + background: rgb(0, 0, 0); + background: var(--scrollbar-thumb-hover); + } + } + + ::-moz-selection { + background-color: #9e9e9e; + background-color: var(--selection); + color: #000; + color: var(--text-bright); + } + + ::selection { + background-color: #9e9e9e; + background-color: var(--selection); + color: #000; + color: var(--text-bright); + } + + @media (prefers-color-scheme: dark) { + + ::-moz-selection { + color: #fff; + color: var(--text-bright); + } + + ::selection { + color: #fff; + color: var(--text-bright); + } + } + + @media (prefers-color-scheme: dark) { + + ::-moz-selection { + background-color: #1c76c5; + background-color: var(--selection); + } + + ::selection { + background-color: #1c76c5; + background-color: var(--selection); + } + } + + details { + display: flex; + flex-direction: column; + align-items: flex-start; + background-color: #f7f7f7; + background-color: var(--background-alt); + padding: 10px 10px 0; + margin: 1em 0; + border-radius: 6px; + overflow: hidden; + } + + @media (prefers-color-scheme: dark) { + + details { + background-color: #1a242f; + background-color: var(--background-alt); + } + } + + details[open] { + padding: 10px; + } + + details > :last-child { + margin-bottom: 0; + } + + details[open] summary { + margin-bottom: 10px; + } + + summary { + display: list-item; + background-color: #efefef; + background-color: var(--background); + padding: 10px; + margin: -10px -10px 0; + cursor: pointer; + outline: none; + } + + @media (prefers-color-scheme: dark) { + + summary { + background-color: #161f27; + background-color: var(--background); + } + } + + summary:hover, + summary:focus { + text-decoration: underline; + } + + details > :not(summary) { + margin-top: 0; + } + + summary::-webkit-details-marker { + color: #363636; + color: var(--text-main); + } + + @media (prefers-color-scheme: dark) { + + summary::-webkit-details-marker { + color: #dbdbdb; + color: var(--text-main); + } + } + + dialog { + background-color: #f7f7f7; + background-color: var(--background-alt); + color: #363636; + color: var(--text-main); + border: none; + border-radius: 6px; + border-color: #dbdbdb; + border-color: var(--border); + padding: 10px 30px; + } + + @media (prefers-color-scheme: dark) { + + dialog { + border-color: #526980; + border-color: var(--border); + } + } + + @media (prefers-color-scheme: dark) { + + dialog { + color: #dbdbdb; + color: var(--text-main); + } + } + + @media (prefers-color-scheme: dark) { + + dialog { + background-color: #1a242f; + background-color: var(--background-alt); + } + } + + dialog > header:first-child { + background-color: #efefef; + background-color: var(--background); + border-radius: 6px 6px 0 0; + margin: -10px -30px 10px; + padding: 10px; + text-align: center; + } + + @media (prefers-color-scheme: dark) { + + dialog > header:first-child { + background-color: #161f27; + background-color: var(--background); + } + } + + dialog::-webkit-backdrop { + background: #0000009c; + -webkit-backdrop-filter: blur(4px); + backdrop-filter: blur(4px); + } + + dialog::backdrop { + background: #0000009c; + -webkit-backdrop-filter: blur(4px); + backdrop-filter: blur(4px); + } + + footer { + border-top: 1px solid #dbdbdb; + border-top: 1px solid var(--border); + padding-top: 10px; + color: #70777f; + color: var(--text-muted); + } + + @media (prefers-color-scheme: dark) { + + footer { + color: #a9b1ba; + color: var(--text-muted); + } + } + + @media (prefers-color-scheme: dark) { + + footer { + border-top: 1px solid #526980; + border-top: 1px solid var(--border); + } + } + + body > footer { + margin-top: 40px; + } + + @media print { + body, + pre, + code, + summary, + details, + button, + input, + textarea { + background-color: #fff; + } + + button, + input, + textarea { + border: 1px solid #000; + } + + body, + h1, + h2, + h3, + h4, + h5, + h6, + pre, + code, + button, + input, + textarea, + footer, + summary, + strong { + color: #000; + } + + summary::marker { + color: #000; + } + + summary::-webkit-details-marker { + color: #000; + } + + tbody tr:nth-child(even) { + background-color: #f2f2f2; + } + + a { + color: #00f; + text-decoration: underline; + } + } \ No newline at end of file diff --git a/index.html b/index.html index 9b87ed7..ecfb860 100644 --- a/index.html +++ b/index.html @@ -5,19 +5,21 @@ fateforge-tools - + - - +
+ + -

FateforgeTools

-
- A suite of tools for Fateforge players and Masters. -
+

FateforgeTools

+
+ A suite of tools for Fateforge players and Masters. +
+

' + + '' + : '' + + '' + ), + onOpen: function (event) { + var inputs = $(this.box).find('input, textarea, select, button'); + inputs.off('.message') + .on('blur.message', function (evt) { + // last input + if (inputs.index(evt.target) + 1 === inputs.length) { + inputs.get(0).focus(); + evt.preventDefault(); + } + }) + .on('keydown.message', function (evt) { + if (evt.keyCode == 27) obj.message(); // esc + }); + setTimeout(function () { + $(this.box).find('.w2ui-btn.btn-default').focus(); + clearTimeout(obj.last.kbd_timer); + }.bind(this), 50); + } + }); + return; + } + // call delete script + var url = (typeof this.url != 'object' ? this.url : this.url.remove); + if (url) { + this.request('delete'); + } else { + if (typeof recs[0] != 'object') { + this.selectNone(); + this.remove.apply(this, recs); + } else { + // clear cells + for (var r = 0; r < recs.length; r++) { + var fld = this.columns[recs[r].column].field; + var ind = this.get(recs[r].recid, true); + var rec = this.records[ind]; + if (ind != null && fld != 'recid') { + this.records[ind][fld] = ''; + if (rec.w2ui && rec.w2ui.changes) delete rec.w2ui.changes[fld]; + // -- style should not be deleted + // if (rec.style != null && $.isPlainObject(rec.style) && rec.style[recs[r].column]) { + // delete rec.style[recs[r].column]; + // } + } + } + this.update(); + } + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + click: function (recid, event) { + var time = (new Date()).getTime(); + var column = null; + var obj = this; + if (this.last.cancelClick == true || (event && event.altKey)) return; + if ((typeof recid == 'object') && (recid !== null)) { + column = recid.column; + recid = recid.recid; + } + if (event == null) event = {}; + // check for double click + if (time - parseInt(this.last.click_time) < 350 && this.last.click_recid == recid && event.type == 'click') { + this.dblClick(recid, event); + return; + } + // hide bubble + if (this.last.bubbleEl) { + $(this.last.bubbleEl).w2tag(); + this.last.bubbleEl = null; + } + this.last.click_time = time; + var last_recid = this.last.click_recid; + this.last.click_recid = recid; + // column user clicked on + if (column == null && event.target) { + var tmp = event.target; + if (tmp.tagName.toUpperCase() != 'TD') tmp = $(tmp).parents('td')[0]; + if ($(tmp).attr('col') != null) column = parseInt($(tmp).attr('col')); + } + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'click', recid: recid, column: column, originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + var obj = this; + var sel = this.getSelection(); + $('#grid_'+ this.name +'_check_all').prop("checked", false); + var ind = this.get(recid, true); + var record = this.records[ind]; + var selectColumns = []; + obj.last.sel_ind = ind; + obj.last.sel_col = column; + obj.last.sel_recid = recid; + obj.last.sel_type = 'click'; + // multi select with shif key + if (event.shiftKey && sel.length > 0 && obj.multiSelect) { + if (sel[0].recid) { + var start = this.get(sel[0].recid, true); + var end = this.get(recid, true); + if (column > sel[0].column) { + var t1 = sel[0].column; + var t2 = column; + } else { + var t1 = column; + var t2 = sel[0].column; + } + for (var c = t1; c <= t2; c++) selectColumns.push(c); + } else { + var start = this.get(last_recid, true); + var end = this.get(recid, true); + } + var sel_add = []; + if (start > end) { var tmp = start; start = end; end = tmp; } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + for (var i = start; i <= end; i++) { + if (this.searchData.length > 0 && !url && $.inArray(i, this.last.searchIds) == -1) continue; + if (this.selectType == 'row') { + sel_add.push(this.records[i].recid); + } else { + for (var sc = 0; sc < selectColumns.length; sc++) { + sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }); + } + } + //sel.push(this.records[i].recid); + } + this.select(sel_add); + } else { + var last = this.last.selection; + var flag = (last.indexes.indexOf(ind) != -1 ? true : false); + var fselect = false; + // if clicked on the checkbox + if ($(event.target).parents('td').hasClass('w2ui-col-select')) fselect = true; + // clear other if necessary + if (((!event.ctrlKey && !event.shiftKey && !event.metaKey && !fselect) || !this.multiSelect) && !this.showSelectColumn) { + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; + if (sel.length > 300) this.selectNone(); else this.unselect(sel); + if (flag === true && sel.length == 1) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } else { + var isChecked = $(event.target).parents('tr').find('.w2ui-grid-select-check').is(':checked'); + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1 && !isChecked) flag = false; + if (flag === true) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } + } + this.status(); + obj.initResize(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + columnClick: function (field, event) { + // event before + var edata = this.trigger({ phase: 'before', type: 'columnClick', target: this.name, field: field, originalEvent: event }); + if (edata.isCancelled === true) return; + // default behaviour + if (this.selectType == 'row') { + var column = this.getColumn(field); + if (column && column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false) ); + if (edata.field == 'line-number') { + if (this.getSelection().length >= this.records.length) { + this.selectNone(); + } else { + this.selectAll(); + } + } + } else { + if (event.altKey){ + var column = this.getColumn(field); + if (column && column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false) ); + } + // select entire column + if (edata.field == 'line-number') { + if (this.getSelection().length >= this.records.length) { + this.selectNone(); + } else { + this.selectAll(); + } + } else { + if (!event.shiftKey && !event.metaKey && !event.ctrlKey) { + this.selectNone(); + } + var tmp = this.getSelection(); + var column = this.getColumn(edata.field, true); + var sel = []; + var cols = []; + // check if there was a selection before + if (tmp.length != 0 && event.shiftKey) { + var start = column; + var end = tmp[0].column; + if (start > end) { + start = tmp[0].column; + end = column; + } + for (var i=start; i<=end; i++) cols.push(i); + } else { + cols.push(column); + } + var edata = this.trigger({ phase: 'before', type: 'columnSelect', target: this.name, columns: cols }); + if (edata.isCancelled !== true) { + for (var i = 0; i < this.records.length; i++) { + sel.push({ recid: this.records[i].recid, column: cols }); + } + this.select(sel); + } + this.trigger($.extend(edata, { phase: 'after' })); + } + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + columnDblClick: function (field, event) { + // event before + var edata = this.trigger({ phase: 'before', type: 'columnDblClick', target: this.name, field: field, originalEvent: event }); + if (edata.isCancelled === true) return; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + focus: function (event) { + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', type: 'focus', target: this.name, originalEvent: event }); + if (edata.isCancelled === true) return false; + // default behaviour + this.hasFocus = true; + $(this.box).removeClass('w2ui-inactive').find('.w2ui-inactive').removeClass('w2ui-inactive'); + setTimeout(function () { + var $input = $(obj.box).find('#grid_'+ obj.name + '_focus'); + if (!$input.is(':focus')) $input.focus(); + }, 10); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + blur: function (event) { + // event before + var edata = this.trigger({ phase: 'before', type: 'blur', target: this.name, originalEvent: event }); + if (edata.isCancelled === true) return false; + // default behaviour + this.hasFocus = false; + $(this.box).addClass('w2ui-inactive').find('.w2ui-selected').addClass('w2ui-inactive'); + $(this.box).find('.w2ui-selection').addClass('w2ui-inactive'); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + keydown: function (event) { + // this method is called from w2utils + var obj = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (obj.keyboard !== true) return; + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + if (edata.isCancelled === true) return; + // default behavior + if ($(this.box).find('>.w2ui-message').length > 0) { + // if there are messages + if (event.keyCode == 27) this.message(); + return + } + var empty = false; + var records = $('#grid_'+ obj.name +'_records'); + var sel = obj.getSelection(); + if (sel.length === 0) empty = true; + var recid = sel[0] || null; + var columns = []; + var recid2 = sel[sel.length-1]; + if (typeof recid == 'object' && recid != null) { + recid = sel[0].recid; + columns = []; + var ii = 0; + while (true) { + if (!sel[ii] || sel[ii].recid != recid) break; + columns.push(sel[ii].column); + ii++; + } + recid2 = sel[sel.length-1].recid; + } + var ind = obj.get(recid, true); + var ind2 = obj.get(recid2, true); + var rec = obj.get(recid); + var recEL = $('#grid_'+ obj.name +'_rec_'+ (ind != null ? w2utils.escapeId(obj.records[ind].recid) : 'none')); + var cancel = false; + var key = event.keyCode; + var shiftKey = event.shiftKey; + + switch (key) { + case 8: // backspace + case 46: // delete + // delete if button is visible + obj["delete"](); + cancel = true; + event.stopPropagation(); + break; + + case 27: // escape + obj.selectNone(); + cancel = true; + break; + + case 65: // cmd + A + if (!event.metaKey && !event.ctrlKey) break; + obj.selectAll(); + cancel = true; + break; + + case 13: // enter + // if expandable columns - expand it + if (this.selectType == 'row' && obj.show.expandColumn === true) { + if (recEL.length <= 0) break; + obj.toggle(recid, event); + cancel = true; + } else { // or enter edit + for (var c = 0; c < this.columns.length; c++) { + var edit = this.getCellEditable(ind, c); + if (edit) { + columns.push(parseInt(c)); + break; + } + } + // edit last column that was edited + if (this.selectType == 'row' && this.last._edit && this.last._edit.column) { + columns = [this.last._edit.column]; + } + if (columns.length > 0) { + obj.editField(recid, columns[0], null, event); + cancel = true; + } + } + break; + + case 37: // left + if (empty) { // no selection + selectTopRecord(); + break; + } + if (this.selectType == 'row') { + if (recEL.length <= 0) break; + var tmp = this.records[ind].w2ui || {}; + if (tmp && tmp.parent_recid != null && (!Array.isArray(tmp.children) || tmp.children.length === 0 || !tmp.expanded)) { + obj.unselect(recid); + obj.collapse(tmp.parent_recid, event); + obj.select(tmp.parent_recid); + } else { + obj.collapse(recid, event); + } + } else { + var prev = obj.prevCell(ind, columns[0]); + if (!shiftKey && prev == null) { + this.selectNone(); + prev = 0; + } + if (prev != null) { + if (shiftKey && obj.multiSelect) { + if (tmpUnselect()) return; + var tmp = []; + var newSel = []; + var unSel = []; + if (columns.indexOf(this.last.sel_col) === 0 && columns.length > 1) { + for (var i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }); + } + obj.unselect(unSel); + obj.scrollIntoView(ind, columns[columns.length-1], true); + } else { + for (var i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + newSel.push({ recid: sel[i].recid, column: prev }); + } + obj.select(newSel); + obj.scrollIntoView(ind, prev, true); + } + } else { + event.metaKey = false; + obj.click({ recid: recid, column: prev }, event); + obj.scrollIntoView(ind, prev, true); + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + if (sel.length > 1) { + obj.selectNone(); + } else { + for (var s = 1; s < sel.length; s++) obj.unselect(sel[s]); + } + } + } + } + cancel = true; + break; + + case 39: // right + if (empty) { + selectTopRecord(); + break; + } + if (this.selectType == 'row') { + if (recEL.length <= 0) break; + obj.expand(recid, event); + } else { + var next = obj.nextCell(ind, columns[columns.length-1]); // columns is an array of selected columns + if (!shiftKey && next == null) { + this.selectNone(); + next = this.columns.length-1; + } + if (next != null) { + if (shiftKey && key == 39 && obj.multiSelect) { + if (tmpUnselect()) return; + var tmp = []; + var newSel = []; + var unSel = []; + if (columns.indexOf(this.last.sel_col) == columns.length-1 && columns.length > 1) { + for (var i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + unSel.push({ recid: sel[i].recid, column: columns[0] }); + } + obj.unselect(unSel); + obj.scrollIntoView(ind, columns[0], true); + } else { + for (var i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + newSel.push({ recid: sel[i].recid, column: next }); + } + obj.select(newSel); + obj.scrollIntoView(ind, next, true); + } + } else { + event.metaKey = false; + obj.click({ recid: recid, column: next }, event); + obj.scrollIntoView(ind, next, true); + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + if (sel.length > 1) { + obj.selectNone(); + } else { + for (var s = 0; s < sel.length-1; s++) obj.unselect(sel[s]); + } + } + } + } + cancel = true; + break; + + case 38: // up + if (empty) selectTopRecord(); + if (recEL.length <= 0) break; + // move to the previous record + var prev = obj.prevRow(ind, columns[0]); + if (!shiftKey && prev == null) { + if (this.searchData.length != 0 && !url) { + prev = this.last.searchIds[0]; + } else { + prev = 0; + } + } + if (prev != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return; + if (obj.selectType == 'row') { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + obj.unselect(obj.records[ind2].recid); + } else { + obj.select(obj.records[prev].recid); + } + } else { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + prev = ind2; + var tmp = []; + for (var c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.unselect(tmp); + } else { + var tmp = []; + for (var c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.select(tmp); + } + } + } else { // move selected record + if (sel.length > 300) this.selectNone(); else this.unselect(sel); + obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event); + } + obj.scrollIntoView(prev); + if (event.preventDefault) event.preventDefault(); + } else { + // if selected more then one, then select first + if (!shiftKey) { + if (sel.length > 1) { + obj.selectNone(); + } else { + for (var s = 1; s < sel.length; s++) obj.unselect(sel[s]); + } + } + } + break; + + case 40: // down + if (empty) selectTopRecord(); + if (recEL.length <= 0) break; + // move to the next record + var next = obj.nextRow(ind2, columns[0]); + if (!shiftKey && next == null) { + if (this.searchData.length != 0 && !url) { + next = this.last.searchIds[this.last.searchIds.length - 1]; + } else { + next = this.records.length - 1; + } + } + if (next != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return; + if (obj.selectType == 'row') { + if (this.last.sel_ind < next && this.last.sel_ind != ind) { + obj.unselect(obj.records[ind].recid); + } else { + obj.select(obj.records[next].recid); + } + } else { + if (this.last.sel_ind < next && this.last.sel_ind != ind) { + next = ind; + var tmp = []; + for (var c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.unselect(tmp); + } else { + var tmp = []; + for (var c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.select(tmp); + } + } + } else { // move selected record + if (sel.length > 300) this.selectNone(); else this.unselect(sel); + obj.click({ recid: obj.records[next].recid, column: columns[0] }, event); + } + obj.scrollIntoView(next); + cancel = true; + } else { + // if selected more then one, then select first + if (!shiftKey) { + if (sel.length > 1) { + obj.selectNone(); + } else { + for (var s = 0; s < sel.length-1; s++) obj.unselect(sel[s]); + } + } + } + break; + + // copy & paste + + case 17: // ctrl key + case 91: // cmd key + // SLOW: 10k records take 7.0 + if (empty) break; + // in Safari need to copy to buffer on cmd or ctrl key (otherwise does not work) + if (obj.last.isSafari) { + obj.last.copy_event = obj.copy(false, event); + $('#grid_'+ obj.name + '_focus').val(obj.last.copy_event.text).select(); + } + break; + + case 67: // - c + // this fill trigger event.onComplete + if (event.metaKey || event.ctrlKey) { + if (obj.last.isSafari) { + obj.copy(obj.last.copy_event, event); + } else { + obj.last.copy_event = obj.copy(false, event); + $('#grid_'+ obj.name + '_focus').val(obj.last.copy_event.text).select(); + obj.copy(obj.last.copy_event, event); + } + } + break; + + case 88: // x - cut + if (empty) break; + if (event.ctrlKey || event.metaKey) { + if (obj.last.isSafari) { + obj.copy(obj.last.copy_event, event); + } else { + obj.last.copy_event = obj.copy(false, event); + $('#grid_'+ obj.name + '_focus').val(obj.last.copy_event.text).select(); + obj.copy(obj.last.copy_event, event); + } + } + break; + } + var tmp = [32, 187, 189, 192, 219, 220, 221, 186, 222, 188, 190, 191]; // other typable chars + for (var i=48; i<=111; i++) tmp.push(i); // 0-9,a-z,A-Z,numpad + if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { + if (columns.length === 0) columns.push(0); + cancel = false; + // move typed key into edit + setTimeout(function () { + var focus = $('#grid_'+ obj.name + '_focus'); + var key = focus.val(); + focus.val(''); + obj.editField(recid, columns[0], key, event); + }, 1); + } + if (cancel) { // cancel default behaviour + if (event.preventDefault) event.preventDefault(); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + + function selectTopRecord() { + var ind = Math.floor(records[0].scrollTop / obj.recordHeight) + 1; + if (!obj.records[ind] || ind < 2) ind = 0; + obj.select({ recid: obj.records[ind].recid, column: 0}); + } + + function tmpUnselect () { + if (obj.last.sel_type != 'click') return false; + if (obj.selectType != 'row') { + obj.last.sel_type = 'key'; + if (sel.length > 1) { + for (var s = 0; s < sel.length; s++) { + if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { + sel.splice(s, 1); + break; + } + } + obj.unselect(sel); + return true; + } + return false; + } else { + obj.last.sel_type = 'key'; + if (sel.length > 1) { + sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1); + obj.unselect(sel); + return true; + } + return false; + } + } + }, + + scrollIntoView: function (ind, column, instant) { + var buffered = this.records.length; + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length; + if (buffered === 0) return; + if (ind == null) { + var sel = this.getSelection(); + if (sel.length === 0) return; + if ($.isPlainObject(sel[0])) { + ind = sel[0].index; + column = sel[0].column; + } else { + ind = this.get(sel[0], true); + } + } + var records = $('#grid_'+ this.name +'_records'); + // if all records in view + var len = this.last.searchIds.length; + if (len > 0) ind = this.last.searchIds.indexOf(ind); // if search is applied + + // vertical + if (records.height() < this.recordHeight * (len > 0 ? len : buffered) && records.length > 0) { + // scroll to correct one + var t1 = Math.floor(records[0].scrollTop / this.recordHeight); + var t2 = t1 + Math.floor(records.height() / this.recordHeight); + if (ind == t1) { + if (instant === true) { + records.prop({ 'scrollTop': records.scrollTop() - records.height() / 1.3 }); + } else { + records.stop(); + records.animate({ 'scrollTop': records.scrollTop() - records.height() / 1.3 }, 250, 'linear'); + } + } + if (ind == t2) { + if (instant === true) { + records.prop({ 'scrollTop': records.scrollTop() + records.height() / 1.3 }); + } else { + records.stop(); + records.animate({ 'scrollTop': records.scrollTop() + records.height() / 1.3 }, 250, 'linear'); + } + } + if (ind < t1 || ind > t2) { + if (instant === true) { + records.prop({ 'scrollTop': (ind - 1) * this.recordHeight }); + } else { + records.stop(); + records.animate({ 'scrollTop': (ind - 1) * this.recordHeight }, 250, 'linear'); + } + } + } + + // horizontal + if (column != null) { + var x1 = 0; + var x2 = 0; + var sb = w2utils.scrollBarSize(); + for (var i = 0; i <= column; i++) { + var col = this.columns[i]; + if (col.frozen || col.hidden) continue; + x1 = x2; + x2 += parseInt(col.sizeCalculated); + } + if (records.width() < x2 - records.scrollLeft()) { // right + if (instant === true) { + records.prop({ 'scrollLeft': x1 - sb }); + } else { + records.animate({ 'scrollLeft': x1 - sb }, 250, 'linear'); + } + } else if (x1 < records.scrollLeft()) { // left + if (instant === true) { + records.prop({ 'scrollLeft': x2 - records.width() + sb * 2 }); + } else { + records.animate({ 'scrollLeft': x2 - records.width() + sb * 2 }, 250, 'linear'); + } + } + } + }, + + dblClick: function (recid, event) { + // find columns + var column = null; + if ((typeof recid == 'object') && (recid !== null)) { + column = recid.column; + recid = recid.recid; + } + if (event == null) event = {}; + // column user clicked on + if (column == null && event.target) { + var tmp = event.target; + if (tmp.tagName.toUpperCase() != 'TD') tmp = $(tmp).parents('td')[0]; + column = parseInt($(tmp).attr('col')); + } + var index = this.get(recid, true); + var rec = this.records[index]; + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'dblClick', recid: recid, column: column, originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + this.selectNone(); + var edit = this.getCellEditable(index, column); + if (edit) { + this.editField(recid, column, null, event); + } else { + this.select({ recid: recid, column: column }); + if (this.show.expandColumn || (rec.w2ui && Array.isArray(rec.w2ui.children))) this.toggle(recid); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + contextMenu: function (recid, column, event) { + var obj = this; + if (obj.last.userSelect == 'text') return; + if (event == null) event = { offsetX: 0, offsetY: 0, target: $('#grid_'+ obj.name +'_rec_'+ recid)[0] }; + if (event.offsetX == null) { + event.offsetX = event.layerX - event.target.offsetLeft; + event.offsetY = event.layerY - event.target.offsetTop; + } + if (w2utils.isFloat(recid)) recid = parseFloat(recid); + var sel = this.getSelection(); + if (this.selectType == 'row') { + if (sel.indexOf(recid) == -1) obj.click(recid); + } else { + var $tmp = $(event.target); + if ($tmp[0].tagName.toUpperCase() != 'TD') $tmp = $(event.target).parents('td'); + var selected = false; + column = $tmp.attr('col'); + // check if any selected sel in the right row/column + for (var i=0; i 0) { + $(obj.box).find(event.target) + .w2menu(obj.menu, { + originalEvent: event, + contextMenu: true, + onSelect: function (event) { + obj.menuClick(recid, event); + } + } + ); + } + // cancel event + if (event.preventDefault) event.preventDefault(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, + + menuClick: function (recid, event) { + var obj = this; + // event before + var edata = obj.trigger({ + phase: 'before', type: 'menuClick', target: obj.name, + originalEvent: event.originalEvent, menuEvent: event, + recid: recid, menuIndex: event.index, menuItem: event.item + }); + if (edata.isCancelled === true) return; + // default action + // -- empty + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, + + toggle: function (recid) { + var rec = this.get(recid); + rec.w2ui = rec.w2ui || {}; + if (rec.w2ui.expanded === true) return this.collapse(recid); else return this.expand(recid); + }, + + expand: function (recid) { + var obj = this; + var ind = this.get(recid, true); + var rec = this.records[ind]; + rec.w2ui = rec.w2ui || {}; + var id = w2utils.escapeId(recid); + var children = rec.w2ui.children; + if (Array.isArray(children)) { + if (rec.w2ui.expanded === true || children.length === 0) return false; // already shown + var edata = this.trigger({ phase: 'before', type: 'expand', target: this.name, recid: recid }); + if (edata.isCancelled === true) return false; + rec.w2ui.expanded = true; + children.forEach(function (child) { + child.w2ui = child.w2ui || {}; + child.w2ui.parent_recid = rec.recid; + if (child.w2ui.children == null) child.w2ui.children = []; + }); + this.records.splice.apply(this.records, [ind + 1, 0].concat(children)); + this.total += children.length; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(true, true); + if (this.searchData.length > 0) { + this.localSearch(true); + } + } + this.refresh(); + this.trigger($.extend(edata, { phase: 'after' })); + } else { + if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0 || this.show.expandColumn !== true) return false; + if (rec.w2ui.expanded == 'none') return false; + // insert expand row + $('#grid_'+ this.name +'_rec_'+ id).after( + ''+ + ' '+ + '
'+ + ' '+ + ' '+ + ''); + + $('#grid_'+ this.name +'_frec_'+ id).after( + ''+ + (this.show.lineNumbers ? '' : '') + + ' '+ + '
'+ + ' '+ + ''); + + // event before + var edata = this.trigger({ phase: 'before', type: 'expand', target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ recid +'_expanded', fbox_id: 'grid_'+ this.name +'_frec_'+ id +'_expanded' }); + if (edata.isCancelled === true) { + $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove(); + $('#grid_'+ this.name +'_frec_'+ id +'_expanded_row').remove(); + return false; + } + // expand column + var row1 = $(this.box).find('#grid_'+ this.name +'_rec_'+ recid +'_expanded'); + var row2 = $(this.box).find('#grid_'+ this.name +'_frec_'+ recid +'_expanded'); + var innerHeight = row1.find('> div:first-child').height(); + if (row1.height() < innerHeight) { + row1.css({ height: innerHeight + 'px' }); + } + if (row2.height() < innerHeight) { + row2.css({ height: innerHeight + 'px' }); + } + // default action + $('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded'); + $('#grid_'+ this.name +'_frec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded'); + // $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').show(); + $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('-'); + rec.w2ui.expanded = true; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + this.resizeRecords(); + } + return true; + }, + + collapse: function (recid) { + var obj = this; + var ind = this.get(recid, true); + var rec = this.records[ind]; + rec.w2ui = rec.w2ui || {}; + var id = w2utils.escapeId(recid); + var children = rec.w2ui.children; + if (Array.isArray(children)) { + if (rec.w2ui.expanded !== true) return false; // already hidden + var edata = this.trigger({ phase: 'before', type: 'collapse', target: this.name, recid: recid }); + if (edata.isCancelled === true) return false; + clearExpanded(rec); + var stops = []; + for (var r = rec; r != null; r = this.get(r.w2ui.parent_recid)) + stops.push(r.w2ui.parent_recid); + // stops contains 'undefined' plus the ID of all nodes in the path from 'rec' to the tree root + var start = ind + 1; + var end = start; + while (true) { + if (this.records.length <= end + 1 || this.records[end+1].w2ui == null || + stops.indexOf(this.records[end+1].w2ui.parent_recid) >= 0) { + break; + } + end++; + } + this.records.splice(start, end - start + 1); + this.total -= end - start + 1; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + if (this.searchData.length > 0) { + this.localSearch(true); + } + } + this.refresh(); + obj.trigger($.extend(edata, { phase: 'after' })); + } else { + if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length === 0 || this.show.expandColumn !== true) return false; + // event before + var edata = this.trigger({ phase: 'before', type: 'collapse', target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded', fbox_id: 'grid_'+ this.name +'_frec_'+ id +'_expanded' }); + if (edata.isCancelled === true) return false; + // default action + $('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded'); + $('#grid_'+ this.name +'_frec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded'); + $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+'); + $('#grid_'+ obj.name +'_rec_'+ id +'_expanded').css('height', '0px'); + $('#grid_'+ obj.name +'_frec_'+ id +'_expanded').css('height', '0px'); + setTimeout(function () { + $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row').remove(); + $('#grid_'+ obj.name +'_frec_'+ id +'_expanded_row').remove(); + rec.w2ui.expanded = false; + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + obj.resizeRecords(); + }, 300); + } + return true; + + function clearExpanded(rec) { + rec.w2ui.expanded = false; + for (var i = 0; i < rec.w2ui.children.length; i++) { + var subRec = rec.w2ui.children[i]; + if (subRec.w2ui.expanded) { + clearExpanded(subRec); + } + } + } + }, + + sort: function (field, direction, multiField) { // if no params - clears sort + // event before + var edata = this.trigger({ phase: 'before', type: 'sort', target: this.name, field: field, direction: direction, multiField: multiField }); + if (edata.isCancelled === true) return; + // check if needed to quit + if (field != null) { + // default action + var sortIndex = this.sortData.length; + for (var s = 0; s < this.sortData.length; s++) { + if (this.sortData[s].field == field) { sortIndex = s; break; } + } + if (direction == null) { + if (this.sortData[sortIndex] == null) { + direction = 'asc'; + } else { + if(this.sortData[sortIndex].direction == null) { + this.sortData[sortIndex].direction = ''; + } + switch (this.sortData[sortIndex].direction.toLowerCase()) { + case 'asc' : direction = 'desc'; break; + case 'desc' : direction = 'asc'; break; + default : direction = 'asc'; break; + } + } + } + if (this.multiSort === false) { this.sortData = []; sortIndex = 0; } + if (multiField != true) { this.sortData = []; sortIndex = 0; } + // set new sort + if (this.sortData[sortIndex] == null) this.sortData[sortIndex] = {}; + this.sortData[sortIndex].field = field; + this.sortData[sortIndex].direction = direction; + } else { + this.sortData = []; + } + // if local + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(true, true); + if (this.searchData.length > 0) this.localSearch(true); + // reset vertical scroll + this.last.scrollTop = 0; + $('#grid_'+ this.name +'_records').prop('scrollTop', 0); + // event after + this.trigger($.extend(edata, { phase: 'after', direction: direction })); + this.refresh(); + } else { + // event after + this.trigger($.extend(edata, { phase: 'after', direction: direction })); + this.last.xhr_offset = 0; + this.reload(); + } + }, + + copy: function (flag, oEvent) { + if ($.isPlainObject(flag)) { + // event after + this.trigger($.extend(flag, { phase: 'after' })); + return flag.text; + } + // generate text to copy + var sel = this.getSelection(); + if (sel.length === 0) return ''; + var text = ''; + if (typeof sel[0] == 'object') { // cell copy + // find min/max column + var minCol = sel[0].column; + var maxCol = sel[0].column; + var recs = []; + for (var s = 0; s < sel.length; s++) { + if (sel[s].column < minCol) minCol = sel[s].column; + if (sel[s].column > maxCol) maxCol = sel[s].column; + if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index); + } + recs.sort(function(a, b) { return a-b; }); // sort function must be for numerical sort + for (var r = 0 ; r < recs.length; r++) { + var ind = recs[r]; + for (var c = minCol; c <= maxCol; c++) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += this.getCellCopy(ind, c) + '\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + } + } else { // row copy + // copy headers + for (var c = 0; c < this.columns.length; c++) { + var col = this.columns[c]; + if (col.hidden === true) continue; + var colName = (col.text ? col.text : col.field); + if (col.text && col.text.length < 3 && col.tooltip) colName = col.tooltip; // if column name is less then 3 char and there is tooltip - use it + text += '"' + w2utils.stripTags(colName) + '"\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + // copy selected text + for (var s = 0; s < sel.length; s++) { + var ind = this.get(sel[s], true); + for (var c = 0; c < this.columns.length; c++) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += '"' + this.getCellCopy(ind, c) + '"\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + } + } + text = text.substr(0, text.length - 1); + + // if called without params + if (flag == null) { + // before event + var edata = this.trigger({ phase: 'before', type: 'copy', target: this.name, text: text, + cut: (oEvent.keyCode == 88 ? true : false), originalEvent: oEvent }); + if (edata.isCancelled === true) return ''; + text = edata.text; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return text; + } else if (flag === false) { // only before event + // before event + var edata = this.trigger({ phase: 'before', type: 'copy', target: this.name, text: text, + cut: (oEvent.keyCode == 88 ? true : false), originalEvent: oEvent }); + if (edata.isCancelled === true) return ''; + text = edata.text; + return edata; + } + }, + + /** + * Gets value to be copied to the clipboard + * @param ind index of the record + * @param col_ind index of the column + * @returns the displayed value of the field's record associated with the cell + */ + getCellCopy: function(ind, col_ind) { + return w2utils.stripTags(this.getCellHTML(ind, col_ind)); + }, + + paste: function (text) { + var sel = this.getSelection(); + var ind = this.get(sel[0].recid, true); + var col = sel[0].column; + // before event + var edata = this.trigger({ phase: 'before', type: 'paste', target: this.name, text: text, index: ind, column: col }); + if (edata.isCancelled === true) return; + text = edata.text; + // default action + if (this.selectType == 'row' || sel.length === 0) { + console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.'); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return; + } + var newSel = []; + var text = text.split('\n'); + for (var t = 0; t < text.length; t++) { + var tmp = text[t].split('\t'); + var cnt = 0; + var rec = this.records[ind]; + var cols = []; + if (rec == null) continue; + for (var dt = 0; dt < tmp.length; dt++) { + if (!this.columns[col + cnt]) continue; + this.setCellPaste(rec, col + cnt, tmp[dt]); + cols.push(col + cnt); + cnt++; + } + for (var c = 0; c < cols.length; c++) newSel.push({ recid: rec.recid, column: cols[c] }); + ind++; + } + this.selectNone(); + this.select(newSel); + this.refresh(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + /** + * Sets record field using clipboard text + * @param rec record + * @param col_ind column index + * @param paste sub part of the pasted text + */ + setCellPaste: function(rec, col_ind, paste) { + var field = this.columns[col_ind].field; + rec.w2ui = rec.w2ui || {}; + rec.w2ui.changes = rec.w2ui.changes || {}; + rec.w2ui.changes[field] = paste; + }, + + // ================================================== + // --- Common functions + + resize: function () { + var obj = this; + var time = (new Date()).getTime(); + // make sure the box is right + if (!this.box || $(this.box).attr('name') != this.name) return; + // determine new width and height + $(this.box).find('> div.w2ui-grid-box') + .css('width', $(this.box).width()) + .css('height', $(this.box).height()); + // event before + var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (edata.isCancelled === true) return; + // resize + obj.resizeBoxes(); + obj.resizeRecords(); + if (obj.toolbar && obj.toolbar.resize) obj.toolbar.resize(); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + update: function (cells) { + var time = (new Date()).getTime(); + if (this.box == null) return 0; + if (cells == null) { + for (var index = this.last.range_start - 1; index <= this.last.range_end - 1; index++) { + if (index < 0) continue; + var rec = this.records[index] || {}; + if (!rec.w2ui) rec.w2ui = {}; + for (var column = 0; column < this.columns.length; column++) { + var row = $(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)); + var cell = $(this.box).find('#grid_'+ this.name + '_data_'+ index +'_'+ column); + cell.replaceWith(this.getCellHTML(index, column, false)); + cell = $(this.box).find('#grid_'+ this.name + '_data_'+ index +'_'+ column); // need to reselect as it was replaced + // assign style + if (rec.w2ui.style != null && !$.isEmptyObject(rec.w2ui.style)) { + if (typeof rec.w2ui.style == 'string') { + row.attr('style', rec.w2ui.style); + } + if ($.isPlainObject(rec.w2ui.style) && typeof rec.w2ui.style[column] == 'string') { + cell.attr('style', rec.w2ui.style[column]); + } + } else { + cell.attr('style', ''); + } + // assign class + if (rec.w2ui.class != null && !$.isEmptyObject(rec.w2ui.class)) { + if (typeof rec.w2ui.class == 'string') { + row.addClass(rec.w2ui.class); + } + if ($.isPlainObject(rec.w2ui.class) && typeof rec.w2ui.class[column] == 'string') { + cell.addClass(rec.w2ui.class[column]); + } + } + } + } + + } else { + + for (var i = 0; i < cells.length; i++) { + var index = cells[i].index; + var column = cells[i].column; + if (index < 0) continue; + if (index == null || column == null) { + console.log('ERROR: Wrong argument for grid.update(cells), cells should be [{ index: X, column: Y }, ...]'); + continue; + } + var rec = this.records[index] || {}; + var row = $(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)); + var cell = $(this.box).find('#grid_'+ this.name + '_data_'+ index +'_'+ column); + if (!rec.w2ui) rec.w2ui = {}; + cell.replaceWith(this.getCellHTML(index, column, false)); + cell = $(this.box).find('#grid_'+ this.name + '_data_'+ index +'_'+ column); // need to reselect as it was replaced + // assign style + if (rec.w2ui.style != null && !$.isEmptyObject(rec.w2ui.style)) { + if (typeof rec.w2ui.style == 'string') { + row.attr('style', rec.w2ui.style); + } + if ($.isPlainObject(rec.w2ui.style) && typeof rec.w2ui.style[column] == 'string') { + cell.attr('style', rec.w2ui.style[column]); + } + } else { + cell.attr('style', ''); + } + // assign class + if (rec.w2ui.class != null && !$.isEmptyObject(rec.w2ui.class)) { + if (typeof rec.w2ui.class == 'string') { + row.addClass(rec.w2ui.class); + } + if ($.isPlainObject(rec.w2ui.class) && typeof rec.w2ui.class[column] == 'string') { + cell.addClass(rec.w2ui.class[column]); + } + } + } + } + return (new Date()).getTime() - time; + }, + + refreshCell: function (recid, field) { + var index = this.get(recid, true); + var col_ind = this.getColumn(field, true); + var isSummary = (this.records[index] && this.records[index].recid == recid ? false : true); + var cell = $(this.box).find((isSummary ? '.w2ui-grid-summary ' : '') + '#grid_'+ this.name + '_data_'+ index +'_'+ col_ind); + if (cell.length == 0) return false; + // set cell html and changed flag + cell.replaceWith(this.getCellHTML(index, col_ind, isSummary)); + }, + + refreshRow: function (recid, ind) { + var tr1 = $(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)); + var tr2 = $(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (tr1.length > 0) { + if (ind == null) ind = this.get(recid, true); + var line = tr1.attr('line'); + var isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true); + // if it is searched, find index in search array + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.searchData.length > 0 && !url) for (var s = 0; s < this.last.searchIds.length; s++) if (this.last.searchIds[s] == ind) ind = s; + var rec_html = this.getRecordHTML(ind, line, isSummary); + $(tr1).replaceWith(rec_html[0]); + $(tr2).replaceWith(rec_html[1]); + // apply style to row if it was changed in render functions + var st = (this.records[ind].w2ui ? this.records[ind].w2ui.style : ''); + if (typeof st == 'string') { + var tr1 = $(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)); + var tr2 = $(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + tr1.attr('custom_style', st); + tr2.attr('custom_style', st); + if (tr1.hasClass('w2ui-selected')) { + st = st.replace('background-color', 'none'); + } + tr1[0].style.cssText = 'height: '+ this.recordHeight + 'px;' + st; + tr2[0].style.cssText = 'height: '+ this.recordHeight + 'px;' + st; + } + if (isSummary) { + this.resize(); + } + } + }, + + refresh: function () { + var obj = this; + var time = (new Date()).getTime(); + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.total <= 0 && !url && this.searchData.length === 0) { + this.total = this.records.length; + } + this.toolbar.disable('w2ui-edit', 'w2ui-delete'); + if (!this.box) return; + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'refresh' }); + if (edata.isCancelled === true) return; + // -- header + if (this.show.header) { + $('#grid_'+ this.name +'_header').html(this.header +' ').show(); + } else { + $('#grid_'+ this.name +'_header').hide(); + } + // -- toolbar + if (this.show.toolbar) { + // if select-collumn is checked - no toolbar refresh + if (this.toolbar && this.toolbar.get('w2ui-column-on-off') && this.toolbar.get('w2ui-column-on-off').checked) { + // no action + } else { + $('#grid_'+ this.name +'_toolbar').show(); + // refresh toolbar all but search field + if (typeof this.toolbar == 'object') { + var tmp = this.toolbar.items; + for (var t = 0; t < tmp.length; t++) { + if (tmp[t].id == 'w2ui-search' || tmp[t].type == 'break') continue; + this.toolbar.refresh(tmp[t].id); + } + } + } + } else { + $('#grid_'+ this.name +'_toolbar').hide(); + } + // -- make sure search is closed + this.searchClose(); + // search placeholder + var el = $('#grid_'+ obj.name +'_search_all'); + if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { + this.last.field = this.searches[0].field; + this.last.label = this.searches[0].label; + } + for (var s = 0; s < this.searches.length; s++) { + if (this.searches[s].field == this.last.field) this.last.label = this.searches[s].label; + } + if (this.last.multi) { + el.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']'); + el.w2field('clear'); + } else { + el.attr('placeholder', w2utils.lang(this.last.label)); + } + if (el.val() != this.last.search) { + var val = this.last.search; + var tmp = el.data('w2field'); + if (tmp) val = tmp.format(val); + el.val(val); + } + + // -- body + obj.refreshBody(); + + // -- footer + if (this.show.footer) { + $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()).show(); + } else { + $('#grid_'+ this.name +'_footer').hide(); + } + // show/hide clear search link + var $clear = $('#grid_'+ this.name +'_searchClear'); + $clear.hide(); + this.searchData.some(function (item) { + var tmp = obj.getSearch(item.field); + if (obj.last.multi || (tmp && !tmp.hidden && ['list', 'enum'].indexOf(tmp.type) == -1)) { + $clear.show(); + return true; + } + }); + // all selected? + var sel = this.last.selection, + areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length); + if (areAllSelected || areAllSearchedSelected) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + // show number of selected + this.status(); + // collapse all records + var rows = obj.find({ 'w2ui.expanded': true }, true); + for (var r = 0; r < rows.length; r++) { + var tmp = obj.records[rows[r]].w2ui; + if (tmp && !Array.isArray(tmp.children)) { + tmp.expanded = false; + } + } + // mark selection + if (obj.markSearch) { + setTimeout(function () { + // mark all search strings + var search = []; + for (var s = 0; s < obj.searchData.length; s++) { + var sdata = obj.searchData[s]; + var fld = obj.getSearch(sdata.field); + if (!fld || fld.hidden) continue; + var ind = obj.getColumn(sdata.field, true); + search.push({ field: sdata.field, search: sdata.value, col: ind }); + } + if (search.length > 0) { + search.forEach(function (item) { + $(obj.box).find('td[col="'+ item.col +'"]').not('.w2ui-head').w2marker(item.search); + }); + } + }, 50); + } + // enable/disable toolbar search button + if (this.show.toolbarSave) { + if (this.getChanges().length > 0) this.toolbar.enable('w2ui-save'); else this.toolbar.disable('w2ui-save'); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + obj.resize(); + obj.addRange('selection'); + setTimeout(function () { // allow to render first + obj.resize(); // needed for horizontal scroll to show (do not remove) + obj.scroll(); + }, 1); + + if ( obj.reorderColumns && !obj.last.columnDrag ) { + obj.last.columnDrag = obj.initColumnDrag(); + } else if ( !obj.reorderColumns && obj.last.columnDrag ) { + obj.last.columnDrag.remove(); + } + return (new Date()).getTime() - time; + }, + + refreshBody: function () { + // -- separate summary + var obj = this, + tmp = this.find({ 'w2ui.summary': true }, true); + if (tmp.length > 0) { + for (var t = 0; t < tmp.length; t++) this.summary.push(this.records[tmp[t]]); + for (var t = tmp.length-1; t >= 0; t--) this.records.splice(tmp[t], 1); + } + + // -- body + this.scroll(); // need to calculate virtual scolling for columns + var recHTML = this.getRecordsHTML(); + var colHTML = this.getColumnsHTML(); + var bodyHTML = + '
'+ + recHTML[0] + + '
'+ + '
' + + recHTML[1] + + '
'+ + '
'+ + // Columns need to be after to be able to overlap + '
'+ + ' '+ colHTML[0] +'
'+ + '
'+ + '
'+ + ' '+ colHTML[1] +'
'+ + '
'; + + var gridBody = $('#grid_'+ this.name +'_body', obj.box).html(bodyHTML), + records = $('#grid_'+ this.name +'_records', obj.box); + var frecords = $('#grid_'+ this.name +'_frecords', obj.box); + var self = this; + if (this.selectType == 'row') { + records + .on('mouseover mouseout', 'tr', function(event) { + $('#grid_'+ self.name +'_frec_' + w2utils.escapeId($(this).attr('recid'))).toggleClass('w2ui-record-hover', event.type == 'mouseover') + }) + frecords + .on('mouseover mouseout', 'tr', function(event) { + $('#grid_'+ self.name +'_rec_' + w2utils.escapeId($(this).attr('recid'))).toggleClass('w2ui-record-hover', event.type == 'mouseover') + }) + } + if(w2utils.isIOS) + records.add(frecords) + .on('click', 'tr', function(ev) { + self.dblClick($(this).attr('recid'), ev); + }) + else + records.add(frecords) + .on('click', 'tr', function(ev) { + self.click($(this).attr('recid'), ev); + }) + .on('contextmenu', 'tr', function(ev) { + self.contextMenu($(this).attr('recid'), null, ev); + }) + + // enable scrolling on frozen records, + gridBody.data('scrolldata', { lastTime: 0, lastDelta: 0, time: 0 }) + .find('.w2ui-grid-frecords') + .on("mousewheel DOMMouseScroll ", function(event) { + event.preventDefault(); + + var e = event.originalEvent, + scrolldata = gridBody.data('scrolldata'), + recordsContainer = $(this).siblings('.w2ui-grid-records').addBack().filter('.w2ui-grid-records'), + amount = typeof e.wheelDelta != null ? e.wheelDelta * -1 / 120 : (e.detail || e.deltaY) / 3, // normalizing scroll speed + newScrollTop = recordsContainer.scrollTop(); + + scrolldata.time = +new Date(); + + if (scrolldata.lastTime < scrolldata.time - 150) { + scrolldata.lastDelta = 0; + } + + scrolldata.lastTime = scrolldata.time; + scrolldata.lastDelta += amount; + + if (Math.abs(scrolldata.lastDelta) < 1) { + amount = 0; + } else { + amount = Math.round(scrolldata.lastDelta); + } + gridBody.data('scrolldata', scrolldata); + + // make scroll amount dependent on visible rows + amount *= (Math.round(records.height() / obj.recordHeight) - 1) * obj.recordHeight / 4; + recordsContainer.stop().animate({ 'scrollTop': newScrollTop + amount }, 250, 'linear'); + }); + + if (this.records.length === 0 && this.msgEmpty) { + $('#grid_'+ this.name +'_body') + .append('
'+ this.msgEmpty +'
'); + } else if ($('#grid_'+ this.name +'_empty_msg').length > 0) { + $('#grid_'+ this.name +'_empty_msg').remove(); + } + // show summary records + if (this.summary.length > 0) { + var sumHTML = this.getSummaryHTML(); + $('#grid_'+ this.name +'_fsummary').html(sumHTML[0]).show(); + $('#grid_'+ this.name +'_summary').html(sumHTML[1]).show(); + } else { + $('#grid_'+ this.name +'_fsummary').hide(); + $('#grid_'+ this.name +'_summary').hide(); + } + }, + + render: function (box) { + var obj = this; + var time = (new Date()).getTime(); + if (box != null) { + if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid w2ui-inactive') + .html(''); + } + this.box = box; + } + if (!this.box) return; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'render', box: box }); + if (edata.isCancelled === true) return; + // reset needed if grid existed + this.reset(true); + // --- default search field + if (!this.last.field) { + if (!this.multiSearch || !this.show.searchAll) { + var tmp = 0; + while (tmp < this.searches.length && (this.searches[tmp].hidden || this.searches[tmp].simple === false)) tmp++; + if (tmp >= this.searches.length) { + // all searches are hidden + this.last.field = ''; + this.last.label = ''; + } else { + this.last.field = this.searches[tmp].field; + this.last.label = this.searches[tmp].label; + } + } else { + this.last.field = 'all'; + this.last.label = w2utils.lang('All Fields'); + } + } + // insert elements + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + ' '+ + ' '+ // readonly needed on android not to open keyboard + '
'); + if (this.selectType != 'row') $(this.box).addClass('w2ui-ss'); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // init toolbar + this.initToolbar(); + if (this.toolbar != null) this.toolbar.render($('#grid_'+ this.name +'_toolbar')[0]); + // reinit search_all + if (this.last.field && this.last.field != 'all') { + var sd = this.searchData; + setTimeout(function () { obj.initAllField(obj.last.field, (sd.length == 1 ? sd[0].value : null)); }, 1); + } + // init footer + $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()); + // refresh + if (!this.last.state) this.last.state = this.stateSave(true); // initial default state + this.stateRestore(); + if (url) { this.clear(); this.refresh(); } // show empty grid (need it) - should it be only for remote data source + // if hidden searches - apply it + var hasHiddenSearches = false; + for (var i = 0; i < this.searches.length; i++) { + if (this.searches[i].hidden) { hasHiddenSearches = true; break; } + } + if (hasHiddenSearches) { + this.searchReset(false); // will call reload + if (!url) setTimeout(function () { obj.searchReset(); }, 1); + } else { + this.reload(); + } + // focus + $(this.box).find('#grid_'+ this.name + '_focus') + .on('focus', function (event) { + clearTimeout(obj.last.kbd_timer); + if (!obj.hasFocus) obj.focus(); + }) + .on('blur', function (event) { + clearTimeout(obj.last.kbd_timer); + obj.last.kbd_timer = setTimeout(function () { + if (obj.hasFocus) { obj.blur(); } + }, 100); // need this timer to be 100 ms + }) + .on('paste', function (event) { + var cd = (event.originalEvent.clipboardData ? event.originalEvent.clipboardData : null) + if (cd && cd.types && cd.types.indexOf('text/plain') != -1) { + event.preventDefault() + var text = cd.getData('text/plain'); + if (text.indexOf('\r') != -1 && text.indexOf('\n') == -1) { + text = text.replace(/\r/g, '\n'); + } + w2ui[obj.name].paste(text); + } else { + // for older browsers + var el = this; + setTimeout(function () { w2ui[obj.name].paste(el.value); el.value = ''; }, 1) + } + }) + .on('keydown', function (event) { + w2ui[obj.name].keydown.call(w2ui[obj.name], event); + }); + // init mouse events for mouse selection + var edataCol; // event for column select + $(this.box).off('mousedown').on('mousedown', mouseStart); + this.updateToolbar() + // event after + this.trigger($.extend(edata, { phase: 'after' })); + // attach to resize event + if ($('.w2ui-layout').length === 0) { // if there is layout, it will send a resize event + $(window) + .off('resize.w2ui-'+ obj.name) + .on('resize.w2ui-'+ obj.name, function (event) { + if (w2ui[obj.name] == null) { + $(window).off('resize.w2ui-'+ obj.name) + } else { + w2ui[obj.name].resize(); + } + }); + } + return (new Date()).getTime() - time; + + function mouseStart (event) { + if (event.which != 1) return; // if not left mouse button + // restore css user-select + if (obj.last.userSelect == 'text') { + delete obj.last.userSelect; + $(obj.box).find('.w2ui-grid-body').css(w2utils.cssPrefix('user-select', 'none')); + } + // regular record select + if (obj.selectType == 'row' && ($(event.target).parents().hasClass('w2ui-head') || $(event.target).hasClass('w2ui-head'))) return; + if (obj.last.move && obj.last.move.type == 'expand') return; + // if altKey - alow text selection + if (event.altKey) { + $(obj.box).find('.w2ui-grid-body').css(w2utils.cssPrefix('user-select', 'text')); + obj.selectNone(); + obj.last.move = { type: 'text-select' }; + obj.last.userSelect = 'text'; + } else { + var tmp = event.target; + var pos = { + x: event.offsetX - 10, + y: event.offsetY - 10 + } + var tmps = false; + while (tmp) { + if (tmp.classList && tmp.classList.contains('w2ui-grid')) break; + if (tmp.tagName && tmp.tagName.toUpperCase() == 'TD') tmps = true; + if (tmp.tagName && tmp.tagName.toUpperCase() != 'TR' && tmps == true) { + pos.x += tmp.offsetLeft; + pos.y += tmp.offsetTop; + } + tmp = tmp.parentNode; + } + + obj.last.move = { + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + focusX : pos.x, + focusY : pos.y, + recid : $(event.target).parents('tr').attr('recid'), + column : parseInt(event.target.tagName.toUpperCase() == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')), + type : 'select', + ghost : false, + start : true + }; + if (obj.last.move.recid == null) obj.last.move.type = 'select-column'; + // set focus to grid + var target = event.target; + var $input = $(obj.box).find('#grid_'+ obj.name + '_focus'); + // move input next to cursor so screen does not jump + if (obj.last.move) { + var sLeft = obj.last.move.focusX; + var sTop = obj.last.move.focusY; + var $owner = $(target).parents('table').parent(); + if ($owner.hasClass('w2ui-grid-records') || $owner.hasClass('w2ui-grid-frecords') + || $owner.hasClass('w2ui-grid-columns') || $owner.hasClass('w2ui-grid-fcolumns') + || $owner.hasClass('w2ui-grid-summary')) { + sLeft = obj.last.move.focusX - $(obj.box).find('#grid_'+ obj.name +'_records').scrollLeft(); + sTop = obj.last.move.focusY - $(obj.box).find('#grid_'+ obj.name +'_records').scrollTop(); + } + if ($(target).hasClass('w2ui-grid-footer') || $(target).parents('div.w2ui-grid-footer').length > 0) { + sTop = $(obj.box).find('#grid_'+ obj.name +'_footer').position().top; + } + // if clicked on toolbar + if ($owner.hasClass('w2ui-scroll-wrapper') && $owner.parent().hasClass('w2ui-toolbar')) { + sLeft = obj.last.move.focusX - $owner.scrollLeft(); + } + $input.css({ + left: sLeft - 10, + top : sTop + }); + } + // if toolbar input is clicked + setTimeout(function () { + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(target.tagName.toUpperCase()) != -1) { + $(target).focus(); + } else { + if (!$input.is(':focus')) $input.focus(); + } + }, 50); + // disable click select for this condition + if (!obj.multiSelect && !obj.reorderRows && obj.last.move.type == 'drag') { + delete obj.last.move; + } + } + if (obj.reorderRows == true) { + var el = event.target; + if (el.tagName.toUpperCase() != 'TD') el = $(el).parents('td')[0]; + if ($(el).hasClass('w2ui-col-number') || $(el).hasClass('w2ui-col-order')) { + obj.selectNone(); + obj.last.move.reorder = true; + // supress hover + var eColor = $(obj.box).find('.w2ui-even.w2ui-empty-record').css('background-color'); + var oColor = $(obj.box).find('.w2ui-odd.w2ui-empty-record').css('background-color'); + $(obj.box).find('.w2ui-even td').not('.w2ui-col-number').css('background-color', eColor); + $(obj.box).find('.w2ui-odd td').not('.w2ui-col-number').css('background-color', oColor); + // display empty record and ghost record + var mv = obj.last.move; + if (!mv.ghost) { + var row = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var tmp = row.parents('table').find('tr:first-child').clone(); + mv.offsetY = event.offsetY; + mv.from = mv.recid; + mv.pos = row.position(); + mv.ghost = $(row).clone(true); + mv.ghost.removeAttr('id'); + row.find('td').remove(); + row.append('
'); + var recs = $(obj.box).find('.w2ui-grid-records'); + recs.append('
'); + recs.append('
'); + $('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost); + } + var ghost = $('#grid_'+ obj.name + '_ghost'); + var recs = $(obj.box).find('.w2ui-grid-records'); + ghost.css({ + top : mv.pos.top + recs.scrollTop(), + left : mv.pos.left, + "border-top" : '1px solid #aaa', + "border-bottom" : '1px solid #aaa' + }); + } else { + obj.last.move.reorder = false; + } + } + $(document) + .on('mousemove.w2ui-' + obj.name, mouseMove) + .on('mouseup.w2ui-' + obj.name, mouseStop); + // needed when grid grids are nested, see issue #1275 + event.stopPropagation(); + } + + function mouseMove (event) { + var mv = obj.last.move; + if (!mv || ['select', 'select-column'].indexOf(mv.type) == -1) return; + mv.divX = (event.screenX - mv.x); + mv.divY = (event.screenY - mv.y); + if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return; // only if moved more then 1px + obj.last.cancelClick = true; + if (obj.reorderRows == true && obj.last.move.reorder) { + var recs = $(obj.box).find('.w2ui-grid-records'); + var tmp = $(event.target).parents('tr'); + var recid = tmp.attr('recid'); + if (recid == '-none-') recid = 'bottom'; + if (recid != mv.from) { + var row1 = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var row2 = $('#grid_'+ obj.name + '_rec_'+ recid); + $(obj.box).find('.insert-before'); + row2.addClass('insert-before'); + // MOVABLE GHOST + // if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); + mv.lastY = event.screenY; + mv.to = recid; + // line to insert before + var pos = row2.position() + var ghost_line = $('#grid_'+ obj.name + '_ghost_line'); + if (pos) { + ghost_line.css({ + top : pos.top + recs.scrollTop(), + left : mv.pos.left, + 'border-top': '2px solid #769EFC' + }); + } else { + ghost_line.css({ + 'border-top': '2px solid transparent' + }); + } + } + var ghost = $('#grid_'+ obj.name + '_ghost'); + ghost.css({ + top : mv.pos.top + mv.divY + recs.scrollTop(), + left : mv.pos.left + }); + return; + } + if (mv.start && mv.recid) { + obj.selectNone(); + mv.start = false; + } + var newSel= []; + var recid = (event.target.tagName.toUpperCase() == 'TR' ? $(event.target).attr('recid') : $(event.target).parents('tr').attr('recid')); + if (recid == null) { + // select by dragging columns + if (obj.selectType == 'row') return; + if (obj.last.move && obj.last.move.type == 'select') return; + var col = parseInt($(event.target).parents('td').attr('col')); + if (isNaN(col)) { + obj.removeRange('column-selection'); + $(obj.box).find('.w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header').removeClass('w2ui-col-selected'); + $(obj.box).find('.w2ui-col-number').removeClass('w2ui-row-selected'); + delete mv.colRange; + } else { + // add all columns in between + var newRange = col + '-' + col; + if (mv.column < col) newRange = mv.column + '-' + col; + if (mv.column > col) newRange = col + '-' + mv.column; + // array of selected columns + var cols = []; + var tmp = newRange.split('-'); + for (var ii = parseInt(tmp[0]); ii <= parseInt(tmp[1]); ii++) { + cols.push(ii) + } + if (mv.colRange != newRange) { + edataCol = obj.trigger({ phase: 'before', type: 'columnSelect', target: obj.name, columns: cols, isCancelled: false }); // initial isCancelled + if (edataCol.isCancelled !== true) { + if (mv.colRange == null) obj.selectNone(); + // highlight columns + var tmp = newRange.split('-'); + $(obj.box).find('.w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header').removeClass('w2ui-col-selected'); + for (var j = parseInt(tmp[0]); j <= parseInt(tmp[1]); j++) { + $(obj.box).find('#grid_'+ obj.name +'_column_' + j + ' .w2ui-col-header').addClass('w2ui-col-selected'); + } + $(obj.box).find('.w2ui-col-number').not('.w2ui-head').addClass('w2ui-row-selected'); + // show new range + mv.colRange = newRange; + obj.removeRange('column-selection'); + obj.addRange({ + name : 'column-selection', + range : [{ recid: obj.records[0].recid, column: tmp[0] }, { recid: obj.records[obj.records.length-1].recid, column: tmp[1] }], + style : 'background-color: rgba(90, 145, 234, 0.1)' + }); + } + } + } + + } else { // regular selection + + var ind1 = obj.get(mv.recid, true); + // this happens when selection is started on summary row + if (ind1 == null || (obj.records[ind1] && obj.records[ind1].recid != mv.recid)) return; + var ind2 = obj.get(recid, true); + // this happens when selection is extended into summary row (a good place to implement scrolling) + if (ind2 == null) return; + var col1 = parseInt(mv.column); + var col2 = parseInt(event.target.tagName.toUpperCase() == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')); + if (isNaN(col1) && isNaN(col2)) { // line number select entire record + col1 = 0; + col2 = obj.columns.length-1; + } + if (ind1 > ind2) { var tmp = ind1; ind1 = ind2; ind2 = tmp; } + // check if need to refresh + var tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2; + if (mv.range == tmp) return; + mv.range = tmp; + for (var i = ind1; i <= ind2; i++) { + if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue; + if (obj.selectType != 'row') { + if (col1 > col2) { var tmp = col1; col1 = col2; col2 = tmp; } + var tmp = []; + for (var c = col1; c <= col2; c++) { + if (obj.columns[c].hidden) continue; + newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }); + } + } else { + newSel.push(obj.records[i].recid); + } + } + if (obj.selectType != 'row') { + var sel = obj.getSelection(); + // add more items + var tmp = []; + for (var ns = 0; ns < newSel.length; ns++) { + var flag = false; + for (var s = 0; s < sel.length; s++) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; + if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }); + } + obj.select(tmp); + // remove items + var tmp = []; + for (var s = 0; s < sel.length; s++) { + var flag = false; + for (var ns = 0; ns < newSel.length; ns++) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; + if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }); + } + obj.unselect(tmp); + } else { + if (obj.multiSelect) { + var sel = obj.getSelection(); + for (var ns = 0; ns < newSel.length; ns++) { + if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]); // add more items + } + for (var s = 0; s < sel.length; s++) { + if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]); // remove items + } + } + } + } + } + + function mouseStop (event) { + var mv = obj.last.move; + setTimeout(function () { delete obj.last.cancelClick; }, 1); + if ($(event.target).parents().hasClass('.w2ui-head') || $(event.target).hasClass('.w2ui-head')) return; + if (mv && ['select', 'select-column'].indexOf(mv.type) != -1) { + if (mv.colRange != null && edataCol.isCancelled !== true) { + var tmp = mv.colRange.split('-'); + var sel = []; + for (var i = 0; i < obj.records.length; i++) { + var cols = [] + for (var j = parseInt(tmp[0]); j <= parseInt(tmp[1]); j++) cols.push(j); + sel.push({ recid: obj.records[i].recid, column: cols }); + } + obj.removeRange('column-selection'); + obj.trigger($.extend(edataCol, { phase: 'after' })); + obj.select(sel); + } + if (obj.reorderRows == true && obj.last.move.reorder) { + // event + var edata = obj.trigger({ phase: 'before', target: obj.name, type: 'reorderRow', recid: mv.from, moveAfter: mv.to }); + if (edata.isCancelled === true) { + $('#grid_'+ obj.name + '_ghost').remove(); + $('#grid_'+ obj.name + '_ghost_line').remove(); + obj.refresh(); + delete obj.last.move; + return; + } + // default behavior + var ind1 = obj.get(mv.from, true); + var ind2 = obj.get(mv.to, true); + if (mv.to == 'bottom') ind2 = obj.records.length; // end of list + var tmp = obj.records[ind1]; + // swap records + if (ind1 != null && ind2 != null) { + obj.records.splice(ind1, 1); + if (ind1 > ind2) { + obj.records.splice(ind2, 0, tmp); + } else { + obj.records.splice(ind2 - 1, 0, tmp); + } + } + $('#grid_'+ obj.name + '_ghost').remove(); + $('#grid_'+ obj.name + '_ghost_line').remove(); + obj.refresh(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + } + delete obj.last.move; + $(document).off('.w2ui-' + obj.name); + } + }, + + destroy: function () { + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'destroy' }); + if (edata.isCancelled === true) return; + // remove all events + $(this.box).off(); + // clean up + if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy(); + if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid w2ui-inactive') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + // =========================================== + // --- Internal Functions + + initColumnOnOff: function () { + if (!this.show.toolbarColumns) return; + var obj = this; + // line number + var col_html = '
'+ + ''+ + ''+ + ' '+ + ' '+ + ''; + // columns + for (var c = 0; c < this.columns.length; c++) { + var col = this.columns[c]; + var tmp = this.columns[c].text; + if (col.hideable === false) continue; + if (!tmp && this.columns[c].tooltip) tmp = this.columns[c].tooltip; + if (!tmp) tmp = '- column '+ (parseInt(c) + 1) +' -'; + col_html += + ''+ + ' '+ + ' '+ + ''; + } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + // devider + if ((url && obj.show.skipRecords) || obj.show.saveRestoreState) { + col_html += ''; + } + // skip records + if (url && obj.show.skipRecords) { + col_html += + ''; + } + // save/restore state + if (obj.show.saveRestoreState) { + col_html += ''+ + ''; + } + col_html += "
'+ + ' '+ + ' '+ + ' '+ + '
'+ + ' '+ + ' '+ + ' '+ + '
'+ + '
'+ w2utils.lang('Skip') + + ' '+ w2utils.lang('Records')+ + '
'+ + '
'+ + '
'+ w2utils.lang('Save Grid State') + '
'+ + '
'+ + '
'+ w2utils.lang('Restore Default State') + '
'+ + '
"; + this.toolbar.get('w2ui-column-on-off').html = col_html; + }, + + /** + * + * @param box, grid object + * @returns {{remove: Function}} contains a closure around all events to ensure they are removed from the dom + */ + initColumnDrag: function ( box ) { + //throw error if using column groups + if ( this.columnGroups && this.columnGroups.length ) throw 'Draggable columns are not currently supported with column groups.'; + + var obj = this, + _dragData = {}; + _dragData.lastInt = null; + _dragData.pressed = false; + _dragData.timeout = null;_dragData.columnHead = null; + + //attach original event listener + $(obj.box).on('mousedown', dragColStart); + $(obj.box).on('mouseup', catchMouseup); + + function catchMouseup(){ + _dragData.pressed = false; + clearTimeout( _dragData.timeout ); + } + /** + * + * @param event, mousedown + * @returns {boolean} false, preventsDefault + */ + function dragColStart ( event ) { + if ( _dragData.timeout ) clearTimeout( _dragData.timeout ); + var self = this; + _dragData.pressed = true; + + _dragData.timeout = setTimeout(function(){ + // When dragging a column for reordering, a quick release and a secondary + // click may result in a bug where the column is ghosted to the screen, + // but can no longer be docked back into the header. It simply floats and you + // can no longer interact with it. + // The erronius event thats fired will have _dragData.numberPreColumnsPresent === 0 + // populated, wheras a valid event will not. + // if we see the erronius event, dont allow that second click to register, which results + // in the floating column remaining under the mouse's control. + if ( !_dragData.pressed || _dragData.numberPreColumnsPresent === 0 ) return; + + var edata, + columns, + selectedCol, + origColumn, + origColumnNumber, + invalidPreColumns = [ 'w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select' ], + invalidPostColumns = [ 'w2ui-head-last' ], + invalidColumns = invalidPreColumns.concat( invalidPostColumns ), + preColumnsSelector = '.w2ui-col-number, .w2ui-col-expand, .w2ui-col-select', + preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select'; + + // do nothing if it is not a header + if ( !$( event.originalEvent.target ).parents().hasClass( 'w2ui-head' ) ) return; + + // do nothing if it is an invalid column + for ( var i = 0, l = invalidColumns.length; i < l; i++ ){ + if ( $( event.originalEvent.target ).parents().hasClass( invalidColumns[ i ] ) ) return; + } + + _dragData.numberPreColumnsPresent = $( obj.box ).find( preColHeadersSelector ).length; + + //start event for drag start + _dragData.columnHead = origColumn = $( event.originalEvent.target ).parents( '.w2ui-head' ); + _dragData.originalPos = origColumnNumber = parseInt( origColumn.attr( 'col' ), 10); + edata = obj.trigger({ type: 'columnDragStart', phase: 'before', originalEvent: event, origColumnNumber: origColumnNumber, target: origColumn[0] }); + if ( edata.isCancelled === true ) return false; + + columns = _dragData.columns = $( obj.box ).find( '.w2ui-head:not(.w2ui-head-last)' ); + + //add events + $( document ).on( 'mouseup', dragColEnd ); + $( document ).on( 'mousemove', dragColOver ); + + //_dragData.columns.css({ overflow: 'visible' }).children( 'div' ).css({ overflow: 'visible' }); + + //configure and style ghost image + _dragData.ghost = $( self ).clone( true ); + + //hide other elements on ghost except the grid body + $( _dragData.ghost ).find( '[col]:not([col="' + _dragData.originalPos + '"]), .w2ui-toolbar, .w2ui-grid-header' ).remove(); + $( _dragData.ghost ).find( preColumnsSelector ).remove(); + $( _dragData.ghost ).find( '.w2ui-grid-body' ).css({ top: 0 }); + + selectedCol = $( _dragData.ghost ).find( '[col="' + _dragData.originalPos + '"]' ); + $( document.body ).append( _dragData.ghost ); + + $( _dragData.ghost ).css({ + width: 0, + height: 0, + margin: 0, + position: 'fixed', + zIndex: 999999, + opacity: 0 + }).addClass( '.w2ui-grid-ghost' ).animate({ + width: selectedCol.width(), + height: $(obj.box).find('.w2ui-grid-body:first').height(), + left : event.pageX, + top : event.pageY, + opacity: 0.8 + }, 0 ); + + //establish current offsets + _dragData.offsets = []; + for ( var i = 0, l = columns.length; i < l; i++ ) { + _dragData.offsets.push( $( columns[ i ] ).offset().left ); + } + + //conclude event + obj.trigger( $.extend( edata, { phase: 'after' } ) ); + }, 150 );//end timeout wrapper + } + + function dragColOver ( event ) { + if ( !_dragData.pressed ) return; + + var cursorX = event.originalEvent.pageX, + cursorY = event.originalEvent.pageY, + offsets = _dragData.offsets, + lastWidth = $( '.w2ui-head:not(.w2ui-head-last)' ).width(); + + _dragData.targetInt = Math.max(_dragData.numberPreColumnsPresent,targetIntersection( cursorX, offsets, lastWidth )); + + markIntersection( _dragData.targetInt ); + trackGhost( cursorX, cursorY ); + } + + function dragColEnd ( event ) { + _dragData.pressed = false; + + var edata, + target, + selected, + columnConfig, + targetColumn, + ghosts = $( '.w2ui-grid-ghost' ); + + //start event for drag start + edata = obj.trigger({ type: 'columnDragEnd', phase: 'before', originalEvent: event, target: _dragData.columnHead[0] }); + if ( edata.isCancelled === true ) return false; + + selected = obj.columns[ _dragData.originalPos ]; + columnConfig = obj.columns; + targetColumn = $( _dragData.columns[ Math.min(_dragData.lastInt, _dragData.columns.length - 1) ] ); + target = (_dragData.lastInt < _dragData.columns.length) ? parseInt(targetColumn.attr('col')) : columnConfig.length; + + if ( target !== _dragData.originalPos + 1 && target !== _dragData.originalPos && targetColumn && targetColumn.length ) { + $( _dragData.ghost ).animate({ + top: $( obj.box ).offset().top, + left: targetColumn.offset().left, + width: 0, + height: 0, + opacity: 0.2 + }, 300, function(){ + $( this ).remove(); + ghosts.remove(); + }); + + columnConfig.splice( target, 0, $.extend( {}, selected ) ); + columnConfig.splice( columnConfig.indexOf( selected ), 1); + + } else { + $( _dragData.ghost ).remove(); + ghosts.remove(); + } + + //_dragData.columns.css({ overflow: '' }).children( 'div' ).css({ overflow: '' }); + + $( document ).off( 'mouseup', dragColEnd ); + $( document ).off( 'mousemove', dragColOver ); + if ( _dragData.marker ) _dragData.marker.remove(); + _dragData = {}; + + obj.refresh(); + + //conclude event + obj.trigger( $.extend( edata, { phase: 'after', targetColumnNumber: target - 1 } ) ); + } + + function markIntersection( intersection ){ + if ( !_dragData.marker && !_dragData.markerLeft ) { + _dragData.marker = $('
' + + '
' + + '
' + + '
'); + _dragData.markerLeft = $('
' + + '
' + + '
' + + '
'); + } + + if ( !_dragData.lastInt || _dragData.lastInt !== intersection ){ + _dragData.lastInt = intersection; + _dragData.marker.remove(); + _dragData.markerLeft.remove(); + $('.w2ui-head').removeClass('w2ui-col-intersection'); + + //if the current intersection is greater than the number of columns add the marker to the end of the last column only + if ( intersection >= _dragData.columns.length ) { + $( _dragData.columns[ _dragData.columns.length - 1 ] ).children( 'div:last' ).append( _dragData.marker.addClass( 'right' ).removeClass( 'left' ) ); + $( _dragData.columns[ _dragData.columns.length - 1 ] ).addClass('w2ui-col-intersection'); + } else if ( intersection <= _dragData.numberPreColumnsPresent ) { + //if the current intersection is on the column numbers place marker on first available column only + $( _dragData.columns[ _dragData.numberPreColumnsPresent ] ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ).css({ position: 'relative' }); + $( _dragData.columns[ _dragData.numberPreColumnsPresent ] ).prev().addClass('w2ui-col-intersection'); + } else { + //otherwise prepend the marker to the targeted column and append it to the previous column + $( _dragData.columns[intersection] ).children( 'div:last' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ); + $( _dragData.columns[intersection] ).prev().children( 'div:last' ).append( _dragData.markerLeft.addClass( 'right' ).removeClass( 'left' ) ).css({ position: 'relative' }); + $( _dragData.columns[intersection - 1] ).addClass('w2ui-col-intersection'); + } + } + } + + function targetIntersection( cursorX, offsets, lastWidth ){ + if ( cursorX <= offsets[0] ) { + return 0; + } else if ( cursorX >= offsets[offsets.length - 1] + lastWidth ) { + return offsets.length; + } else { + for ( var i = 0, l = offsets.length; i < l; i++ ) { + var thisOffset = offsets[ i ]; + var nextOffset = offsets[ i + 1 ] || offsets[ i ] + lastWidth; + var midpoint = ( nextOffset - offsets[ i ]) / 2 + offsets[ i ]; + + if ( cursorX > thisOffset && cursorX <= midpoint ) { + return i; + } else if ( cursorX > midpoint && cursorX <= nextOffset ) { + return i + 1; + } + } + return intersection; + } + } + + function trackGhost( cursorX, cursorY ){ + $( _dragData.ghost ).css({ + left: cursorX - 10, + top: cursorY - 10 + }); + } + + //return an object to remove drag if it has ever been enabled + return { + remove: function(){ + $( obj.box ).off( 'mousedown', dragColStart ); + $( obj.box ).off( 'mouseup', catchMouseup ); + $( obj.box ).find( '.w2ui-head' ).removeAttr( 'draggable' ); + obj.last.columnDrag = false; + } + }; + }, + + columnOnOff: function (event, field) { + var $el = $(event.target).parents('tr').find('.w2ui-column-check'); + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'columnOnOff', field: field, originalEvent: event }); + if (edata.isCancelled === true) return; + // regular processing + var obj = this; + var hide = (!event.shiftKey && !event.metaKey && !event.ctrlKey && !$(event.target).hasClass('w2ui-column-check')); + // collapse expanded rows + var rows = obj.find({ 'w2ui.expanded': true }, true); + for (var r = 0; r < rows.length; r++) { + var tmp = this.records[r].w2ui; + if (tmp && !Array.isArray(tmp.children)) { + this.records[r].w2ui.expanded = false; + } + } + // show/hide + if (field == 'line-numbers') { + this.show.lineNumbers = !this.show.lineNumbers; + if (this.show.lineNumbers) { + $el.addClass('w2ui-icon-check').removeClass('w2ui-icon-empty'); + } else { + $el.addClass('w2ui-icon-empty').removeClass('w2ui-icon-check'); + } + this.refreshBody(); + this.resizeRecords(); + } else { + var col = this.getColumn(field); + if (col.hidden) { + $el.addClass('w2ui-icon-check').removeClass('w2ui-icon-empty'); + setTimeout(function () { + obj.showColumn(col.field); + }, hide ? 0 : 50); + } else { + $el.addClass('w2ui-icon-empty').removeClass('w2ui-icon-check'); + setTimeout(function () { + obj.hideColumn(col.field); + }, hide ? 0 : 50); + } + } + if (hide) { + setTimeout(function () { + $().w2overlay({ name: obj.name + '_toolbar' }); + }, 40); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + scrollToColumn: function (field) { + if (field == null) + return; + var sWidth = 0; + var found = false; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.field == field) { + found = true; + break; + } + if (col.frozen || col.hidden) + continue; + var cSize = parseInt(col.sizeCalculated ? col.sizeCalculated : col.size); + sWidth += cSize; + } + if (!found) + return; + this.last.scrollLeft = sWidth+1; + this.scroll(); + }, + + initToolbar: function () { + var obj = this; + // -- if toolbar is true + if (this.toolbar['render'] == null) { + var tmp_items = this.toolbar.items || []; + this.toolbar.items = []; + this.toolbar = $().w2toolbar($.extend(true, {}, this.toolbar, { name: this.name +'_toolbar', owner: this })); + + // ============================================= + // ------ Toolbar Generic buttons + + if (this.show.toolbarReload) { + this.toolbar.items.push($.extend(true, {}, this.buttons['reload'])); + } + if (this.show.toolbarColumns) { + this.toolbar.items.push($.extend(true, {}, this.buttons['columns'])); + } + if (this.show.toolbarReload || this.show.toolbarColumns) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break0' }); + } + if (this.show.toolbarInput) { + var html = + ''; + this.toolbar.items.push({ type: 'html', id: 'w2ui-search', html: html }); + } + if (this.show.toolbarSearch && this.multiSearch && this.searches.length > 0) { + this.toolbar.items.push($.extend(true, {}, this.buttons['search-go'])); + } + if ((this.show.toolbarSearch || this.show.toolbarInput) + && (this.show.toolbarAdd || this.show.toolbarEdit || this.show.toolbarDelete || this.show.toolbarSave)) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break1' }); + } + if (this.show.toolbarAdd && Array.isArray(tmp_items) + && tmp_items.map(function (item) { return item.id }).indexOf(this.buttons['add'].id) == -1) { + this.toolbar.items.push($.extend(true, {}, this.buttons['add'])); + } + if (this.show.toolbarEdit && Array.isArray(tmp_items) + && tmp_items.map(function (item) { return item.id }).indexOf(this.buttons['edit'].id) == -1) { + this.toolbar.items.push($.extend(true, {}, this.buttons['edit'])); + } + if (this.show.toolbarDelete && Array.isArray(tmp_items) + && tmp_items.map(function (item) { return item.id }).indexOf(this.buttons['delete'].id) == -1) { + this.toolbar.items.push($.extend(true, {}, this.buttons['delete'])); + } + if (this.show.toolbarSave && Array.isArray(tmp_items) + && tmp_items.map(function (item) { return item.id }).indexOf(this.buttons['save'].id) == -1) { + if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }); + } + this.toolbar.items.push($.extend(true, {}, this.buttons['save'])); + } + // add original buttons + if (tmp_items) for (var i = 0; i < tmp_items.length; i++) this.toolbar.items.push(tmp_items[i]); + + // ============================================= + // ------ Toolbar onClick processing + + var obj = this; + this.toolbar.on('click', function (event) { + var edata = obj.trigger({ phase: 'before', type: 'toolbar', target: event.target, originalEvent: event }); + if (edata.isCancelled === true) return; + var id = event.target; + switch (id) { + case 'w2ui-reload': + var edata2 = obj.trigger({ phase: 'before', type: 'reload', target: obj.name }); + if (edata2.isCancelled === true) return false; + obj.reload(); + obj.trigger($.extend(edata2, { phase: 'after' })); + break; + case 'w2ui-column-on-off': + obj.initColumnOnOff(); + obj.initResize(); + obj.resize(); + break; + case 'w2ui-search-advanced': + var it = this.get(id); + if (it.checked) { + obj.searchClose(); + } else { + obj.searchOpen(); + } + // need to cancel event in order to user custom searchOpen/close functions + obj.toolbar.tooltipHide('w2ui-search-advanced'); + event.preventDefault(); + break; + case 'w2ui-add': + // events + var edata2 = obj.trigger({ phase: 'before', target: obj.name, type: 'add', recid: null }); + if (edata2.isCancelled === true) return false; + obj.trigger($.extend(edata2, { phase: 'after' })); + // hide all tooltips + setTimeout(function () { $().w2tag(); }, 20); + break; + case 'w2ui-edit': + var sel = obj.getSelection(); + var recid = null; + if (sel.length == 1) recid = sel[0]; + // events + var edata2 = obj.trigger({ phase: 'before', target: obj.name, type: 'edit', recid: recid }); + if (edata2.isCancelled === true) return false; + obj.trigger($.extend(edata2, { phase: 'after' })); + // hide all tooltips + setTimeout(function () { $().w2tag(); }, 20); + break; + case 'w2ui-delete': + obj["delete"](); + break; + case 'w2ui-save': + obj.save(); + break; + } + // no default action + obj.trigger($.extend(edata, { phase: 'after' })); + }) + this.toolbar.on('refresh', function (event) { + if (event.target == 'w2ui-search') { + var sd = obj.searchData; + setTimeout(function () { + obj.initAllField(obj.last.field, (sd.length == 1 ? sd[0].value : null)); + }, 1); + } + }) + } + }, + + initResize: function () { + var obj = this; + //if (obj.resizing === true) return; + $(this.box).find('.w2ui-resizer') + .off('.grid-col-resize') + .on('click.grid-col-resize', function (event) { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + }) + .on('mousedown.grid-col-resize', function (event) { + if (!event) event = window.event; + obj.resizing = true; + obj.last.tmp = { + x : event.screenX, + y : event.screenY, + gx : event.screenX, + gy : event.screenY, + col : parseInt($(this).attr('name')) + }; + // find tds that will be resized + obj.last.tmp.tds = $('#grid_'+ obj.name +'_body table tr:first-child td[col='+ obj.last.tmp.col +']') + + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + // fix sizes + for (var c = 0; c < obj.columns.length; c++) { + if (obj.columns[c].hidden) continue; + if (obj.columns[c].sizeOriginal == null) obj.columns[c].sizeOriginal = obj.columns[c].size; + obj.columns[c].size = obj.columns[c].sizeCalculated; + } + var edata = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field }; + edata = obj.trigger($.extend(edata, { resizeBy: 0, originalEvent: event })); + // set move event + var timer; + var mouseMove = function (event) { + if (obj.resizing != true) return; + if (!event) event = window.event; + // event before + edata = obj.trigger($.extend(edata, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })); + if (edata.isCancelled === true) { edata.isCancelled = false; return; } + // default action + obj.last.tmp.x = (event.screenX - obj.last.tmp.x); + obj.last.tmp.y = (event.screenY - obj.last.tmp.y); + var newWidth =(parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px' + obj.columns[obj.last.tmp.col].size = newWidth; + if (timer) clearTimeout(timer) + timer = setTimeout(function () { + obj.resizeRecords() + obj.scroll() + }, 100) + // quick resize + obj.last.tmp.tds.css({ width: newWidth }) + // reset + obj.last.tmp.x = event.screenX; + obj.last.tmp.y = event.screenY; + }; + var mouseUp = function (event) { + delete obj.resizing; + $(document).off('.grid-col-resize'); + obj.resizeRecords(); + obj.scroll(); + // event after + obj.trigger($.extend(edata, { phase: 'after', originalEvent: event })); + }; + + $(document) + .off('.grid-col-resize') + .on('mousemove.grid-col-resize', mouseMove) + .on('mouseup.grid-col-resize', mouseUp); + }) + .on('dblclick.grid-col-resize', function(event) { + var colId = parseInt($(this).attr('name')), + col = obj.columns[colId], + maxDiff = 0; + + if (col.autoResize === false) { + return true; + } + + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + $('.w2ui-grid-records td[col="' + colId + '"] > div', obj.box).each(function() { + var thisDiff = this.offsetWidth - this.scrollWidth; + + if (thisDiff < maxDiff) { + maxDiff = thisDiff - 3; // 3px buffer needed for Firefox + } + }); + + // event before + var edata = { phase: 'before', type: 'columnAutoResize', target: obj.name, column: col, field: col.field }; + edata = obj.trigger($.extend(edata, { resizeBy: Math.abs(maxDiff), originalEvent: event })); + if (edata.isCancelled === true) { edata.isCancelled = false; return; } + + if (maxDiff < 0) { + col.size = Math.min(parseInt(col.size) + Math.abs(maxDiff), col.max || Infinity) + 'px'; + obj.resizeRecords(); + obj.resizeRecords(); // Why do we have to call it twice in order to show the scrollbar? + obj.scroll(); + } + + // event after + obj.trigger($.extend(edata, { phase: 'after', originalEvent: event })); + }) + .each(function (index, el) { + var td = $(el).parent(); + $(el).css({ + "height" : td.height(), + "margin-left" : (td.width() - 3) + 'px' + }); + }); + }, + + resizeBoxes: function () { + // elements + var header = $('#grid_'+ this.name +'_header'); + var toolbar = $('#grid_'+ this.name +'_toolbar'); + var fsummary = $('#grid_'+ this.name +'_fsummary'); + var summary = $('#grid_'+ this.name +'_summary'); + var footer = $('#grid_'+ this.name +'_footer'); + var body = $('#grid_'+ this.name +'_body'); + + if (this.show.header) { + header.css({ + top: '0px', + left: '0px', + right: '0px' + }); + } + + if (this.show.toolbar) { + toolbar.css({ + top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + } + if (this.summary.length > 0) { + fsummary.css({ + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) ) + 'px' + }); + summary.css({ + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) ) + 'px', + right: '0px' + }); + } + if (this.show.footer) { + footer.css({ + bottom: '0px', + left: '0px', + right: '0px' + }); + } + body.css({ + top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) ) + 'px', + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + }, + + resizeRecords: function () { + var obj = this; + // remove empty records + $(this.box).find('.w2ui-empty-record').remove(); + // -- Calculate Column size in PX + var box = $(this.box); + var grid = $(this.box).find('> div.w2ui-grid-box'); + var header = $('#grid_'+ this.name +'_header'); + var toolbar = $('#grid_'+ this.name +'_toolbar'); + var summary = $('#grid_'+ this.name +'_summary'); + var fsummary = $('#grid_'+ this.name +'_fsummary'); + var footer = $('#grid_'+ this.name +'_footer'); + var body = $('#grid_'+ this.name +'_body'); + var columns = $('#grid_'+ this.name +'_columns'); + var fcolumns = $('#grid_'+ this.name +'_fcolumns'); + var records = $('#grid_'+ this.name +'_records'); + var frecords = $('#grid_'+ this.name +'_frecords'); + var scroll1 = $('#grid_'+ this.name +'_scroll1'); + var lineNumberWidth = String(this.total).length * 8 + 10; + if (lineNumberWidth < 34) lineNumberWidth = 34; // 3 digit width + if (this.lineNumberWidth != null) lineNumberWidth = this.lineNumberWidth; + + var bodyOverflowX = false; + var bodyOverflowY = false; + var sWidth = 0; + for (var i = 0; i < obj.columns.length; i++) { + if (obj.columns[i].frozen || obj.columns[i].hidden) continue; + var cSize = parseInt(obj.columns[i].sizeCalculated ? obj.columns[i].sizeCalculated : obj.columns[i].size); + sWidth += cSize; + } + if (records.width() < sWidth) bodyOverflowX = true; + if (body.height() - columns.height() < $(records).find('>table').height() + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) bodyOverflowY = true; + + // body might be expanded by data + if (!this.fixedBody) { + // allow it to render records, then resize + var calculatedHeight = w2utils.getSize(columns, 'height') + + w2utils.getSize($('#grid_'+ obj.name +'_records table'), 'height') + + (bodyOverflowX ? w2utils.scrollBarSize() : 0); + obj.height = calculatedHeight + + w2utils.getSize(grid, '+height') + + (obj.show.header ? w2utils.getSize(header, 'height') : 0) + + (obj.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + + (obj.show.footer ? w2utils.getSize(footer, 'height') : 0); + grid.css('height', obj.height); + body.css('height', calculatedHeight); + box.css('height', w2utils.getSize(grid, 'height') + w2utils.getSize(box, '+height')); + } else { + // fixed body height + var calculatedHeight = grid.height() + - (this.show.header ? w2utils.getSize(header, 'height') : 0) + - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + - (this.show.footer ? w2utils.getSize(footer, 'height') : 0); + body.css('height', calculatedHeight); + } + + var buffered = this.records.length; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length; + // apply overflow + if (!this.fixedBody) { bodyOverflowY = false; } + if (bodyOverflowX || bodyOverflowY) { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + "-webkit-overflow-scrolling": "touch", + "overflow-x": (bodyOverflowX ? 'auto' : 'hidden'), + "overflow-y": (bodyOverflowY ? 'auto' : 'hidden') + }); + } else { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').hide(); + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + overflow: 'hidden' + }); + if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0; } // if no scrollbars, always show top + } + if (bodyOverflowX) { + frecords.css('margin-bottom', w2utils.scrollBarSize()); + scroll1.show(); + } else { + frecords.css('margin-bottom', 0); + scroll1.hide(); + } + frecords.css({ overflow: 'hidden', top: records.css('top') }); + if (this.show.emptyRecords && !bodyOverflowY) { + var max = Math.floor(records.height() / this.recordHeight) - 1; + var leftover = 0; + if (records[0]) leftover = records[0].scrollHeight - max * this.recordHeight; + if (leftover >= this.recordHeight) { + leftover -= this.recordHeight; + max++; + } + if (this.fixedBody) { + for (var di = buffered; di < max; di++) { + addEmptyRow(di, this.recordHeight, this); + } + addEmptyRow(max, leftover, this); + } + } + + function addEmptyRow(row, height, grid) { + var html1 = ''; + var html2 = ''; + var htmlp = ''; + html1 += ''; + html2 += ''; + if (grid.show.lineNumbers) html1 += ''; + if (grid.show.selectColumn) html1 += ''; + if (grid.show.expandColumn) html1 += ''; + html2 += ''; + if (grid.show.orderColumn) html2 += ''; + for (var j = 0; j < grid.columns.length; j++) { + var col = grid.columns[j]; + if ((col.hidden || j < grid.last.colStart || j > grid.last.colEnd) && !col.frozen) continue; + htmlp = ''; + if (col.frozen) html1 += htmlp; else html2 += htmlp; + } + html1 += ' '; + html2 += ' '; + $('#grid_'+ grid.name +'_frecords > table').append(html1); + $('#grid_'+ grid.name +'_records > table').append(html2); + } + if (body.length > 0) { + var width_max = parseInt(body.width()) + - (bodyOverflowY ? w2utils.scrollBarSize() : 0) + - (this.show.lineNumbers ? lineNumberWidth : 0) + // - (this.show.orderColumn ? 26 : 0) + - (this.show.selectColumn ? 26 : 0) + - (this.show.expandColumn ? 26 : 0) + - 1; // left is 1xp due to border width + var width_box = width_max; + var percent = 0; + // gridMinWidth processing + var restart = false; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.gridMinWidth > 0) { + if (col.gridMinWidth > width_box && col.hidden !== true) { + col.hidden = true; + restart = true; + } + if (col.gridMinWidth < width_box && col.hidden === true) { + col.hidden = false; + restart = true; + } + } + } + if (restart === true) { + this.refresh(); + return; + } + // assign PX column s + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { + width_max -= parseFloat(col.size); + this.columns[i].sizeCalculated = col.size; + this.columns[i].sizeType = 'px'; + } else { + percent += parseFloat(col.size); + this.columns[i].sizeType = '%'; + delete col.sizeCorrected; + } + } + // if sum != 100% -- reassign proportionally + if (percent != 100 && percent > 0) { + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.sizeType == '%') { + col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%'; + } + } + } + // calculate % columns + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.sizeType == '%') { + if (this.columns[i].sizeCorrected != null) { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px'; + } else { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px'; + } + } + } + } + // fix margin of error that is due percentage calculations + var width_cols = 0; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.min == null) col.min = 20; + if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px'; + if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px'; + width_cols += parseInt(col.sizeCalculated); + } + var width_diff = parseInt(width_box) - parseInt(width_cols); + if (width_diff > 0 && percent > 0) { + var i = 0; + while (true) { + var col = this.columns[i]; + if (col == null) { i = 0; continue; } + if (col.hidden || col.sizeType == 'px') { i++; continue; } + col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px'; + width_diff--; + if (width_diff === 0) break; + i++; + } + } else if (width_diff > 0) { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); + } + + // find width of frozen columns + var fwidth = 1; + if (this.show.lineNumbers) fwidth += lineNumberWidth; + if (this.show.selectColumn) fwidth += 26; + // if (this.show.orderColumn) fwidth += 26; + if (this.show.expandColumn) fwidth += 26; + for (var i = 0; i < this.columns.length; i++) { + if (this.columns[i].hidden) continue; + if (this.columns[i].frozen) fwidth += parseInt(this.columns[i].sizeCalculated); + } + fcolumns.css('width', fwidth); + frecords.css('width', fwidth); + fsummary.css('width', fwidth); + scroll1.css('width', fwidth); + columns.css('left', fwidth); + records.css('left', fwidth); + summary.css('left', fwidth); + + // resize columns + columns.find('> table > tbody > tr:nth-child(1) td') + .add(fcolumns.find('> table > tbody > tr:nth-child(1) td')) + .each(function (index, el) { + // line numbers + if ($(el).hasClass('w2ui-col-number')) { + $(el).css('width', lineNumberWidth); + } + // records + var ind = $(el).attr('col'); + if (ind != null) { + if (ind == 'start') { + var width = 0; + for (var i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue; + width += parseInt(obj.columns[i].sizeCalculated); + } + $(el).css('width', width + 'px'); + } + if (obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + } + // last column + if ($(el).hasClass('w2ui-head-last')) { + if (obj.last.colEnd + 1 < obj.columns.length) { + var width = 0; + for (var i = obj.last.colEnd + 1; i < obj.columns.length; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue; + width += parseInt(obj.columns[i].sizeCalculated); + } + $(el).css('width', width + 'px'); + } else { + $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px'); + } + } + }); + // if there are column groups - hide first row (needed for sizing) + if (columns.find('> table > tbody > tr').length == 3) { + columns.find('> table > tbody > tr:nth-child(1) td') + .add(fcolumns.find('> table > tbody > tr:nth-child(1) td')) + .html('').css({ + 'height' : '0px', + 'border' : '0px', + 'padding': '0px', + 'margin' : '0px' + }); + } + // resize records + records.find('> table > tbody > tr:nth-child(1) td') + .add(frecords.find('> table > tbody > tr:nth-child(1) td')) + .each(function (index, el) { + // line numbers + if ($(el).hasClass('w2ui-col-number')) { + $(el).css('width', lineNumberWidth); + } + // records + var ind = $(el).attr('col'); + if (ind != null) { + if (ind == 'start') { + var width = 0; + for (var i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue; + width += parseInt(obj.columns[i].sizeCalculated); + } + $(el).css('width', width + 'px'); + } + if (obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + } + // last column + if ($(el).hasClass('w2ui-grid-data-last') && $(el).parents('.w2ui-grid-frecords').length === 0) { // not in frecords + if (obj.last.colEnd + 1 < obj.columns.length) { + var width = 0; + for (var i = obj.last.colEnd + 1; i < obj.columns.length; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue; + width += parseInt(obj.columns[i].sizeCalculated); + } + $(el).css('width', width + 'px'); + } else { + $(el).css('width', (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px'); + } + } + }); + // resize summary + summary.find('> table > tbody > tr:nth-child(1) td') + .add(fsummary.find('> table > tbody > tr:nth-child(1) td')) + .each(function (index, el) { + // line numbers + if ($(el).hasClass('w2ui-col-number')) { + $(el).css('width', lineNumberWidth); + } + // records + var ind = $(el).attr('col'); + if (ind != null) { + if (ind == 'start') { + var width = 0; + for (var i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue; + width += parseInt(obj.columns[i].sizeCalculated); + } + $(el).css('width', width + 'px'); + } + if (obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + } + // last column + if ($(el).hasClass('w2ui-grid-data-last') && $(el).parents('.w2ui-grid-frecords').length === 0) { // not in frecords + $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px'); + } + }); + this.initResize(); + this.refreshRanges(); + // apply last scroll if any + if ((this.last.scrollTop || this.last.scrollLeft) && records.length > 0) { + columns.prop('scrollLeft', this.last.scrollLeft); + records.prop('scrollTop', this.last.scrollTop); + records.prop('scrollLeft', this.last.scrollLeft); + } + }, + + getSearchesHTML: function () { + var obj = this; + var html = ''; + var showBtn = false; + for (var i = 0; i < this.searches.length; i++) { + var s = this.searches[i]; + s.type = String(s.type).toLowerCase(); + if (s.hidden) continue; + var btn = ''; + if (showBtn == false) { + btn = ''; + showBtn = true; + } + if (s.inTag == null) s.inTag = ''; + if (s.outTag == null) s.outTag = ''; + if (s.style == null) s.style = ''; + if (s.type == null) s.type = 'text'; + if (s.label == null && s.caption != null) { + console.log('NOTICE: grid search.caption property is deprecated, please use search.label. Search ->', s) + s.label = s.caption; + } + var operator = + ''; + + html += ''+ + ' ' + + ' ' + + ' '+ + ' ' + + ''; + } + html += ''+ + ' '+ + '
'+ btn +''+ (s.label || '') +''+ operator +''; + + switch (s.type) { + case 'text': + case 'alphanumeric': + case 'hex': + case 'color': + case 'list': + case 'combo': + case 'enum': + var tmpStyle = 'width: 250px;'; + if (['hex', 'color'].indexOf(s.type) != -1) tmpStyle = 'width: 90px;'; + html += ''; + break; + + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + case 'datetime': + var tmpStyle = 'width: 90px;'; + if (s.type == 'datetime') tmpStyle = 'width: 140px;'; + html += ''+ + ''; + break; + + case 'select': + html += ''; + break; + + } + html += s.outTag + + '
'+ + '
'+ + ' '+ + ' '+ + '
'+ + '
'; + return html; + + function getOperators(type, fieldOperators) { + var html = ''; + var operators = obj.operators[obj.operatorsMap[type]]; + if (fieldOperators != null) operators = fieldOperators; + for (var i = 0; i < operators.length; i++) { + var oper = operators[i]; + var text = oper; + if (Array.isArray(oper)) { + text = oper[1]; + oper = oper[0]; + if (text == null) text = oper; + } else if ($.isPlainObject(oper)) { + text = oper.text; + oper = oper.oper; + } + html += '\n'; + } + return html; + } + }, + + initOperator: function (el, search_ind) { + var obj = this; + var search = obj.searches[search_ind]; + var range = $('#grid_'+ obj.name + '_range_'+ search_ind); + var fld1 = $('#grid_'+ obj.name +'_field_'+ search_ind); + var fld2 = fld1.parent().find('span input'); + fld1.show(); + range.hide(); + switch ($(el).val()) { + case 'between': + range.show(); + fld2.w2field(search.type, search.options); + break; + case 'not null': + case 'null': + fld1.hide(); + fld1.val('1'); // need to insert something for search to activate + fld1.change(); + break; + } + }, + + initSearches: function () { + var obj = this; + // init searches + for (var s = 0; s < this.searches.length; s++) { + var search = this.searches[s]; + var sdata = this.getSearchData(search.field); + search.type = String(search.type).toLowerCase(); + var operators = obj.operators[obj.operatorsMap[search.type]]; + if (search.operators) operators = search.operators; + var operator = operators[0]; // default operator + if ($.isPlainObject(operator)) operator = operator.oper; + if (typeof search.options != 'object') search.options = {}; + if (search.type == 'text') operator = this.textSearch; + // only accept search.operator if it is valid + for (var i = 0; i < operators.length; i++) { + var oper = operators[i]; + if ($.isPlainObject(oper)) oper = oper.oper; + if (search.operator == oper) { + operator = search.operator; + break; + } + } + // init types + switch (search.type) { + case 'text': + case 'alphanumeric': + $('#grid_'+ this.name +'_field_' + s).w2field(search.type, search.options); + break; + + case 'int': + case 'float': + case 'hex': + case 'color': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + case 'datetime': + $('#grid_'+ this.name +'_field_'+s).w2field(search.type, search.options); + $('#grid_'+ this.name +'_field2_'+s).w2field(search.type, search.options); + setTimeout(function () { // convert to date if it is number + $('#grid_'+ obj.name +'_field_'+s).keydown(); + $('#grid_'+ obj.name +'_field2_'+s).keydown(); + }, 1); + break; + + case 'list': + case 'combo': + case 'enum': + var options = search.options; + if (search.type == 'list') options.selected = {}; + if (search.type == 'enum') options.selected = []; + if (sdata) options.selected = sdata.value; + $('#grid_'+ this.name +'_field_'+s).w2field(search.type, $.extend({ openOnFocus: true }, options)); + if (sdata && sdata.text != null) $('#grid_'+ this.name +'_field_'+s).data('selected', {id: sdata.value, text: sdata.text}); + break; + + case 'select': + // build options + var options = ''; + for (var i = 0; i < search.options.items.length; i++) { + var si = search.options.items[i]; + if ($.isPlainObject(search.options.items[i])) { + var val = si.id; + var txt = si.text; + if (val == null && si.value != null) val = si.value; + if (txt == null && si.text != null) txt = si.text; + if (val == null) val = ''; + options += ''; + } else { + options += ''; + } + } + $('#grid_'+ this.name +'_field_'+s).html(options); + break; + } + if (sdata != null) { + if (sdata.type == 'int' && ['in', 'not in'].indexOf(sdata.operator) != -1) { + $('#grid_'+ this.name +'_field_'+ s).w2field('clear').val(sdata.value); + } + $('#grid_'+ this.name +'_operator_'+ s).val(sdata.operator).trigger('change'); + if (!$.isArray(sdata.value)) { + if (sdata.value != null) $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); + } else { + if (['in', 'not in'].indexOf(sdata.operator) != -1) { + $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); + } else { + $('#grid_'+ this.name +'_field_'+ s).val(sdata.value[0]).trigger('change'); + $('#grid_'+ this.name +'_field2_'+ s).val(sdata.value[1]).trigger('change'); + } + } + } else { + $('#grid_'+ this.name +'_operator_'+s).val(operator).trigger('change'); + } + } + // add on change event + $('#w2ui-overlay-'+ this.name +'-searchOverlay .w2ui-grid-searches *[rel=search]').on('keypress', function (evnt) { + if (evnt.keyCode == 13) { + obj.search(); + $().w2overlay({ name: obj.name + '-searchOverlay' }); + } + }); + }, + + getColumnsHTML: function () { + var obj = this; + var html1 = ''; + var html2 = ''; + if (this.show.columnHeaders) { + if (this.columnGroups.length > 0) { + var tmp1 = getColumns(true); + var tmp2 = getGroups(); + var tmp3 = getColumns(false); + html1 = tmp1[0] + tmp2[0] + tmp3[0]; + html2 = tmp1[1] + tmp2[1] + tmp3[1]; + } else { + var tmp = getColumns(true); + html1 = tmp[0]; + html2 = tmp[1]; + } + } + return [html1, html2]; + + function getGroups () { + var html1 = ''; + var html2 = ''; + var tmpf = ''; + // add empty group at the end + var tmp = obj.columnGroups.length - 1; + if (obj.columnGroups[tmp].text == null && obj.columnGroups[tmp].caption != null) { + console.log('NOTICE: grid columnGroup.caption property is deprecated, please use columnGroup.text. Group -> ', obj.columnGroups[tmp]); + obj.columnGroups[tmp].text = obj.columnGroups[tmp].caption; + } + if (obj.columnGroups[obj.columnGroups.length-1].text != '') obj.columnGroups.push({ text: '' }); + + if (obj.show.lineNumbers) { + html1 += ''+ + '
 
'+ + ''; + } + if (obj.show.selectColumn) { + html1 += ''+ + '
 
'+ + ''; + } + if (obj.show.expandColumn) { + html1 += ''+ + '
 
'+ + ''; + } + var ii = 0; + html2 += ''; + if (obj.show.orderColumn) { + html2 += ''+ + '
 
'+ + ''; + } + for (var i=0; i', col); + col.text = col.caption; + } + var colspan = 0; + for (var jj = ii; jj < ii + colg.span; jj++) { + if (obj.columns[jj] && !obj.columns[jj].hidden) { + colspan++; + } + } + if (i == obj.columnGroups.length-1) { + colspan = 100; // last column + } + if (colspan <= 0) { + // do nothing here, all columns in the group are hidden. + } else if (colg.master === true) { + var sortStyle = ''; + for (var si = 0; si < obj.sortData.length; si++) { + if (obj.sortData[si].field == col.field) { + if ((obj.sortData[si].direction || '').toLowerCase() === 'asc') sortStyle = 'w2ui-sort-up'; + if ((obj.sortData[si].direction || '').toLowerCase() === 'desc') sortStyle = 'w2ui-sort-down'; + } + } + var resizer = ""; + if (col.resizable !== false) { + resizer = '
'; + } + var text = (typeof col.text == 'function' ? col.text(col) : col.text); + tmpf = ''+ + resizer + + '
'+ + '
'+ + (!text ? ' ' : text) + + '
'+ + ''; + if (col && col.frozen) html1 += tmpf; else html2 += tmpf; + } else { + var gText = (typeof colg.text == 'function' ? colg.text(colg) : colg.text); + tmpf = ''+ + '
'+ + (!gText ? ' ' : gText) + + '
'+ + ''; + if (col && col.frozen) html1 += tmpf; else html2 += tmpf; + } + ii += colg.span; + } + html1 += ''; // need empty column for border-right + html2 += ''; + return [html1, html2]; + } + + function getColumns (master) { + var html1 = ''; + var html2 = ''; + if (obj.show.lineNumbers) { + html1 += ''+ + '
#
'+ + ''; + } + if (obj.show.selectColumn) { + html1 += ''+ + '
'+ + ' '+ + '
'+ + ''; + } + if (obj.show.expandColumn) { + html1 += ''+ + '
 
'+ + ''; + } + var ii = 0; + var id = 0; + var colg; + html2 += ''; + if (obj.show.orderColumn) { + html2 += ''+ + '
 
'+ + ''; + } + for (var i = 0; i < obj.columns.length; i++) { + var col = obj.columns[i]; + if (col.text == null && col.caption != null) { + console.log('NOTICE: grid column.caption property is deprecated, please use column.text. Column -> ', col); + col.text = col.caption; + } + if (col.size == null) col.size = '100%'; + if (i == id) { // always true on first iteration + colg = obj.columnGroups[ii++] || {}; + id = id + colg.span; + } + if ((i < obj.last.colStart || i > obj.last.colEnd) && !col.frozen) + continue; + if (col.hidden) + continue; + if (colg.master !== true || master) { // grouping of columns + var colCellHTML = obj.getColumnCellHTML(i); + if (col && col.frozen) html1 += colCellHTML; else html2 += colCellHTML; + } + } + html1 += '
 
'; + html2 += '
 
'; + html1 += ''; + html2 += ''; + return [html1, html2]; + } + }, + + getColumnCellHTML: function (i) { + var col = this.columns[i]; + if (col == null) return ''; + // reorder style + var reorderCols = (this.reorderColumns && (!this.columnGroups || !this.columnGroups.length)) ? ' w2ui-reorder-cols-head ' : ''; + // sort style + var sortStyle = ''; + for (var si = 0; si < this.sortData.length; si++) { + if (this.sortData[si].field == col.field) { + if ((this.sortData[si].direction || '').toLowerCase() === 'asc') sortStyle = 'w2ui-sort-up'; + if ((this.sortData[si].direction || '').toLowerCase() === 'desc') sortStyle = 'w2ui-sort-down'; + } + } + // col selected + var tmp = this.last.selection.columns; + var selected = false; + for (var t in tmp) { + for (var si = 0; si < tmp[t].length; si++) { + if (tmp[t][si] == i) selected = true; + } + } + var text = (typeof col.text == 'function' ? col.text(col) : col.text); + var html = ''+ + (col.resizable !== false ? '
' : '') + + '
'+ + '
'+ + (!text ? ' ' : text) + + '
'+ + ''; + + return html + }, + + columnTooltipShow: function (ind) { + if (this.columnTooltip == 'normal') return; + var $el = $(this.box).find('#grid_'+ this.name + '_column_'+ ind); + var item = this.columns[ind]; + var pos = this.columnTooltip; + $el.prop('_mouse_over', true); + setTimeout(function () { + if ($el.prop('_mouse_over') === true && $el.prop('_mouse_tooltip') !== true) { + $el.prop('_mouse_tooltip', true); + // show tooltip + $el.w2tag(item.tooltip, { position: pos, top: 5 }); + } + }, 1); + }, + + columnTooltipHide: function (ind) { + if (this.columnTooltip == 'normal') return; + var $el = $(this.box).find('#grid_'+ this.name + '_column_'+ ind); + var item = this.columns[ind]; + $el.removeProp('_mouse_over'); + setTimeout(function () { + if ($el.prop('_mouse_over') !== true && $el.prop('_mouse_tooltip') === true) { + $el.removeProp('_mouse_tooltip'); + // hide tooltip + $el.w2tag(); + } + }, 1); + }, + + getRecordsHTML: function () { + var buffered = this.records.length; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length; + // larger number works better with chrome, smaller with FF. + if (buffered > this.vs_start) this.last.show_extra = this.vs_extra; else this.last.show_extra = this.vs_start; + var records = $('#grid_'+ this.name +'_records'); + var limit = Math.floor((records.height() || 0) / this.recordHeight) + this.last.show_extra + 1; + if (!this.fixedBody || limit > buffered) limit = buffered; + // always need first record for resizing purposes + var rec_html = this.getRecordHTML(-1, 0); + var html1 = '' + rec_html[0]; + var html2 = '
' + rec_html[1]; + // first empty row with height + html1 += ''+ + ' '+ + ''; + html2 += ''+ + ' '+ + ''; + for (var i = 0; i < limit; i++) { + rec_html = this.getRecordHTML(i, i+1); + html1 += rec_html[0]; + html2 += rec_html[1]; + } + var h2 = (buffered - limit) * this.recordHeight; + html1 += '' + + ' '+ + ''+ + ''+ + ' '+ + ''+ + '
'; + html2 += '' + + ' '+ + ''+ + ''+ + ' '+ + ''+ + ''; + this.last.range_start = 0; + this.last.range_end = limit; + return [html1, html2]; + }, + + getSummaryHTML: function () { + if (this.summary.length === 0) return; + var rec_html = this.getRecordHTML(-1, 0); // need this in summary too for colspan to work properly + var html1 = '' + rec_html[0]; + var html2 = '
' + rec_html[1]; + for (var i = 0; i < this.summary.length; i++) { + rec_html = this.getRecordHTML(i, i+1, true); + html1 += rec_html[0]; + html2 += rec_html[1]; + } + html1 += '
'; + html2 += ''; + return [html1, html2]; + }, + + scroll: function (event) { + var time = (new Date()).getTime(); + var obj = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var records = $('#grid_'+ this.name +'_records'); + var frecords = $('#grid_'+ this.name +'_frecords'); + // sync scroll positions + if (event) { + var sTop = event.target.scrollTop; + var sLeft = event.target.scrollLeft; + obj.last.scrollTop = sTop; + obj.last.scrollLeft = sLeft; + $('#grid_'+ obj.name +'_columns')[0].scrollLeft = sLeft; + $('#grid_'+ obj.name +'_summary')[0].scrollLeft = sLeft; + frecords[0].scrollTop = sTop; + } + // hide bubble + if (this.last.bubbleEl) { + $(this.last.bubbleEl).w2tag(); + this.last.bubbleEl = null; + } + // column virtual scroll + var colStart = null; + var colEnd = null; + if (obj.disableCVS || obj.columnGroups.length > 0) { + // disable virtual scroll + colStart = 0; + colEnd = obj.columns.length - 1; + } else { + var sWidth = records.width(); + var cLeft = 0; + for (var i = 0; i < obj.columns.length; i++) { + if (obj.columns[i].frozen || obj.columns[i].hidden) continue; + var cSize = parseInt(obj.columns[i].sizeCalculated ? obj.columns[i].sizeCalculated : obj.columns[i].size); + if (cLeft + cSize + 30 > obj.last.scrollLeft && colStart == null) colStart = i; + if (cLeft + cSize - 30 > obj.last.scrollLeft + sWidth && colEnd == null) colEnd = i; + cLeft += cSize; + } + if (colEnd == null) colEnd = obj.columns.length - 1; + } + if (colStart != null) { + if (colStart < 0) colStart = 0; + if (colEnd < 0) colEnd = 0; + if (colStart == colEnd) { + if (colStart > 0) colStart--; else colEnd++; // show at least one column + } + // --------- + if (colStart != obj.last.colStart || colEnd != obj.last.colEnd) { + var $box = $(obj.box); + var deltaStart = Math.abs(colStart - obj.last.colStart); + var deltaEnd = Math.abs(colEnd - obj.last.colEnd) + // add/remove columns for small jumps + if (deltaStart < 5 && deltaEnd < 5) { + var $cfirst = $box.find('.w2ui-grid-columns #grid_'+ obj.name +'_column_start'); + var $clast = $box.find('.w2ui-grid-columns .w2ui-head-last'); + var $rfirst = $box.find('#grid_'+ obj.name +'_records .w2ui-grid-data-spacer'); + var $rlast = $box.find('#grid_'+ obj.name +'_records .w2ui-grid-data-last'); + var $sfirst = $box.find('#grid_'+ obj.name +'_summary .w2ui-grid-data-spacer'); + var $slast = $box.find('#grid_'+ obj.name +'_summary .w2ui-grid-data-last'); + // remove on left + if (colStart > obj.last.colStart) { + for (var i = obj.last.colStart; i < colStart; i++) { + $box.find('#grid_'+ obj.name +'_columns #grid_'+ obj.name +'_column_'+ i).remove(); // column + $box.find('#grid_'+ obj.name +'_records td[col="'+ i +'"]').remove(); // record + $box.find('#grid_'+ obj.name +'_summary td[col="'+ i +'"]').remove(); // summary + } + } + // remove on right + if (colEnd < obj.last.colEnd) { + for (var i = obj.last.colEnd; i > colEnd; i--) { + $box.find('#grid_'+ obj.name +'_columns #grid_'+ obj.name +'_column_'+ i).remove(); // column + $box.find('#grid_'+ obj.name +'_records td[col="'+ i +'"]').remove(); // record + $box.find('#grid_'+ obj.name +'_summary td[col="'+ i +'"]').remove(); // summary + } + } + // add on left + if (colStart < obj.last.colStart) { + for (var i = obj.last.colStart - 1; i >= colStart; i--) { + if (obj.columns[i] && (obj.columns[i].frozen || obj.columns[i].hidden)) continue; + $cfirst.after(obj.getColumnCellHTML(i)); // column + // record + $rfirst.each(function (ind, el) { + var index = $(el).parent().attr('index'); + var td = ''; // width column + if (index != null) td = obj.getCellHTML(parseInt(index), i, false); + $(el).after(td); + }); + // summary + $sfirst.each(function (ind, el) { + var index = $(el).parent().attr('index'); + var td = ''; // width column + if (index != null) td = obj.getCellHTML(parseInt(index), i, true); + $(el).after(td); + }); + } + } + // add on right + if (colEnd > obj.last.colEnd) { + for (var i = obj.last.colEnd + 1; i <= colEnd; i++) { + if (obj.columns[i] && (obj.columns[i].frozen || obj.columns[i].hidden)) continue; + $clast.before(obj.getColumnCellHTML(i)); // column + // record + $rlast.each(function (ind, el) { + var index = $(el).parent().attr('index'); + var td = ''; // width column + if (index != null) td = obj.getCellHTML(parseInt(index), i, false); + $(el).before(td); + }); + // summary + $slast.each(function (ind, el) { + var index = $(el).parent().attr('index') || -1; + var td = obj.getCellHTML(parseInt(index), i, true); + $(el).before(td); + }); + } + } + obj.last.colStart = colStart; + obj.last.colEnd = colEnd; + obj.resizeRecords(); + } else { + obj.last.colStart = colStart; + obj.last.colEnd = colEnd; + // dot not just call obj.refresh(); + var colHTML = this.getColumnsHTML(); + var recHTML = this.getRecordsHTML(); + var sumHTML = this.getSummaryHTML(); + var $columns = $box.find('#grid_'+ this.name +'_columns'); + var $records = $box.find('#grid_'+ this.name +'_records'); + var $frecords = $box.find('#grid_'+ this.name +'_frecords'); + var $summary = $box.find('#grid_'+ this.name +'_summary'); + $columns.find('tbody').html(colHTML[1]); + $frecords.html(recHTML[0]); + $records.prepend(recHTML[1]); + if (sumHTML != null) $summary.html(sumHTML[1]); + // need timeout to clean up (otherwise scroll problem) + setTimeout(function () { + $records.find('> table').not('table:first-child').remove(); + if ($summary[0]) $summary[0].scrollLeft = obj.last.scrollLeft; + }, 1); + obj.resizeRecords(); + } + } + } + // perform virtual scroll + var buffered = this.records.length; + if (buffered > this.total && this.total !== -1) buffered = this.total; + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length; + if (buffered === 0 || records.length === 0 || records.height() === 0) return; + if (buffered > this.vs_start) this.last.show_extra = this.vs_extra; else this.last.show_extra = this.vs_start; + // update footer + var t1 = Math.round(records[0].scrollTop / this.recordHeight + 1); + var t2 = t1 + (Math.round(records.height() / this.recordHeight) - 1); + if (t1 > buffered) t1 = buffered; + if (t2 >= buffered - 1) t2 = buffered; + $('#grid_'+ this.name + '_footer .w2ui-footer-right').html( + (obj.show.statusRange + ? w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + + (this.total != -1 ? ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) : '') + : '') + + (url && obj.show.statusBuffered ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(buffered) + + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') + ); + // only for local data source, else no extra records loaded + if (!url && (!this.fixedBody || (this.total != -1 && this.total <= this.vs_start))) return; + // regular processing + var start = Math.floor(records[0].scrollTop / this.recordHeight) - this.last.show_extra; + var end = start + Math.floor(records.height() / this.recordHeight) + this.last.show_extra * 2 + 1; + // var div = start - this.last.range_start; + if (start < 1) start = 1; + if (end > this.total && this.total != -1) end = this.total; + var tr1 = records.find('#grid_'+ this.name +'_rec_top'); + var tr2 = records.find('#grid_'+ this.name +'_rec_bottom'); + var tr1f = frecords.find('#grid_'+ this.name +'_frec_top'); + var tr2f = frecords.find('#grid_'+ this.name +'_frec_bottom'); + // if row is expanded + if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) { + tr1.next().remove(); + tr1f.next().remove(); + } + if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) { + tr2.prev().remove(); + tr2f.prev().remove(); + } + var first = parseInt(tr1.next().attr('line')); + var last = parseInt(tr2.prev().attr('line')); + //$('#log').html('buffer: '+ this.buffered +' start-end: ' + start + '-'+ end + ' ===> first-last: ' + first + '-' + last); + if (first < start || first == 1 || this.last.pull_refresh) { // scroll down + if (end <= last + this.last.show_extra - 2 && end != this.total) return; + this.last.pull_refresh = false; + // remove from top + while (true) { + var tmp1 = frecords.find('#grid_'+ this.name +'_frec_top').next(); + var tmp2 = records.find('#grid_'+ this.name +'_rec_top').next(); + if (tmp2.attr('line') == 'bottom') break; + if (parseInt(tmp2.attr('line')) < start) { tmp1.remove(); tmp2.remove(); } else break; + } + // add at bottom + var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); + var rec_start = tmp.attr('line'); + if (rec_start == 'top') rec_start = start; + for (var i = parseInt(rec_start) + 1; i <= end; i++) { + if (!this.records[i-1]) continue; + var tmp2 = this.records[i-1].w2ui; + if (tmp2 && !Array.isArray(tmp2.children)) { + tmp2.expanded = false; + } + var rec_html = this.getRecordHTML(i-1, i); + tr2.before(rec_html[1]); + tr2f.before(rec_html[0]); + } + markSearch(); + setTimeout(function() { obj.refreshRanges(); }, 0); + } else { // scroll up + if (start >= first - this.last.show_extra + 2 && start > 1) return; + // remove from bottom + while (true) { + var tmp1 = frecords.find('#grid_'+ this.name +'_frec_bottom').prev(); + var tmp2 = records.find('#grid_'+ this.name +'_rec_bottom').prev(); + if (tmp2.attr('line') == 'top') break; + if (parseInt(tmp2.attr('line')) > end) { tmp1.remove(); tmp2.remove(); } else break; + } + // add at top + var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); + var rec_start = tmp.attr('line'); + if (rec_start == 'bottom') rec_start = end; + for (var i = parseInt(rec_start) - 1; i >= start; i--) { + if (!this.records[i-1]) continue; + var tmp2 = this.records[i-1].w2ui; + if (tmp2 && !Array.isArray(tmp2.children)) { + tmp2.expanded = false; + } + var rec_html = this.getRecordHTML(i-1, i); + tr1.after(rec_html[1]); + tr1f.after(rec_html[0]); + } + markSearch(); + setTimeout(function() { obj.refreshRanges(); }, 0); + } + // first/last row size + var h1 = (start - 1) * obj.recordHeight; + var h2 = (buffered - end) * this.recordHeight; + if (h2 < 0) h2 = 0; + tr1.css('height', h1 + 'px'); + tr1f.css('height', h1 + 'px'); + tr2.css('height', h2 + 'px'); + tr2f.css('height', h2 + 'px'); + obj.last.range_start = start; + obj.last.range_end = end; + // load more if needed + var s = Math.floor(records[0].scrollTop / this.recordHeight); + var e = s + Math.floor(records.height() / this.recordHeight); + if (e + 10 > buffered && this.last.pull_more !== true && (buffered < this.total - this.offset || (this.total == -1 && this.last.xhr_hasMore))) { + if (this.autoLoad === true) { + this.last.pull_more = true; + this.last.xhr_offset += this.limit; + this.request('get'); + } + // scroll function + var more = $('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more'); + more.show() + .eq(1) // only main table + .off('.load-more') + .on('click.load-more', function () { + // show spinner + $(this).find('td').html('
'); + // load more + obj.last.pull_more = true; + obj.last.xhr_offset += obj.limit; + obj.request('get'); + }) + .find('td') + .html(obj.autoLoad + ? '
' + : '
'+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
' + ) + } + + function markSearch() { + // mark search + if (!obj.markSearch) return; + clearTimeout(obj.last.marker_timer); + obj.last.marker_timer = setTimeout(function () { + // mark all search strings + var search = []; + for (var s = 0; s < obj.searchData.length; s++) { + var sdata = obj.searchData[s]; + var fld = obj.getSearch(sdata.field); + if (!fld || fld.hidden) continue; + var ind = obj.getColumn(sdata.field, true); + search.push({ field: sdata.field, search: sdata.value, col: ind }); + } + if (search.length > 0) { + search.forEach(function (item) { + $(obj.box).find('td[col="'+ item.col +'"]').not('.w2ui-head').w2marker(item.search); + }); + } + }, 50); + } + }, + + getRecordHTML: function (ind, lineNum, summary) { + var tmph = ''; + var rec_html1 = ''; + var rec_html2 = ''; + var sel = this.last.selection; + var record; + // first record needs for resize purposes + if (ind == -1) { + rec_html1 += ''; + rec_html2 += ''; + if (this.show.lineNumbers) rec_html1 += ''; + if (this.show.selectColumn) rec_html1 += ''; + if (this.show.expandColumn) rec_html1 += ''; + rec_html2 += ''; + if (this.show.orderColumn) rec_html2 += ''; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + tmph = ''; + if (col.frozen && !col.hidden) { + rec_html1 += tmph; + } else { + if (col.hidden || i < this.last.colStart || i > this.last.colEnd) continue; + rec_html2 += tmph; + } + } + rec_html1 += ''; + rec_html2 += ''; + rec_html1 += ''; + rec_html2 += ''; + return [rec_html1, rec_html2]; + } + // regular record + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (summary !== true) { + if (this.searchData.length > 0 && !url) { + if (ind >= this.last.searchIds.length) return ''; + ind = this.last.searchIds[ind]; + record = this.records[ind]; + } else { + if (ind >= this.records.length) return ''; + record = this.records[ind]; + } + } else { + if (ind >= this.summary.length) return ''; + record = this.summary[ind]; + } + if (!record) return ''; + if (record.recid == null && this.recid != null) { + var rid = this.parseField(record, this.recid) + if (rid != null) record.recid = rid; + } + var id = w2utils.escapeId(record.recid); + var isRowSelected = false; + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true; + var rec_style = (record.w2ui ? record.w2ui.style : ''); + if (rec_style == null || typeof rec_style != 'string') rec_style = ''; + var rec_class = (record.w2ui ? record.w2ui.class : ''); + if (rec_class == null || typeof rec_class != 'string') rec_class = ''; + // render TR + rec_html1 += ''; + rec_html2 += ''; + if (this.show.lineNumbers) { + rec_html1 += ''+ + (summary !== true ? this.getLineHTML(lineNum, record) : '') + + ''; + } + if (this.show.selectColumn) { + var hideCB = false; + if (record && record.w2ui && record.w2ui.hideCheckBox === true) hideCB = true; + rec_html1 += + ''+ + (summary !== true && !(record.w2ui && record.w2ui.hideCheckBox === true) ? + '
'+ + ' '+ + '
' + : + '' ) + + ''; + } + if (this.show.expandColumn) { + var tmp_img = ''; + if (record.w2ui && record.w2ui.expanded === true) tmp_img = '-'; else tmp_img = '+'; + if (record.w2ui && record.w2ui.expanded == 'none') tmp_img = ''; + if (record.w2ui && record.w2ui.expanded == 'spinner') tmp_img = '
'; + rec_html1 += + ''+ + (summary !== true ? + '
'+ + ' '+ tmp_img +'
' + : + '' ) + + ''; + } + // insert empty first column + rec_html2 += ''; + if (this.show.orderColumn) { + rec_html2 += + ''+ + (summary !== true ? '
 
' : '' ) + + ''; + } + var col_ind = 0; + var col_skip = 0; + while (true) { + var col_span = 1; + var col = this.columns[col_ind]; + if (col == null) break; + if (col.hidden) { + col_ind++; + if (col_skip > 0) col_skip--; + continue; + } + if (col_skip > 0) { + col_ind++; + if (this.columns[col_ind] == null) break; + record.w2ui.colspan[this.columns[col_ind-1].field] = 0; // need it for other methods + col_skip--; + continue; + } else if (record.w2ui) { + var tmp1 = record.w2ui.colspan; + var tmp2 = this.columns[col_ind].field; + if (tmp1 && tmp1[tmp2] === 0) { + delete tmp1[tmp2]; // if no longer colspan then remove 0 + } + } + // column virtual scroll + if ((col_ind < this.last.colStart || col_ind > this.last.colEnd) && !col.frozen) { + col_ind++; + continue; + } + if (record.w2ui) { + if (typeof record.w2ui.colspan == 'object') { + var span = parseInt(record.w2ui.colspan[col.field]) || null; + if (span > 1) { + // if there are hidden columns, then no colspan on them + var hcnt = 0; + for (var i = col_ind; i < col_ind + span; i++) { + if (i >= this.columns.length) break; + if (this.columns[i].hidden) hcnt++; + } + col_span = span - hcnt; + col_skip = span - 1; + } + } + } + var rec_cell = this.getCellHTML(ind, col_ind, summary, col_span); + if (col.frozen) rec_html1 += rec_cell; else rec_html2 += rec_cell; + col_ind++; + } + rec_html1 += ''; + rec_html2 += ''; + rec_html1 += ''; + rec_html2 += ''; + return [rec_html1, rec_html2]; + }, + + getLineHTML: function(lineNum) { + return '
' + lineNum + '
'; + }, + + getCellHTML: function (ind, col_ind, summary, col_span) { + var obj = this; + var col = this.columns[col_ind]; + if (col == null) return ''; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = (ind !== -1 ? this.getCellValue(ind, col_ind, summary) : ''); + var edit = (ind !== -1 ? this.getCellEditable(ind, col_ind) : ''); + var style = 'max-height: '+ parseInt(this.recordHeight) +'px;' + (col.clipboardCopy ? 'margin-right: 20px' : ''); + var isChanged = !summary && record && record.w2ui && record.w2ui.changes && record.w2ui.changes[col.field] != null; + var addStyle = ''; + var addClass = ''; + var sel = this.last.selection; + var isRowSelected = false; + var infoBubble = ''; + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true; + if (col_span == null) { + if (record && record.w2ui && record.w2ui.colspan && record.w2ui.colspan[col.field]) { + col_span = record.w2ui.colspan[col.field]; + } else { + col_span = 1; + } + } + // expand icon + if (col_ind === 0 && record && record.w2ui && Array.isArray(record.w2ui.children)) { + var level = 0; + var subrec = this.get(record.w2ui.parent_recid, true); + while (true) { + if (subrec != null) { + level++ + var tmp = this.records[subrec].w2ui; + if (tmp != null && tmp.parent_recid != null) { + subrec = this.get(tmp.parent_recid, true); + } else { + break; + } + } else { + break; + } + } + if (record.w2ui.parent_recid){ + for (var i = 0; i < level; i++) { + infoBubble += ''; + } + } + infoBubble += ''; + } + // info bubble + if (col.info === true) col.info = {}; + if (col.info != null) { + var infoIcon = 'w2ui-icon-info'; + if (typeof col.info.icon == 'function') { + infoIcon = col.info.icon(record); + } else if (typeof col.info.icon == 'object') { + infoIcon = col.info.icon[this.parseField(record, col.field)] || '' + } else if (typeof col.info.icon == 'string') { + infoIcon = col.info.icon; + } + var infoStyle = col.info.style || ''; + if (typeof col.info.style == 'function') { + infoStyle = col.info.style(record); + } else if (typeof col.info.style == 'object') { + infoStyle = col.info.style[this.parseField(record, col.field)] || ''; + } else if (typeof col.info.style == 'string') { + infoStyle = col.info.style; + } + infoBubble += ''; + } + if (col.render != null && ind !== -1) { + if (typeof col.render == 'function') { + var html = col.render.call(this, record, ind, col_ind, data); + if (html != null && typeof html == 'object') { + data = $.trim(html.html || ''); + addClass = html.class || ''; + addStyle = html.style || ''; + } else { + data = $.trim(html); + } + if (data.length < 4 || data.substr(0, 4).toLowerCase() != '' + infoBubble + String(data) + '
'; + } + } + // if it is an object + if (typeof col.render == 'object') { + var dsp = col.render[data]; + if (dsp == null || dsp === '') dsp = data; + data = '
' + infoBubble + String(dsp) + '
'; + } + // formatters + if (typeof col.render == 'string') { + var t = col.render.toLowerCase().indexOf(':'); + var tmp = []; + if (t == -1) { + tmp[0] = col.render.toLowerCase(); + tmp[1] = ''; + } else { + tmp[0] = col.render.toLowerCase().substr(0, t); + tmp[1] = col.render.toLowerCase().substr(t+1); + } + // formatters + var func = w2utils.formatters[tmp[0]]; + if (col.options && col.options.autoFormat === false) { + func = null; + } + data = (typeof func == 'function' ? func(data, tmp[1], record) : ''); + data = '
' + infoBubble + String(data) + '
'; + } + } else { + // if editable checkbox + if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { + var changeInd = summary ? -(ind + 1) : ind; + style += 'text-align: center;'; + data = ''; + infoBubble = ''; + } + data = '
' + infoBubble + String(data) + '
'; + } + if (data == null) data = ''; + // --> cell TD + if (typeof col.render == 'string') { + var tmp = col.render.toLowerCase().split(':'); + if (['number', 'int', 'float', 'money', 'currency', 'percent', 'size'].indexOf(tmp[0]) != -1) addStyle += 'text-align: right;'; + } + if (record && record.w2ui) { + if (typeof record.w2ui.style == 'object') { + if (typeof record.w2ui.style[col_ind] == 'string') addStyle += record.w2ui.style[col_ind] + ';'; + if (typeof record.w2ui.style[col.field] == 'string') addStyle += record.w2ui.style[col.field] + ';'; + } + if (typeof record.w2ui.class == 'object') { + if (typeof record.w2ui.class[col_ind] == 'string') addClass += record.w2ui.class[col_ind] + ' '; + if (typeof record.w2ui.class[col.field] == 'string') addClass += record.w2ui.class[col.field] + ' '; + } + } + var isCellSelected = false; + if (isRowSelected && $.inArray(col_ind, sel.columns[ind]) != -1) isCellSelected = true; + var clipboardTxt = (typeof col.clipboardCopy == 'string' ? col.clipboardCopy : 'Copy to clipboard') + var clipboardIcon = '' + // data + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>' + data + (w2utils.stripTags(data) != '' && col.clipboardCopy && clipboardTxt ? clipboardIcon : '') +''; + // summary top row + if (ind === -1 && summary === true) { + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>'; + } + return data; + + function getTitle(cellData){ + var title = ""; + if (obj.show.recordTitles) { + if (col.title != null) { + if (typeof col.title == 'function') title = col.title.call(obj, record, ind, col_ind); + if (typeof col.title == 'string') title = col.title; + } else { + title = w2utils.stripTags(String(cellData).replace(/"/g, "''")); + } + } + return (title != null) ? String(title) : ""; + } + }, + + clipboardCopy: function (ind, col_ind) { + var rec = this.records[ind] + var col = this.columns[col_ind] + var txt = (col ? this.parseField(rec, col.field) : ''); + if (typeof col.clipboardCopy == 'function') { + txt = col.clipboardCopy(rec) + } + $('#grid_' + this.name + '_focus').text(txt).select(); + document.execCommand('copy'); + }, + + showBubble: function (ind, col_ind) { + var html = ''; + var info = this.columns[col_ind].info; + var rec = this.records[ind]; + var el = $(this.box).find('#grid_'+ this.name +'_data_'+ ind +'_'+ col_ind + ' .w2ui-info'); + if (this.last.bubbleEl) $(this.last.bubbleEl).w2tag(); + this.last.bubbleEl = el; + // if no fields defined - show all + if (info.fields == null) { + info.fields = []; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + info.fields.push(col.field + (typeof col.render == 'string' ? ':' + col.render : '')); + } + } + var fields = info.fields; + if (typeof fields == 'function') { + fields = fields(rec, ind, col_ind); // custom renderer + } + // generate html + if (typeof info.render == 'function') { + html = info.render(rec, ind, col_ind); + + } else if ($.isArray(fields)) { + // display mentioned fields + html = ''; + for (var i = 0; i < fields.length; i++) { + var tmp = String(fields[i]).split(':'); + if (tmp[0] == '' || tmp[0] == '-' || tmp[0] == '--' || tmp[0] == '---') { + html += ''; + continue; + } + var col = this.getColumn(tmp[0]); + if (col == null) col = { field: tmp[0], caption: tmp[0] }; // if not found in columns + var val = (col ? this.parseField(rec, col.field) : ''); + if (tmp.length > 1) { + if (w2utils.formatters[tmp[1]]) { + val = w2utils.formatters[tmp[1]](val, tmp[2] || null, rec); + } else { + console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') + } + } + if (info.showEmpty !== true && (val == null || val == '')) continue; + if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...'; + html += ''; + } + html += '
' + col.text + '' + ((val === 0 ? '0' : val) || '') + '
'; + } else if ($.isPlainObject(fields)) { + // display some fields + html = ''; + for (var caption in fields) { + var fld = fields[caption]; + if (fld == '' || fld == '-' || fld == '--' || fld == '---') { + html += ''; + continue; + } + var tmp = String(fld).split(':'); + var col = this.getColumn(tmp[0]); + if (col == null) col = { field: tmp[0], caption: tmp[0] }; // if not found in columns + var val = (col ? this.parseField(rec, col.field) : ''); + if (tmp.length > 1) { + if (w2utils.formatters[tmp[1]]) { + val = w2utils.formatters[tmp[1]](val, tmp[2] || null, rec); + } else { + console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') + } + } + if (typeof fld == 'function') { + val = fld(rec, ind, col_ind); + } + if (info.showEmpty !== true && (val == null || val == '')) continue; + if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...'; + html += ''; + } + html += '
' + caption + '' + (val || '') + '
'; + } + $(el).w2tag($.extend({ + html : html, + left : -4, + position : 'bottom|top', + className : 'w2ui-info-bubble', + style : '', + hideOnClick : true + }, info.options || {})); + }, + + // return null or the editable object if the given cell is editable + getCellEditable: function (ind, col_ind) { + var col = this.columns[col_ind]; + var rec = this.records[ind]; + if (!rec || !col) return null; + var edit = (rec.w2ui ? rec.w2ui.editable : null); + if (edit === false) return null; + if (edit == null || edit === true) { + edit = (col ? col.editable : null); + if (typeof(edit) === 'function') { + var data = this.getCellValue(ind, col_ind, false); + // same arguments as col.render() + edit = edit.call(this, rec, ind, col_ind, data); + } + } + return edit; + }, + + getCellValue: function (ind, col_ind, summary) { + var col = this.columns[col_ind]; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = this.parseField(record, col.field); + if (record && record.w2ui && record.w2ui.changes && record.w2ui.changes[col.field] != null) { + data = record.w2ui.changes[col.field]; + } + if ($.isPlainObject(data) /*&& col.editable*/) { //It can be an object btw + if (col.options && col.options.items) { + val=col.options.items.find(function(item){ return item.id==data.id}); + if (val) data=val.text; + else data=data.id; + } else { + if (data.text != null) data = data.text; + if (data.id != null) data = data.id; + } + } + if (data == null) data = ''; + return data; + }, + + getFooterHTML: function () { + return '
'+ + ' '+ + ' '+ + ' '+ + '
'; + }, + + status: function (msg) { + if (msg != null) { + $('#grid_'+ this.name +'_footer').find('.w2ui-footer-left').html(msg); + } else { + // show number of selected + var msgLeft = ''; + var sel = this.getSelection(); + if (sel.length > 0) { + if (this.show.statusSelection && sel.length > 1) { + msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") + ' ' + w2utils.lang('selected'); + } + if (this.show.statusRecordID && sel.length == 1) { + var tmp = sel[0]; + if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column; + msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' '; + } + } + $('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft); + // toolbar + if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); + if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); + } + }, + + lock: function (msg, showSpinner) { + var obj = this; + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(this.box); + setTimeout(function () { + // hide empty msg if any + $(obj.box).find('#grid_'+ obj.name +'_empty_msg').remove(); + w2utils.lock.apply(window, args); + }, 10); + }, + + unlock: function (speed) { + var box = this.box; + setTimeout(function () { + // do not unlock if there is a message + if ($(box).find('.w2ui-message').not('.w2ui-closing').length > 0) return; + w2utils.unlock(box, speed); + }, 25); // needed timer so if server fast, it will not flash + }, + + stateSave: function (returnOnly) { + var obj = this; + if (!w2utils.hasLocalStorage) return null; + var state = { + columns : [], + show : $.extend({}, this.show), + last : { + search : this.last.search, + multi : this.last.multi, + logic : this.last.logic, + label : this.last.label, + field : this.last.field, + scrollTop : this.last.scrollTop, + scrollLeft : this.last.scrollLeft + }, + sortData : [], + searchData : [] + }; + var prop_val; + for (var i = 0; i < this.columns.length; i++) { + var col = obj.columns[i]; + var col_save_obj = {}; + // iterate properties to save + Object.keys(obj.stateColProps).forEach(function(prop, idx) { + if(obj.stateColProps[prop]){ + // check if the property is defined on the column + if(col[prop] !== undefined){ + prop_val = col[prop]; + } else { + // use fallback or null + prop_val = obj.stateColDefaults[prop] || null; + } + col_save_obj[prop] = prop_val; + } + }); + state.columns.push(col_save_obj); + } + for (var i = 0; i < this.sortData.length; i++) state.sortData.push($.extend({}, this.sortData[i])); + for (var i = 0; i < this.searchData.length; i++) state.searchData.push($.extend({}, this.searchData[i])); + // save into local storage + if (returnOnly !== true) { + // event before + var edata = this.trigger({ phase: 'before', type: 'stateSave', target: this.name, state: state }); + if (edata.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + try { + var savedState = $.parseJSON(localStorage.w2ui || '{}'); + if (!savedState) savedState = {}; + if (!savedState.states) savedState.states = {}; + savedState.states[(this.stateId || this.name)] = state; + localStorage.w2ui = JSON.stringify(savedState); + } catch (e) { + delete localStorage.w2ui; + return null; + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + } + return state; + }, + + stateRestore: function (newState) { + var obj = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!newState) { + // read it from local storage + try { + if (!w2utils.hasLocalStorage) return false; + var tmp = $.parseJSON(localStorage.w2ui || '{}'); + if (!tmp) tmp = {}; + if (!tmp.states) tmp.states = {}; + newState = tmp.states[(this.stateId || this.name)]; + } catch (e) { + delete localStorage.w2ui; + return null; + } + } + // event before + var edata = this.trigger({ phase: 'before', type: 'stateRestore', target: this.name, state: newState }); + if (edata.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + // default behavior + if ($.isPlainObject(newState)) { + $.extend(this.show, newState.show); + $.extend(this.last, newState.last); + var sTop = this.last.scrollTop; + var sLeft = this.last.scrollLeft; + for (var c = 0; c < newState.columns.length; c++) { + var tmp = newState.columns[c]; + var col_index = this.getColumn(tmp.field, true); + if (col_index !== null) { + $.extend(this.columns[col_index], tmp); + // restore column order from saved state + if (c !== col_index) this.columns.splice(c, 0, this.columns.splice(col_index, 1)[0]); + } + } + this.sortData.splice(0, this.sortData.length); + for (var c = 0; c < newState.sortData.length; c++) this.sortData.push(newState.sortData[c]); + this.searchData.splice(0, this.searchData.length); + for (var c = 0; c < newState.searchData.length; c++) this.searchData.push(newState.searchData[c]); + // apply sort and search + setTimeout(function () { + // needs timeout as records need to be populated + // ez 10.09.2014 this --> + if (!url) { + if (obj.sortData.length > 0) obj.localSort(); + if (obj.searchData.length > 0) obj.localSearch(); + } + obj.last.scrollTop = sTop; + obj.last.scrollLeft = sLeft; + obj.refresh(); + }, 1); + } + // event after + this.trigger($.extend(edata, { phase: 'after' })); + return true; + }, + + stateReset: function () { + var obj = this; + this.stateRestore(this.last.state); + // remove from local storage + if (w2utils.hasLocalStorage) { + try { + var tmp = $.parseJSON(localStorage.w2ui || '{}'); + if (tmp.states && tmp.states[(this.stateId || this.name)]) { + delete tmp.states[(this.stateId || this.name)]; + } + localStorage.w2ui = JSON.stringify(tmp); + } catch (e) { + delete localStorage.w2ui; + return null; + } + } + }, + + parseField: function (obj, field) { + if (this.nestedFields) { + var val = ''; + try { // need this to make sure no error in fields + val = obj; + var tmp = String(field).split('.'); + for (var i = 0; i < tmp.length; i++) { + val = val[tmp[i]]; + } + } catch (event) { + val = ''; + } + return val; + } else { + return obj ? obj[field] : ''; + } + }, + + prepareData: function () { + var obj = this; + + // loops thru records and prepares date and time objects + for (var r = 0; r < this.records.length; r++) { + var rec = this.records[r]; + prepareRecord(rec); + } + + // prepare date and time objects for the 'rec' record and its closed children + function prepareRecord(rec) { + for (var c = 0; c < obj.columns.length; c++) { + var column = obj.columns[c]; + if (rec[column.field] == null || typeof column.render != 'string') continue; + // number + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { + if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]); + } + // date + if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { + if (!rec[column.field + '_']) { + var dt = rec[column.field]; + if (w2utils.isInt(dt)) dt = parseInt(dt); + rec[column.field + '_'] = new Date(dt); + } + } + // time + if (['time'].indexOf(column.render) != -1) { + if (w2utils.isTime(rec[column.field])) { // if string + var tmp = w2utils.isTime(rec[column.field], true); + var dt = new Date(); + dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0); // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt; + } else { // if date object + var tmp = rec[column.field]; + if (w2utils.isInt(tmp)) tmp = parseInt(tmp); + var tmp = (tmp != null ? new Date(tmp) : new Date()); + var dt = new Date(); + dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0); // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt; + } + } + } + + if (rec.w2ui && rec.w2ui.children && rec.w2ui.expanded !== true) { + // there are closed children, prepare them too. + for (var r = 0; r < rec.w2ui.children.length; r++) { + var subRec = rec.w2ui.children[r]; + prepareRecord(subRec); + } + } + } + }, + + nextCell: function (index, col_ind, editable) { + var check = col_ind + 1; + if (check >= this.columns.length) return null; + var tmp = this.records[index].w2ui; + var ccol = this.columns[col_ind]; + // if (tmp && tmp.colspan[ccol.field]) check += parseInt(tmp.colspan[ccol.field]) -1; // colspan of a column + var col = this.columns[check]; + var span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); + if (col == null) return null; + if (col && col.hidden || span === 0) return this.nextCell(index, check, editable); + if (editable) { + var edit = this.getCellEditable(index, col_ind); + if (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1) { + return this.nextCell(index, check, editable); + } + } + return check; + }, + + prevCell: function (index, col_ind, editable) { + var check = col_ind - 1; + if (check < 0) return null; + var tmp = this.records[index].w2ui; + var col = this.columns[check]; + var span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); + if (col == null) return null; + if (col && col.hidden || span === 0) return this.prevCell(index, check, editable); + if (editable) { + var edit = this.getCellEditable(index, col_ind); + if (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1) { + return this.prevCell(index, check, editable); + } + } + return check; + }, + + nextRow: function (ind, col_ind) { + var sids = this.last.searchIds; + var ret = null; + if ((ind + 1 < this.records.length && sids.length === 0) // if there are more records + || (sids.length > 0 && ind < sids[sids.length-1])) { + ind++; + if (sids.length > 0) while (true) { + if ($.inArray(ind, sids) != -1 || ind > this.records.length) break; + ind++; + } + // colspan + var tmp = this.records[ind].w2ui; + var col = this.columns[col_ind]; + var span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); + if (span === 0) { + ret = this.nextRow(ind, col_ind); + } else { + ret = ind; + } + } + return ret; + }, + + prevRow: function (ind, col_ind) { + var sids = this.last.searchIds; + var ret = null; + if ((ind > 0 && sids.length === 0) // if there are more records + || (sids.length > 0 && ind > sids[0])) { + ind--; + if (sids.length > 0) while (true) { + if ($.inArray(ind, sids) != -1 || ind < 0) break; + ind--; + } + // colspan + var tmp = this.records[ind].w2ui; + var col = this.columns[col_ind]; + var span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); + if (span === 0) { + ret = this.prevRow(ind, col_ind); + } else { + ret = ind; + } + } + return ret; + }, + + selectionSave: function () { + this.last._selection = this.getSelection(); + return this.last._selection; + }, + + selectionRestore: function (noRefresh) { + var time = (new Date()).getTime(); + this.last.selection = { indexes: [], columns: {} }; + var sel = this.last.selection; + var lst = this.last._selection; + if (lst) for (var i = 0; i < lst.length; i++) { + if ($.isPlainObject(lst[i])) { + // selectType: cell + var tmp = this.get(lst[i].recid, true); + if (tmp != null) { + if (sel.indexes.indexOf(tmp) == -1) sel.indexes.push(tmp); + if (!sel.columns[tmp]) sel.columns[tmp] = []; + sel.columns[tmp].push(lst[i].column); + } + } else { + // selectType: row + var tmp = this.get(lst[i], true); + if (tmp != null) sel.indexes.push(tmp); + } + } + delete this.last._selection; + if (noRefresh !== true) this.refresh(); + return (new Date()).getTime() - time; + }, + + message: function(options, callBack) { + if (typeof options == 'string') { + options = { + width : (options.length < 300 ? 350 : 550), + height : (options.length < 300 ? 170: 250), + body : '
' + options + '
', + buttons : '', + onOpen : function (event) { + setTimeout(function () { + $(this.box).find('.w2ui-btn').focus(); + }, 25); + }, + onClose: function (even) { + if (typeof callBack == 'function') callBack(); + } + }; + } + w2utils.message.call(this, { + box : this.box, + path : 'w2ui.' + this.name, + title : '.w2ui-grid-header:visible', + body : '.w2ui-grid-box' + }, options); + } + } + + $.extend(w2grid.prototype, w2utils.event); + w2obj.grid = w2grid; +})(jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2layout - layout widget +* - $().w2layout - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2toolbar, w2tabs +* +* == changes +* - negative values for left, right panel +* - onResize for layout as well as onResizing +* - panel.callBack - one time +* - layout.html().replaced(function () {}) +* +* == NICE TO HAVE == +* - onResize for the panel +* - add more panel title positions (left=rotated, right=rotated, bottom) +* - bug: when you assign content before previous transition completed. +* +************************************************************************/ + +(function ($) { + var w2layout = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.panels = []; + this.tmp = {}; + this.padding = 1; // panel padding + this.resizer = 4; // resizer width or height + this.style = ''; + + $.extend(true, this, w2obj.layout, options); + }; + + var w2panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2layout = function(method) { + if ($.isPlainObject(method)) { + // check name parameter + if (!w2utils.checkName(method, 'w2layout')) return; + var panels = method.panels || []; + var object = new w2layout(method); + $.extend(object, { handlers: [], panels: [] }); + // add defined panels + for (var p = 0, len = panels.length; p < len; p++) { + object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, panels[p]); + if ($.isPlainObject(object.panels[p].tabs) || $.isArray(object.panels[p].tabs)) initTabs(object, panels[p].type); + if ($.isPlainObject(object.panels[p].toolbar) || $.isArray(object.panels[p].toolbar)) initToolbar(object, panels[p].type); + } + // add all other panels + for (var p1 = 0; p1 < w2panels.length; p1++) { + if (object.get(w2panels[p1]) != null) continue; + object.panels.push($.extend(true, {}, w2layout.prototype.panel, { type: w2panels[p1], hidden: (w2panels[p1] !== 'main'), size: 50 })); + } + w2ui[object.name] = object; + if ($(this).length > 0) { + object.render($(this)[0]); + } + return object; + + } else { + var obj = w2ui[$(this).attr('name')]; + if (!obj) return null; + if (arguments.length > 0) { + if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + return obj; + } + } + + function initTabs(object, panel, tabs) { + var pan = object.get(panel); + if (pan != null && tabs == null) tabs = pan.tabs; + if (pan == null || tabs == null) return false; + // instanciate tabs + if ($.isArray(tabs)) tabs = { tabs: tabs }; + $().w2destroy(object.name + '_' + panel + '_tabs'); // destroy if existed + pan.tabs = $().w2tabs($.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })); + pan.show.tabs = true; + return true; + } + + function initToolbar(object, panel, toolbar) { + var pan = object.get(panel); + if (pan != null && toolbar == null) toolbar = pan.toolbar; + if (pan == null || toolbar == null) return false; + // instanciate toolbar + if ($.isArray(toolbar)) toolbar = { items: toolbar }; + $().w2destroy(object.name + '_' + panel + '_toolbar'); // destroy if existed + pan.toolbar = $().w2toolbar($.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })); + pan.show.toolbar = true; + return true; + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2layout.prototype = { + onShow : null, + onHide : null, + onResizing : null, + onResizerClick: null, + onRender : null, + onRefresh : null, + onContent : null, + onResize : null, + onDestroy : null, + + // default setting for a panel + panel: { + type : null, // left, right, top, bottom + title : '', + size : 100, // width or height depending on panel name + minSize : 20, + maxSize : false, + hidden : false, + resizable : false, + overflow : 'auto', + style : '', + content : '', // can be String or Object with .render(box) method + tabs : null, + toolbar : null, + width : null, // read only + height : null, // read only + show : { + toolbar : false, + tabs : false + }, + callBack : null, // function to call when content is overwritten + onRefresh : null, + onShow : null, + onHide : null + }, + + // alias for content + content: function (panel, data, transition) { + console.log('NOTICE: layout.content method is deprecated, please use layout.html() instead'); + return this.html(panel, data, transition); + }, + + html: function (panel, data, transition) { + var obj = this; + var p = this.get(panel); + var promise = { + panel : panel, + html : p.content, + error : false, + cancelled : false, + removed : function (callBack) { + if (typeof callBack == 'function') { + p.callBack = callBack + } + } + } + if (typeof p.callBack == 'function') { + p.callBack({ panel: panel, content: p.content, new_content: data, transition: transition || 'none' }); + p.callBack = null; // this is one time call back only + } + // if it is CSS panel + if (panel == 'css') { + $('#layout_'+ obj.name +'_panel_css').html(''); + promise.status = true; + return promise; + } + if (p == null) { + console.log('ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css') + promise.error = true; + return promise; + } + if (data == null) { + return promise; + } + // event before + var edata = this.trigger({ phase: 'before', type: 'content', target: panel, object: p, content: data, transition: transition }); + if (edata.isCancelled === true) { + promise.cancelled = true; + return promise; + } + + if (data instanceof jQuery) { + console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); + return promise; + } + var pname = '#layout_'+ this.name + '_panel_'+ p.type; + var current = $(pname + '> .w2ui-panel-content'); + var panelTop = 0; + if (current.length > 0) { + $(pname).scrollTop(0); + panelTop = $(current).position().top; + } + if (p.content === '') { + p.content = data; + this.refresh(panel); + } else { + p.content = data; + if (!p.hidden) { + if (transition != null && transition !== '') { + // apply transition + var div1 = $(pname + '> .w2ui-panel-content'); + div1.after('
'); + var div2 = $(pname + '> .w2ui-panel-content.new-panel'); + div1.css('top', panelTop); + div2.css('top', panelTop); + if (typeof data == 'object') { + data.box = div2[0]; // do not do .render(box); + data.render(); + } else { + div2.html(data); + } + w2utils.transition(div1[0], div2[0], transition, function () { + div1.remove(); + div2.removeClass('new-panel'); + div2.css('overflow', p.overflow); + // make sure only one content left + $(pname + '> .w2ui-panel-content').slice(1).remove() + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + }); + } + } + this.refresh(panel); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + return promise; + }, + + message: function(panel, options) { + var obj = this; + if (typeof options == 'string') { + options = { + width : (options.length < 300 ? 350 : 550), + height : (options.length < 300 ? 170: 250), + body : '
' + options + '
', + buttons : '', + onOpen : function (event) { + setTimeout(function () { + $(this.box).find('.w2ui-btn').focus(); + }, 25); + } + }; + } + var p = this.get(panel); + var $el = $('#layout_'+ this.name + '_panel_'+ p.type); + var oldOverflow = $el.css('overflow'); + var oldOnClose; + if (options) { + if (options.onClose) oldOnClose = options.onClose; + options.onClose = function (event) { + if (typeof oldOnClose == 'function') oldOnClose(event); + event.done(function () { + $('#layout_'+ obj.name + '_panel_'+ p.type).css('overflow', oldOverflow); + }); + }; + } + $('#layout_'+ this.name + '_panel_'+ p.type).css('overflow', 'hidden'); + w2utils.message.call(this, { + box : $('#layout_'+ this.name + '_panel_'+ p.type), + param : panel, + path : 'w2ui.' + this.name, + title : '.w2ui-panel-title:visible', + body : '.w2ui-panel-content' + }, options); + }, + + load: function (panel, url, transition, onLoad) { + var obj = this; + if (panel == 'css') { + $.get(url, function (data, status, xhr) { // should always be $.get as it is template + obj.html(panel, xhr.responseText); + if (onLoad) onLoad(); + }); + return true; + } + if (this.get(panel) != null) { + $.get(url, function (data, status, xhr) { // should always be $.get as it is template + obj.html(panel, xhr.responseText, transition); + if (onLoad) onLoad(); + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + }); + return true; + } + return false; + }, + + sizeTo: function (panel, size, instant) { + var obj = this; + var pan = obj.get(panel); + if (pan == null) return false; + // resize + $(obj.box).find(' > div > .w2ui-panel') + .css(w2utils.cssPrefix('transition', (instant !== true ? '.2s' : '0s'))); + setTimeout(function () { + obj.set(panel, { size: size }); + }, 1); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '0s')); + obj.resize(); + }, 500); + return true; + }, + + show: function (panel, immediate) { + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', type: 'show', target: panel, object: this.get(panel), immediate: immediate }); + if (edata.isCancelled === true) return; + + var p = obj.get(panel); + if (p == null) return false; + p.hidden = false; + if (immediate === true) { + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '1' }); + obj.trigger($.extend(edata, { phase: 'after' })); + obj.resize(); + } else { + // resize + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '.2s')); + setTimeout(function () { obj.resize(); }, 1); + // show + setTimeout(function() { + $('#layout_'+ obj.name +'_panel_'+ panel).css({ 'opacity': '1' }); + }, 250); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '0s')); + obj.trigger($.extend(edata, { phase: 'after' })); + obj.resize(); + }, 500); + } + return true; + }, + + hide: function (panel, immediate) { + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', type: 'hide', target: panel, object: this.get(panel), immediate: immediate }); + if (edata.isCancelled === true) return; + + var p = obj.get(panel); + if (p == null) return false; + p.hidden = true; + if (immediate === true) { + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + obj.trigger($.extend(edata, { phase: 'after' })); + obj.resize(); + } else { + // hide + $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '.2s')); + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + setTimeout(function () { obj.resize(); }, 1); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '0s')); + obj.trigger($.extend(edata, { phase: 'after' })); + obj.resize(); + }, 500); + } + return true; + }, + + toggle: function (panel, immediate) { + var p = this.get(panel); + if (p == null) return false; + if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate); + }, + + set: function (panel, options) { + var ind = this.get(panel, true); + if (ind == null) return false; + $.extend(this.panels[ind], options); + // refresh only when content changed + if (options.content != null || options.resizable != null) { + this.refresh(panel); + } + // show/hide resizer + this.resize(); // resize is needed when panel size is changed + return true; + }, + + get: function (panel, returnIndex) { + for (var p = 0; p < this.panels.length; p++) { + if (this.panels[p].type == panel) { + if (returnIndex === true) return p; else return this.panels[p]; + } + } + return null; + }, + + el: function (panel) { + var el = $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content'); + if (el.length != 1) return null; + return el[0]; + }, + + hideToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.toolbar = false; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide(); + this.resize(); + }, + + showToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.toolbar = true; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show(); + this.resize(); + }, + + toggleToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); + }, + + assignToolbar: function (panel, toolbar) { + if (typeof toolbar == 'string' && w2ui[toolbar] != null) toolbar = w2ui[toolbar]; + var pan = this.get(panel); + pan.toolbar = toolbar; + var tmp = $(this.box).find(panel +'> .w2ui-panel-toolbar'); + if (pan.toolbar != null) { + if (tmp.find('[name='+ pan.toolbar.name +']').length === 0) { + tmp.w2render(pan.toolbar); + } else if (pan.toolbar != null) { + pan.toolbar.refresh(); + } + toolbar.owner = this; + this.showToolbar(panel); + this.refresh(panel); + } else { + tmp.html(''); + this.hideToolbar(panel); + } + }, + + hideTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.tabs = false; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide(); + this.resize(); + }, + + showTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.tabs = true; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show(); + this.resize(); + }, + + toggleTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); + }, + + render: function (box) { + var obj = this; + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + var time = (new Date()).getTime(); + // event before + var edata = obj.trigger({ phase: 'before', type: 'render', target: obj.name, box: box }); + if (edata.isCancelled === true) return; + + if (box != null) { + if ($(obj.box).find('#layout_'+ obj.name +'_panel_main').length > 0) { + $(obj.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html(''); + } + obj.box = box; + } + if (!obj.box) return false; + $(obj.box) + .attr('name', obj.name) + .addClass('w2ui-layout') + .html('
'); + if ($(obj.box).length > 0) $(obj.box)[0].style.cssText += obj.style; + // create all panels + for (var p1 = 0; p1 < w2panels.length; p1++) { + var pan = obj.get(w2panels[p1]); + var html = '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'; + $(obj.box).find(' > div').append(html); + // tabs are rendered in refresh() + } + $(obj.box).find(' > div') + .append('
'); + obj.refresh(); // if refresh is not called here, the layout will not be available right after initialization + // process event + obj.trigger($.extend(edata, { phase: 'after' })); + // reinit events + setTimeout(function () { // needed this timeout to allow browser to render first if there are tabs or toolbar + initEvents(); + obj.resize(); + }, 0); + return (new Date()).getTime() - time; + + function initEvents() { + obj.tmp.events = { + resize : function (event) { + if (w2ui[obj.name] == null) { + $(window).off('resize.w2ui-'+ obj.name); + } else { + w2ui[obj.name].resize(); + } + }, + resizeStart : resizeStart, + mouseMove : resizeMove, + mouseUp : resizeStop + }; + $(window).on('resize.w2ui-'+ obj.name, obj.tmp.events.resize); + } + + function resizeStart(type, evnt) { + if (!obj.box) return; + if (!evnt) evnt = window.event; + $(document).off('mousemove', obj.tmp.events.mouseMove).on('mousemove', obj.tmp.events.mouseMove); + $(document).off('mouseup', obj.tmp.events.mouseUp).on('mouseup', obj.tmp.events.mouseUp); + obj.tmp.resize = { + type : type, + x : evnt.screenX, + y : evnt.screenY, + diff_x : 0, + diff_y : 0, + value : 0 + }; + // lock all panels + for (var p1 = 0; p1 < w2panels.length; p1++) { + var $tmp = $(obj.el(w2panels[p1])).parent().find('.w2ui-lock'); + if ($tmp.length > 0) { + $tmp.attr('locked', 'previous'); + } else { + obj.lock(w2panels[p1], { opacity: 0 }); + } + } + if (type == 'left' || type == 'right') { + obj.tmp.resize.value = parseInt($('#layout_'+ obj.name +'_resizer_'+ type)[0].style.left); + } + if (type == 'top' || type == 'preview' || type == 'bottom') { + obj.tmp.resize.value = parseInt($('#layout_'+ obj.name +'_resizer_'+ type)[0].style.top); + } + } + + function resizeStop(evnt) { + if (!obj.box) return; + if (!evnt) evnt = window.event; + $(document).off('mousemove', obj.tmp.events.mouseMove); + $(document).off('mouseup', obj.tmp.events.mouseUp); + if (obj.tmp.resize == null) return; + // unlock all panels + for (var p1 = 0; p1 < w2panels.length; p1++) { + var $tmp = $(obj.el(w2panels[p1])).parent().find('.w2ui-lock'); + if ($tmp.attr('locked') == 'previous') { + $tmp.removeAttr('locked'); + } else { + obj.unlock(w2panels[p1]); + } + } + // set new size + if (obj.tmp.diff_x !== 0 || obj.tmp.resize.diff_y !== 0) { // only recalculate if changed + var ptop = obj.get('top'); + var pbottom = obj.get('bottom'); + var panel = obj.get(obj.tmp.resize.type); + var height = parseInt($(obj.box).height()); + var width = parseInt($(obj.box).width()); + var str = String(panel.size); + var ns, nd; + switch (obj.tmp.resize.type) { + case 'top': + ns = parseInt(panel.sizeCalculated) + obj.tmp.resize.diff_y; + nd = 0; + break; + case 'bottom': + ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_y; + nd = 0; + break; + case 'preview': + ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_y; + nd = (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) + + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); + break; + case 'left': + ns = parseInt(panel.sizeCalculated) + obj.tmp.resize.diff_x; + nd = 0; + break; + case 'right': + ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_x; + nd = 0; + break; + } + // set size + if (str.substr(str.length-1) == '%') { + panel.size = Math.floor(ns * 100 / (panel.type == 'left' || panel.type == 'right' ? width : height - nd) * 100) / 100 + '%'; + } else { + if (String(panel.size).substr(0, 1) == '-') { + panel.size = parseInt(panel.size) - panel.sizeCalculated + ns; + } else { + panel.size = ns; + } + } + obj.resize(); + } + $('#layout_'+ obj.name + '_resizer_'+ obj.tmp.resize.type).removeClass('active'); + delete obj.tmp.resize; + } + + function resizeMove(evnt) { + if (!obj.box) return; + if (!evnt) evnt = window.event; + if (obj.tmp.resize == null) return; + var panel = obj.get(obj.tmp.resize.type); + // event before + var tmp = obj.tmp.resize; + var edata = obj.trigger({ phase: 'before', type: 'resizing', target: obj.name, object: panel, originalEvent: evnt, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); + if (edata.isCancelled === true) return; + + var p = $('#layout_'+ obj.name + '_resizer_'+ tmp.type); + var resize_x = (evnt.screenX - tmp.x); + var resize_y = (evnt.screenY - tmp.y); + var mainPanel = obj.get('main'); + + if (!p.hasClass('active')) p.addClass('active'); + + switch (tmp.type) { + case 'left': + if (panel.minSize - resize_x > panel.width) { + resize_x = panel.minSize - panel.width; + } + if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { + resize_x = panel.maxSize - panel.width; + } + if (mainPanel.minSize + resize_x > mainPanel.width) { + resize_x = mainPanel.width - mainPanel.minSize; + } + break; + + case 'right': + if (panel.minSize + resize_x > panel.width) { + resize_x = panel.width - panel.minSize; + } + if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { + resize_x = panel.width - panel.maxSize; + } + if (mainPanel.minSize - resize_x > mainPanel.width) { + resize_x = mainPanel.minSize - mainPanel.width; + } + break; + + case 'top': + if (panel.minSize - resize_y > panel.height) { + resize_y = panel.minSize - panel.height; + } + if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { + resize_y = panel.maxSize - panel.height; + } + if (mainPanel.minSize + resize_y > mainPanel.height) { + resize_y = mainPanel.height - mainPanel.minSize; + } + break; + + case 'preview': + case 'bottom': + if (panel.minSize + resize_y > panel.height) { + resize_y = panel.height - panel.minSize; + } + if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { + resize_y = panel.height - panel.maxSize; + } + if (mainPanel.minSize - resize_y > mainPanel.height) { + resize_y = mainPanel.minSize - mainPanel.height; + } + break; + } + tmp.diff_x = resize_x; + tmp.diff_y = resize_y; + + switch (tmp.type) { + case 'top': + case 'preview': + case 'bottom': + tmp.diff_x = 0; + if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'; + break; + + case 'left': + case 'right': + tmp.diff_y = 0; + if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'; + break; + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } + }, + + refresh: function (panel) { + var obj = this; + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (panel == null) panel = null; + var time = (new Date()).getTime(); + // event before + var edata = obj.trigger({ phase: 'before', type: 'refresh', target: (panel != null ? panel : obj.name), object: obj.get(panel) }); + if (edata.isCancelled === true) return; + // obj.unlock(panel); + if (typeof panel == 'string') { + var p = obj.get(panel); + if (p == null) return; + var pname = '#layout_'+ obj.name + '_panel_'+ p.type; + var rname = '#layout_'+ obj.name +'_resizer_'+ p.type; + // apply properties to the panel + $(pname).css({ display: p.hidden ? 'none' : 'block' }); + if (p.resizable) $(rname).show(); else $(rname).hide(); + // insert content + if (typeof p.content == 'object' && typeof p.content.render === 'function') { + p.content.box = $(pname +'> .w2ui-panel-content')[0]; + setTimeout(function () { + // need to remove unnecessary classes + if ($(pname +'> .w2ui-panel-content').length > 0) { + $(pname +'> .w2ui-panel-content') + .removeClass() + .removeAttr('name') + .addClass('w2ui-panel-content') + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; + } + if (p.content && typeof p.content.render == 'function') { + p.content.render(); // do not do .render(box); + } + }, 1); + } else { + // need to remove unnecessary classes + if ($(pname +'> .w2ui-panel-content').length > 0) { + $(pname +'> .w2ui-panel-content') + .removeClass() + .removeAttr('name') + .addClass('w2ui-panel-content') + .html(p.content) + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; + } + } + // if there are tabs and/or toolbar - render it + var tmp = $(obj.box).find(pname +'> .w2ui-panel-tabs'); + if (p.show.tabs) { + if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs != null) tmp.w2render(p.tabs); else p.tabs.refresh(); + } else { + tmp.html('').removeClass('w2ui-tabs').hide(); + } + tmp = $(obj.box).find(pname +'> .w2ui-panel-toolbar'); + if (p.show.toolbar) { + if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar != null) tmp.w2render(p.toolbar); else p.toolbar.refresh(); + } else { + tmp.html('').removeClass('w2ui-toolbar').hide(); + } + // show title + tmp = $(obj.box).find(pname +'> .w2ui-panel-title'); + if (p.title) { + tmp.html(p.title).show(); + } else { + tmp.html('').hide(); + } + } else { + if ($('#layout_'+ obj.name +'_panel_main').length === 0) { + obj.render(); + return; + } + obj.resize(); + // refresh all of them + for (var p1 = 0; p1 < this.panels.length; p1++) { obj.refresh(this.panels[p1].type); } + } + obj.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + resize: function () { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (!this.box) return false; + var time = (new Date()).getTime(); + // event before + var tmp = this.tmp.resize; + var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); + if (edata.isCancelled === true) return; + if (this.padding < 0) this.padding = 0; + + // layout itself + var width = parseInt($(this.box).width()); + var height = parseInt($(this.box).height()); + $(this.box).find(' > div').css({ + width : width + 'px', + height : height + 'px' + }); + var obj = this; + // panels + var pmain = this.get('main'); + var pprev = this.get('preview'); + var pleft = this.get('left'); + var pright = this.get('right'); + var ptop = this.get('top'); + var pbottom = this.get('bottom'); + var smain = true; // main always on + var sprev = (pprev != null && pprev.hidden !== true ? true : false); + var sleft = (pleft != null && pleft.hidden !== true ? true : false); + var sright = (pright != null && pright.hidden !== true ? true : false); + var stop = (ptop != null && ptop.hidden !== true ? true : false); + var sbottom = (pbottom != null && pbottom.hidden !== true ? true : false); + var l, t, w, h, e; + // calculate % + for (var p = 0; p < w2panels.length; p++) { + if (w2panels[p] === 'main') continue; + tmp = this.get(w2panels[p]); + if (!tmp) continue; + var str = String(tmp.size || 0); + if (str.substr(str.length-1) == '%') { + var tmph = height; + if (tmp.type == 'preview') { + tmph = tmph - + (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); + } + tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100); + } else { + tmp.sizeCalculated = parseInt(tmp.size); + } + tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)); + } + // negative size + if (String(pright.size).substr(0, 1) == '-') { + if (sleft && String(pleft.size).substr(0, 1) == '-') { + console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.'); + } else { + pright.sizeCalculated = width - (sleft ? pleft.sizeCalculated : 0) + parseInt(pright.size); + } + } + if (String(pleft.size).substr(0, 1) == '-') { + if (sright && pright.size.substr(0, 1) == '-') { + console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.'); + } else { + pleft.sizeCalculated = width - (sright ? pright.sizeCalculated : 0) + parseInt(pleft.size); + } + } + // top if any + if (ptop != null && ptop.hidden !== true) { + l = 0; + t = 0; + w = width; + h = ptop.sizeCalculated; + $('#layout_'+ this.name +'_panel_top').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + ptop.width = w; + ptop.height = h; + // resizer + if (ptop.resizable) { + t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_top').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'top', originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('top', event); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_top').hide(); + $('#layout_'+ this.name +'_resizer_top').hide(); + } + // left if any + if (pleft != null && pleft.hidden !== true) { + l = 0; + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = pleft.sizeCalculated; + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0); + e = $('#layout_'+ this.name +'_panel_left'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pleft.width = w; + pleft.height = h; + // resizer + if (pleft.resizable) { + l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0); + w = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_left').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'left', originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('left', event); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_left').hide(); + $('#layout_'+ this.name +'_resizer_left').hide(); + } + // right if any + if (pright != null && pright.hidden !== true) { + l = width - pright.sizeCalculated; + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = pright.sizeCalculated; + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0); + $('#layout_'+ this.name +'_panel_right').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pright.width = w; + pright.height = h; + // resizer + if (pright.resizable) { + l = l - this.padding; + w = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_right').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'right', originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('right', event); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_right').hide(); + $('#layout_'+ this.name +'_resizer_right').hide(); + } + // bottom if any + if (pbottom != null && pbottom.hidden !== true) { + l = 0; + t = height - pbottom.sizeCalculated; + w = width; + h = pbottom.sizeCalculated; + $('#layout_'+ this.name +'_panel_bottom').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pbottom.width = w; + pbottom.height = h; + // resizer + if (pbottom.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_bottom').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'bottom', originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('bottom', event); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_bottom').hide(); + $('#layout_'+ this.name +'_resizer_bottom').hide(); + } + // main - always there + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding: 0); + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) - + (sprev ? pprev.sizeCalculated + this.padding : 0); + e = $('#layout_'+ this.name +'_panel_main'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }); + pmain.width = w; + pmain.height = h; + + // preview if any + if (pprev != null && pprev.hidden !== true) { + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); + t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding : 0); + h = pprev.sizeCalculated; + e = $('#layout_'+ this.name +'_panel_preview'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pprev.width = w; + pprev.height = h; + // resizer + if (pprev.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_preview').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'preview', originalEvent: event }); + if (edata.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('preview', event); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_preview').hide(); + $('#layout_'+ this.name +'_resizer_preview').hide(); + } + + // display tabs and toolbar if needed + for (var p1 = 0; p1 < w2panels.length; p1++) { + var pan = this.get(w2panels[p1]); + var tmp2 = '#layout_'+ this.name +'_panel_'+ w2panels[p1] +' > .w2ui-panel-'; + var tabHeight = 0; + if (pan) { + if (pan.title) { + tabHeight += w2utils.getSize($(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + if (pan.show.tabs) { + if (pan.tabs != null && w2ui[this.name +'_'+ w2panels[p1] +'_tabs']) w2ui[this.name +'_'+ w2panels[p1] +'_tabs'].resize(); + tabHeight += w2utils.getSize($(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + if (pan.show.toolbar) { + if (pan.toolbar != null && w2ui[this.name +'_'+ w2panels[p1] +'_toolbar']) w2ui[this.name +'_'+ w2panels[p1] +'_toolbar'].resize(); + tabHeight += w2utils.getSize($(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + } + $(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }); + } + // send resize to all objects + clearTimeout(this._resize_timer); + this._resize_timer = setTimeout(function () { + for (var e in w2ui) { + if (typeof w2ui[e].resize == 'function') { + // sent to all none-layouts + if (w2ui[e].panels == null) w2ui[e].resize(); + // only send to nested layouts + var parent = $(w2ui[e].box).parents('.w2ui-layout'); + if (parent.length > 0 && parent.attr('name') == obj.name) w2ui[e].resize(); + } + } + }, 100); + this.trigger($.extend(edata, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var edata = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (edata.isCancelled === true) return; + if (w2ui[this.name] == null) return false; + // clean up + if ($(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(edata, { phase: 'after' })); + if (this.tmp.events && this.tmp.events.resize) $(window).off('resize', this.tmp.events.resize); + return true; + }, + + lock: function (panel, msg, showSpinner) { + if (w2panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.'); + return; + } + var args = Array.prototype.slice.call(arguments, 0); + args[0] = '#layout_'+ this.name + '_panel_' + panel; + w2utils.lock.apply(window, args); + }, + + unlock: function (panel, speed) { + if (w2panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.'); + return; + } + var nm = '#layout_'+ this.name + '_panel_' + panel; + w2utils.unlock(nm, speed); + } + }; + + $.extend(w2layout.prototype, w2utils.event); + w2obj.layout = w2layout; +})(jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2popup - popup widget +* - $().w2popup - jQuery wrapper +* - Dependencies: jQuery, w2utils +* +* == changes +* - added onMove event +* - w2prompt.options.ok_class, cancel_class +* - w2confirm.options.onOpen, w2confirm.options.onClose +* - w2prompt.options.onOpen, w2prompt.options.onClose +* - w2popup.actions, w2popup.action, w2popup.onAction +* - w2popup.onMsgOpen, w2popup.onMsgClose +* - options.multiple +* +* == NICE TO HAVE == +* - hide overlay on esc +* - make popup width/height in % +* +************************************************************************/ + +var w2popup = {}; + +(function ($) { + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2popup = function(method, options) { + if (method == null) { + options = {}; + method = 'open'; + } + if ($.isPlainObject(method)) { + options = method; + method = 'open'; + } + method = method.toLowerCase(); + if (method === 'load' && typeof options === 'string') { + options = $.extend({ url: options }, arguments.length > 2 ? arguments[2] : {}); + } + if (method === 'open' && options.url != null) method = 'load'; + options = options || {}; + // load options from markup + var dlgOptions = {}; + if ($(this).length > 0 && method == 'open') { + if ($(this).find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { + // remember previous tempalte + if ($('#w2ui-popup').length > 0) { + var tmp = $('#w2ui-popup').data('options'); + w2popup._prev = { + template : w2popup._template, + title : tmp.title, + body : tmp.body, + buttons : tmp.buttons + }; + } + w2popup._template = this; + + if ($(this).find('div[rel=title]').length > 0) { + dlgOptions['title'] = $(this).find('div[rel=title]'); + } + if ($(this).find('div[rel=body]').length > 0) { + dlgOptions['body'] = $(this).find('div[rel=body]'); + dlgOptions['style'] = $(this).find('div[rel=body]')[0].style.cssText; + } + if ($(this).find('div[rel=buttons]').length > 0) { + dlgOptions['buttons'] = $(this).find('div[rel=buttons]'); + } + } else { + dlgOptions['title'] = ' '; + dlgOptions['body'] = $(this).html(); + } + if (parseInt($(this).css('width')) !== 0) dlgOptions['width'] = parseInt($(this).css('width')); + //if the popup will have a title bar, we must add the height of title bar to the popup height + var hasTitlebar = options.title || (options.showClose || options.showClose === undefined) || (options.showMax || options.showMax === undefined) ; + if (parseInt($(this).css('height')) !== 0) dlgOptions['height'] = parseInt($(this).css('height')) + (hasTitlebar?32:0); + } + // show popup + return w2popup[method]($.extend({}, dlgOptions, options)); + }; + + // ==================================================== + // -- Implementation of core functionality (SINGLETON) + + w2popup = { + defaults: { + title : '', + body : '', + buttons : '', + style : '', + color : '#000', + opacity : 0.4, + speed : 0.3, + modal : false, + maximized : false, + keyboard : true, // will close popup on esc if not modal + width : 500, + height : 300, + showClose : true, + showMax : false, + transition: null, + multiple : false // if popup already open, opens as a message + }, + status : 'closed', // string that describes current status + handlers : [], + onOpen : null, + onClose : null, + onMax : null, + onMin : null, + onToggle : null, + onKeydown : null, + + open: function (options) { + var obj = this; + var orig_options = $.extend(true, {}, options); + if (w2popup.status == 'closing') { + setTimeout(function () { obj.open.call(obj, options); }, 100); + return; + } + // get old options and merge them + var old_options = $('#w2ui-popup').data('options'); + var options = $.extend({}, this.defaults, old_options, { title: '', body : '', buttons: '' }, options, { maximized: false }); + // need timer because popup might not be open + setTimeout(function () { $('#w2ui-popup').data('options', options); }, 100); + // if new - reset event handlers + if ($('#w2ui-popup').length === 0) { + // w2popup.handlers = []; // if commented, allows to add w2popup.on() for all + w2popup.onMax = null; + w2popup.onMin = null; + w2popup.onToggle = null; + w2popup.onOpen = null; + w2popup.onClose = null; + w2popup.onKeydown = null; + w2popup.onAction = null; + } + if (options.onOpen) w2popup.onOpen = options.onOpen; + if (options.onClose) w2popup.onClose = options.onClose; + if (options.onMax) w2popup.onMax = options.onMax; + if (options.onMin) w2popup.onMin = options.onMin; + if (options.onToggle) w2popup.onToggle = options.onToggle; + if (options.onKeydown) w2popup.onKeydown = options.onKeydown; + if (options.onAction) w2popup.onAction = options.onAction; + options.width = parseInt(options.width); + options.height = parseInt(options.height); + + var maxW, maxH; + if (window.innerHeight == undefined) { + maxW = parseInt(document.documentElement.offsetWidth); + maxH = parseInt(document.documentElement.offsetHeight); + if (w2utils.engine === 'IE7') { maxW += 21; maxH += 4; } + } else { + maxW = parseInt(window.innerWidth); + maxH = parseInt(window.innerHeight); + } + if (maxW - 10 < options.width) options.width = maxW - 10; + if (maxH - 10 < options.height) options.height = maxH - 10; + var top = (maxH - options.height) / 2 * 0.6; + var left = (maxW - options.width) / 2; + + // convert action arrays into buttons + if (options.actions != null) { + options.buttons = ''; + Object.keys(options.actions).forEach(function (action) { + var handler = options.actions[action]; + if (typeof handler == 'function') { + options.buttons += '' + } + if (typeof handler == 'object') { + options.buttons += '' + } + if (typeof handler == 'string') { + options.buttons += handler + } + }); + } + + // check if message is already displayed + if ($('#w2ui-popup').length === 0) { + // trigger event + var edata = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: false }); + if (edata.isCancelled === true) return; + w2popup.status = 'opening'; + // output message + w2popup.lockScreen(options); + var btn = ''; + if (options.showClose) { + btn += '
Close
'; + } + if (options.showMax) { + btn += '
Max
'; + } + // first insert just body + var msg = '
'; + $('body').append(msg); + // parse rel=* + var parts = $('#w2ui-popup'); + if (parts.find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { + // title + var tmp = parts.find('div[rel=title]'); + if (tmp.length > 0) { options.title = tmp.html(); tmp.remove(); } + // buttons + var tmp = parts.find('div[rel=buttons]'); + if (tmp.length > 0) { options.buttons = tmp.html(); tmp.remove(); } + // body + var tmp = parts.find('div[rel=body]'); + if (tmp.length > 0) options.body = tmp.html(); else options.body = parts.html(); + } + // then content + var msg = '
' + btn + '
'+ + '
'+ + '
' + + '
'+ + '
'+ + '
'+ + ''; // this is needed to keep focus in popup + $('#w2ui-popup').html(msg); + + if (options.title) $('#w2ui-popup .w2ui-popup-title').append(options.title); + if (options.buttons) $('#w2ui-popup .w2ui-popup-buttons').append(options.buttons); + if (options.body) $('#w2ui-popup .w2ui-popup-body').append(options.body); + + // allow element to render + setTimeout(function () { + $('#w2ui-popup') + .css(w2utils.cssPrefix({ + 'transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform' + })) + .removeClass("w2ui-popup-opening"); + obj.focus(); + }, 1); + // clean transform + setTimeout(function () { + $('#w2ui-popup').css(w2utils.cssPrefix('transform', '')); + }, options.speed * 1000); + // event after + w2popup.status = 'open'; + obj.trigger($.extend(edata, { phase: 'after' })); + + } else if (options.multiple === true) { + // popup is not compatible with w2popup.message + w2popup.message(orig_options) + } else { + // if was from template and now not + if (w2popup._prev == null && w2popup._template != null) obj.restoreTemplate(); + + // trigger event + var edata = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: true }); + if (edata.isCancelled === true) return; + // check if size changed + w2popup.status = 'opening'; + if (old_options != null) { + if (!old_options.maximized && (old_options['width'] != options['width'] || old_options['height'] != options['height'])) { + w2popup.resize(options.width, options.height); + } + options.prevSize = options.width + 'px:' + options.height + 'px'; + options.maximized = old_options.maximized; + } + // show new items + var cloned = $('#w2ui-popup .w2ui-box').clone(); + cloned.removeClass('w2ui-box').addClass('w2ui-box-temp').find('.w2ui-popup-body').empty().append(options.body); + // parse rel=* + if (typeof options.body == 'string' && cloned.find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { + // title + var tmp = cloned.find('div[rel=title]'); + if (tmp.length > 0) { options['title'] = tmp.html(); tmp.remove(); } + // buttons + var tmp = cloned.find('div[rel=buttons]'); + if (tmp.length > 0) { options['buttons'] = tmp.html(); tmp.remove(); } + // body + var tmp = cloned.find('div[rel=body]'); + if (tmp.length > 0) options['body'] = tmp.html(); else options['body'] = cloned.html(); + // set proper body + cloned.html(options.body); + } + $('#w2ui-popup .w2ui-box').after(cloned); + + if (options.buttons) { + $('#w2ui-popup .w2ui-popup-buttons').show().html('').append(options.buttons); + $('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-buttons'); + $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', ''); + } else { + $('#w2ui-popup .w2ui-popup-buttons').hide().html(''); + $('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-buttons'); + $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', '0px'); + } + if (options.title) { + $('#w2ui-popup .w2ui-popup-title') + .show() + .html((options.showClose ? '
Close
' : '') + + (options.showMax ? '
Max
' : '')) + .append(options.title); + $('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-title'); + $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', ''); + } else { + $('#w2ui-popup .w2ui-popup-title').hide().html(''); + $('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-title'); + $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', '0px'); + } + // transition + var div_old = $('#w2ui-popup .w2ui-box')[0]; + var div_new = $('#w2ui-popup .w2ui-box-temp')[0]; + w2utils.transition(div_old, div_new, options.transition, function () { + // clean up + obj.restoreTemplate(); + $(div_old).remove(); + $(div_new).removeClass('w2ui-box-temp').addClass('w2ui-box'); + var $body = $(div_new).find('.w2ui-popup-body'); + if ($body.length == 1) $body[0].style.cssText = options.style; + // remove max state + $('#w2ui-popup').data('prev-size', null); + // focus on first button + obj.focus(); + }); + // call event onOpen + w2popup.status = 'open'; + obj.trigger($.extend(edata, { phase: 'after' })); + } + + // save new options + options._last_focus = $(':focus'); + // keyboard events + if (options.keyboard) $(document).on('keydown', this.keydown); + + // initialize move + var tmp = { + resizing : false, + mvMove : mvMove, + mvStop : mvStop + }; + $('#w2ui-popup .w2ui-popup-title').on('mousedown', function (event) { + if (!w2popup.get().maximized) mvStart(event); + }); + + return this; + + // handlers + function mvStart(evnt) { + if (!evnt) evnt = window.event; + w2popup.status = 'moving'; + tmp.resizing = true; + tmp.isLocked = $('#w2ui-popup > .w2ui-lock').length == 1 ? true : false; + tmp.x = evnt.screenX; + tmp.y = evnt.screenY; + tmp.pos_x = $('#w2ui-popup').position().left; + tmp.pos_y = $('#w2ui-popup').position().top; + if (!tmp.isLocked) w2popup.lock({ opacity: 0 }); + $(document).on('mousemove', tmp.mvMove); + $(document).on('mouseup', tmp.mvStop); + if (evnt.stopPropagation) evnt.stopPropagation(); else evnt.cancelBubble = true; + if (evnt.preventDefault) evnt.preventDefault(); else return false; + } + + function mvMove(evnt) { + if (tmp.resizing != true) return; + if (!evnt) evnt = window.event; + tmp.div_x = evnt.screenX - tmp.x; + tmp.div_y = evnt.screenY - tmp.y; + // trigger event + var edata = w2popup.trigger({ phase: 'before', type: 'move', target: 'popup', div_x: tmp.div_x, div_y: tmp.div_y }); + if (edata.isCancelled === true) return; + // default behavior + $('#w2ui-popup').css(w2utils.cssPrefix({ + 'transition': 'none', + 'transform' : 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)' + })); + // event after + w2popup.trigger($.extend(edata, { phase: 'after'})); + } + + function mvStop(evnt) { + if (tmp.resizing != true) return; + if (!evnt) evnt = window.event; + w2popup.status = 'open'; + tmp.div_x = (evnt.screenX - tmp.x); + tmp.div_y = (evnt.screenY - tmp.y); + $('#w2ui-popup').css({ + 'left': (tmp.pos_x + tmp.div_x) + 'px', + 'top' : (tmp.pos_y + tmp.div_y) + 'px' + }).css(w2utils.cssPrefix({ + 'transition': 'none', + 'transform' : 'translate3d(0px, 0px, 0px)' + })); + tmp.resizing = false; + $(document).off('mousemove', tmp.mvMove); + $(document).off('mouseup', tmp.mvStop); + if (!tmp.isLocked) w2popup.unlock(); + } + }, + + action: function (action, msgId) { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (msgId != null) { + options = $('#w2ui-message' + msgId).data('options'); + obj = { + parent: this, + options: options, + close: function () { + w2popup.message({ msgId: msgId }) + } + } + } + var act = options.actions[action]; + var click = act; + if ($.isPlainObject(act) && act.onClick) click = act.onClick; + // event before + var edata = this.trigger({ phase: 'before', target: action, msgId: msgId, type: 'action', action: act, originalEvent: event }); + if (edata.isCancelled === true) return; + // default actions + if (typeof click === 'function') click.call(obj, event); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + keydown: function (event) { + var options = $('#w2ui-popup').data('options'); + if (options && !options.keyboard) return; + // trigger event + var edata = w2popup.trigger({ phase: 'before', type: 'keydown', target: 'popup', options: options, originalEvent: event }); + if (edata.isCancelled === true) return; + // default behavior + switch (event.keyCode) { + case 27: + event.preventDefault(); + if ($('#w2ui-popup .w2ui-message').length > 0) w2popup.message(); else w2popup.close(); + break; + } + // event after + w2popup.trigger($.extend(edata, { phase: 'after'})); + }, + + close: function (options) { + var obj = this; + var options = $.extend({}, $('#w2ui-popup').data('options'), options); + if ($('#w2ui-popup').length === 0 || this.status == 'closed') return; + if (this.status == 'opening') { + setTimeout(function () { w2popup.close(); }, 100); + return; + } + // trigger event + var edata = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); + if (edata.isCancelled === true) return; + // default behavior + w2popup.status = 'closing'; + $('#w2ui-popup') + .css(w2utils.cssPrefix({ + 'transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform' + })) + .addClass("w2ui-popup-closing"); + w2popup.unlockScreen(options); + setTimeout(function () { + // return template + obj.restoreTemplate(); + $('#w2ui-popup').remove(); + w2popup.status = 'closed'; + // restore active + if (options._last_focus && options._last_focus.length > 0) options._last_focus.focus(); + // event after + obj.trigger($.extend(edata, { phase: 'after'})); + }, options.speed * 1000); + // remove keyboard events + if (options.keyboard) $(document).off('keydown', this.keydown); + }, + + toggle: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + // trigger event + var edata = this.trigger({ phase: 'before', type: 'toggle', target: 'popup', options: options }); + if (edata.isCancelled === true) return; + // defatul action + if (options.maximized === true) w2popup.min(); else w2popup.max(); + // event after + setTimeout(function () { + obj.trigger($.extend(edata, { phase: 'after'})); + }, (options.speed * 1000) + 50); + }, + + max: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (options.maximized === true) return; + // trigger event + var edata = this.trigger({ phase: 'before', type: 'max', target: 'popup', options: options }); + if (edata.isCancelled === true) return; + // default behavior + w2popup.status = 'resizing'; + options.prevSize = $('#w2ui-popup').css('width') + ':' + $('#w2ui-popup').css('height'); + // do resize + w2popup.resize(10000, 10000, function () { + w2popup.status = 'open'; + options.maximized = true; + obj.trigger($.extend(edata, { phase: 'after'})); + // resize gird, form, layout inside popup + $('#w2ui-popup .w2ui-grid, #w2ui-popup .w2ui-form, #w2ui-popup .w2ui-layout').each(function () { + var name = $(this).attr('name'); + if (w2ui[name] && w2ui[name].resize) w2ui[name].resize(); + }) + }); + }, + + min: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (options.maximized !== true) return; + var size = options.prevSize.split(':'); + // trigger event + var edata = this.trigger({ phase: 'before', type: 'min', target: 'popup', options: options }); + if (edata.isCancelled === true) return; + // default behavior + w2popup.status = 'resizing'; + // do resize + w2popup.resize(parseInt(size[0]), parseInt(size[1]), function () { + w2popup.status = 'open'; + options.maximized = false; + options.prevSize = null; + obj.trigger($.extend(edata, { phase: 'after'})); + // resize gird, form, layout inside popup + $('#w2ui-popup .w2ui-grid, #w2ui-popup .w2ui-form, #w2ui-popup .w2ui-layout').each(function () { + var name = $(this).attr('name'); + if (w2ui[name] && w2ui[name].resize) w2ui[name].resize(); + }) + }); + }, + + get: function () { + return $('#w2ui-popup').data('options'); + }, + + set: function (options) { + w2popup.open(options); + }, + + clear: function() { + $('#w2ui-popup .w2ui-popup-title').html(''); + $('#w2ui-popup .w2ui-popup-body').html(''); + $('#w2ui-popup .w2ui-popup-buttons').html(''); + }, + + reset: function () { + w2popup.open(w2popup.defaults); + }, + + load: function (options) { + w2popup.status = 'loading'; + if (options.url == null) { + console.log('ERROR: The url parameter is empty.'); + return; + } + var tmp = String(options.url).split('#'); + var url = tmp[0]; + var selector = tmp[1]; + if (options == null) options = {}; + // load url + var html = $('#w2ui-popup').data(url); + if (html != null) { + popup(html, selector); + } else { + $.get(url, function (data, status, obj) { // should always be $.get as it is template + popup(obj.responseText, selector); + $('#w2ui-popup').data(url, obj.responseText); // remember for possible future purposes + }); + } + function popup(html, selector) { + delete options.url; + $('body').append(''); + if (selector != null && $('#w2ui-tmp #'+selector).length > 0) { + $('#w2ui-tmp #' + selector).w2popup(options); + } else { + $('#w2ui-tmp > div').w2popup(options); + } + // link styles + if ($('#w2ui-tmp > style').length > 0) { + var style = $('
').append($('#w2ui-tmp > style').clone()).html(); + if ($('#w2ui-popup #div-style').length === 0) { + $('#w2ui-popup').append('
'); + } + $('#w2ui-popup #div-style').html(style); + } + $('#w2ui-tmp').remove(); + } + }, + + message: function (options) { + var obj = this; + $().w2tag(); // hide all tags + if (!options) options = { width: 200, height: 100 }; + var pWidth = parseInt($('#w2ui-popup').width()); + var pHeight = parseInt($('#w2ui-popup').height()); + options.originalWidth = options.width; + options.originalHeight = options.height; + if (parseInt(options.width) < 10) options.width = 10; + if (parseInt(options.height) < 10) options.height = 10; + if (options.hideOnClick == null) options.hideOnClick = false; + var poptions = $('#w2ui-popup').data('options') || {}; + var titleHeight = parseInt($('#w2ui-popup > .w2ui-popup-title').css('height')); + if (options.width == null || options.width > poptions.width - 10) { + options.width = poptions.width - 10; + } + if (options.height == null || options.height > poptions.height - titleHeight - 5) { + options.height = poptions.height - titleHeight - 5; // need margin from bottom only + } + // negative value means margin + if (options.originalHeight < 0) options.height = pHeight + options.originalHeight - titleHeight; + if (options.originalWidth < 0) options.width = pWidth + options.originalWidth * 2; // x 2 because there is left and right margin + + var head = $('#w2ui-popup .w2ui-popup-title'); + var msgCount = $('#w2ui-popup .w2ui-message').length; + + // convert action arrays into buttons + if (options.actions != null) { + options.buttons = ''; + Object.keys(options.actions).forEach(function (action) { + var handler = options.actions[action]; + if (typeof handler == 'function') { + options.buttons += '' + } + if (typeof handler == 'object') { + options.buttons += '' + } + if (typeof handler == 'string') { + options.buttons += handler + } + }); + } + + // remove message + if ($.trim(options.html) === '' && $.trim(options.body) === '' && $.trim(options.buttons) === '') { + var $msg = $('#w2ui-popup .w2ui-message').last(); + if (options.msgId != null) { + $msg = $('#w2ui-message'+ options.msgId); + } + var options = $msg.data('options') || {}; + // message close event + var edata = obj.trigger({ phase: 'before', type: 'msgClose', msgId: $msg.attr('data-msgId'), target: 'popup', options: options }); + if (edata.isCancelled === true) return; + // start hide transition + $msg.css(w2utils.cssPrefix({ + 'transition': '0.15s', + 'transform': 'translateY(-' + options.height + 'px)' + })); + var $focus = $('#w2ui-popup .w2ui-message'); + $focus = $($focus[$focus.length - 2]) + .css('z-index', 1500) + .data('msg-focus'); + if ($focus && $focus.length > 0) $focus.focus(); else obj.focus(); + if (msgCount == 1) w2popup.unlock(150); + setTimeout(function () { + $msg.remove(); + // default action + if (typeof options.onClose == 'function') { + options.onClose(edata); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, 150); + } else { + if ($.trim(options.body) !== '' || $.trim(options.buttons) !== '') { + options.html = '
'+ options.body +'
'+ + '
'+ options.buttons +'
'; + } + // hide previous messages + $('#w2ui-popup .w2ui-message').css('z-index', 1390).data('msg-focus', $(':focus')); + head.css('z-index', 1501); + if (options.close == null) { + options.close = function () { + w2popup.message({ msgId: msgCount }) + } + } + // add message + $('#w2ui-popup .w2ui-box') + .before(''); + $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options); + var display = $('#w2ui-popup #w2ui-message'+ msgCount).css('display'); + $('#w2ui-popup #w2ui-message'+ msgCount).css(w2utils.cssPrefix({ + 'transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') + })); + if (display == 'none') { + $('#w2ui-popup #w2ui-message'+ msgCount).show().html(options.html); + // timer needs to animation + setTimeout(function () { + $('#w2ui-popup #w2ui-message'+ msgCount).css( + $.extend( + w2utils.cssPrefix('transition', '.3s', false), + w2utils.cssPrefix({ + 'transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') + }) + ) + ); + }, 1); + // timer for lock + if (msgCount === 0) w2popup.lock(); + // message open event + var edata = obj.trigger({ phase: 'before', type: 'msgOpen', msgId: msgCount, target: 'popup', options: options }); + if (edata.isCancelled === true) return; + setTimeout(function() { + obj.focus(); + // has to be on top of lock + $('#w2ui-popup #w2ui-message'+ msgCount).css(w2utils.cssPrefix({ 'transition': '0s' })); + if (typeof options.onOpen == 'function') { + options.onOpen(edata); + } + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }, 350); + } + } + }, + + focus: function () { + var tmp = null; + var pop = $('#w2ui-popup'); + var sel = 'input:visible, button:visible, select:visible, textarea:visible, [contentEditable], .w2ui-input'; + // clear previous blur + $(pop).find(sel).off('.keep-focus'); + // in message or popup + var cnt = $('#w2ui-popup .w2ui-message').length - 1; + var msg = $('#w2ui-popup #w2ui-message' + cnt); + if (msg.length > 0) { + var btn =$(msg[msg.length - 1]).find('button'); + if (btn.length > 0) btn[0].focus(); + tmp = msg; + } else if (pop.length > 0) { + var btn = pop.find('.w2ui-popup-buttons button'); + if (btn.length > 0) btn[0].focus(); + tmp = pop; + } + // keep focus/blur inside popup + $(tmp).find(sel) + .on('blur.keep-focus', function (event) { + setTimeout(function () { + var focus = $(':focus'); + if ((focus.length > 0 && !$(tmp).find(sel).is(focus)) || focus.hasClass('w2ui-popup-hidden')) { + var el = $(tmp).find(sel); + if (el.length > 0) el[0].focus(); + } + }, 1); + }); + }, + + lock: function (msg, showSpinner) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift($('#w2ui-popup')); + w2utils.lock.apply(window, args); + }, + + unlock: function (speed) { + w2utils.unlock($('#w2ui-popup'), speed); + }, + + // --- INTERNAL FUNCTIONS + + lockScreen: function (options) { + if ($('#w2ui-lock').length > 0) return false; + if (options == null) options = $('#w2ui-popup').data('options'); + if (options == null) options = {}; + options = $.extend({}, w2popup.defaults, options); + // show element + $('body').append('
'); + // lock screen + setTimeout(function () { + $('#w2ui-lock') + .css('opacity', options.opacity) + .css(w2utils.cssPrefix('transition', options.speed + 's opacity')); + }, 1); + // add events + if (options.modal == true) { + $('#w2ui-lock').on('mousedown', function () { + $('#w2ui-lock') + .css('opacity', '0.6') + .css(w2utils.cssPrefix('transition', '.1s')); + }); + $('#w2ui-lock').on('mouseup', function () { + setTimeout(function () { + $('#w2ui-lock') + .css('opacity', options.opacity) + .css(w2utils.cssPrefix('transition', '.1s')); + }, 100); + }); + } else { + $('#w2ui-lock').on('mousedown', function () { w2popup.close(); }); + } + return true; + }, + + unlockScreen: function (options) { + if ($('#w2ui-lock').length === 0) return false; + if (options == null) options = $('#w2ui-popup').data('options'); + if (options == null) options = {}; + options = $.extend({}, w2popup.defaults, options); + $('#w2ui-lock') + .css('opacity', '0') + .css(w2utils.cssPrefix('transition', options.speed + 's opacity')); + setTimeout(function () { + $('#w2ui-lock').remove(); + }, options.speed * 1000); + return true; + }, + + resizeMessages: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + // see if there are messages and resize them + $('#w2ui-popup .w2ui-message').each(function () { + var moptions = $(this).data('options'); + var $popup = $('#w2ui-popup'); + if (parseInt(moptions.width) < 10) moptions.width = 10; + if (parseInt(moptions.height) < 10) moptions.height = 10; + var titleHeight = parseInt($popup.find('> .w2ui-popup-title').css('height')); + var pWidth = parseInt($popup.width()); + var pHeight = parseInt($popup.height()); + // recalc width + moptions.width = moptions.originalWidth; + if (moptions.width > pWidth - 10) { + moptions.width = pWidth - 10; + } + // recalc height + moptions.height = moptions.originalHeight; + if (moptions.height > pHeight - titleHeight - 5) { + moptions.height = pHeight - titleHeight - 5; + } + if (moptions.originalHeight < 0) moptions.height = pHeight + moptions.originalHeight - titleHeight; + if (moptions.originalWidth < 0) moptions.width = pWidth + moptions.originalWidth * 2; // x 2 because there is left and right margin + $(this).css({ + left : ((pWidth - moptions.width) / 2) + 'px', + width : moptions.width + 'px', + height : moptions.height + 'px' + }); + }); + }, + + resize: function (width, height, callBack) { + var obj = this; + var options = $('#w2ui-popup').data('options') || {}; + if (options.speed == null) options.speed = 0; + width = parseInt(width); + height = parseInt(height); + // calculate new position + var maxW, maxH; + if (window.innerHeight == undefined) { + maxW = parseInt(document.documentElement.offsetWidth); + maxH = parseInt(document.documentElement.offsetHeight); + if (w2utils.engine === 'IE7') { maxW += 21; maxH += 4; } + } else { + maxW = parseInt(window.innerWidth); + maxH = parseInt(window.innerHeight); + } + if (maxW - 10 < width) width = maxW - 10; + if (maxH - 10 < height) height = maxH - 10; + var top = (maxH - height) / 2 * 0.6; + var left = (maxW - width) / 2; + // resize there + $('#w2ui-popup') + .css(w2utils.cssPrefix({ + 'transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top' + })) + .css({ + 'top' : top, + 'left' : left, + 'width' : width, + 'height': height + }); + var tmp_int = setInterval(function () { obj.resizeMessages(); }, 10); // then messages resize nicely + setTimeout(function () { + clearInterval(tmp_int); + options.width = width; + options.height = height; + obj.resizeMessages(); + if (typeof callBack == 'function') callBack(); + }, (options.speed * 1000) + 50); // give extra 50 ms + }, + + /*********************** + * Internal + **/ + + // restores template + restoreTemplate: function () { + var options = $('#w2ui-popup').data('options'); + if (options == null) return; + var template = w2popup._template; + var title = options.title; + var body = options.body; + var buttons = options.buttons; + if (w2popup._prev) { + template = w2popup._prev.template; + title = w2popup._prev.title; + body = w2popup._prev.body; + buttons = w2popup._prev.buttons; + delete w2popup._prev; + } else { + delete w2popup._template; + } + if (template != null) { + var $tmp = $(template); + if ($tmp.length === 0) return; + if ($(body).attr('rel') == 'body') { + if (title) $tmp.append(title); + if (body) $tmp.append(body); + if (buttons) $tmp.append(buttons); + } else { + $tmp.append(body); + } + } + } + }; + + // merge in event handling + $.extend(w2popup, w2utils.event); + +})(jQuery); + +// ============================================ +// --- Common dialogs + +var w2alert = function (msg, title, callBack) { + var $ = jQuery; + if (title == null) title = w2utils.lang('Notification'); + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + w2popup.message({ + width : 400, + height : 170, + body : '
' + msg + '
', + buttons : '', + onOpen: function () { + $('#w2ui-popup .w2ui-message .w2ui-popup-btn').focus(); + }, + onClose: function () { + if (typeof callBack == 'function') callBack(); + } + }); + } else { + w2popup.open({ + width : 450, + height : 220, + showMax : false, + showClose : false, + title : title, + body : '
' + msg + '
', + buttons : '', + onOpen: function (event) { + // do not use onComplete as it is slower + setTimeout(function () { $('#w2ui-popup .w2ui-popup-btn').focus(); }, 1); + }, + onKeydown: function (event) { + $('#w2ui-popup .w2ui-popup-btn').focus().addClass('clicked'); + }, + onClose: function () { + if (typeof callBack == 'function') callBack(); + } + }); + } + return { + ok: function (fun) { + callBack = fun; + return this; + }, + done: function (fun) { + callBack = fun; + return this; + } + }; +}; + +var w2confirm = function (msg, title, callBack) { + var $ = jQuery; + var options = {}; + var defaults = { + msg : '', + title : w2utils.lang('Confirmation'), + width : ($('#w2ui-popup').length > 0 ? 400 : 450), + height : ($('#w2ui-popup').length > 0 ? 170 : 220), + yes_text : 'Yes', + yes_class : '', + yes_style : '', + yes_callBack: null, + no_text : 'No', + no_class : '', + no_style : '', + no_callBack : null, + focus_to_no : false, + callBack : null + }; + if (arguments.length == 1 && typeof msg == 'object') { + $.extend(options, defaults, msg); + } else { + if (typeof title == 'function') { + $.extend(options, defaults, { + msg : msg, + callBack: title + }) + } else { + $.extend(options, defaults, { + msg : msg, + title : title, + callBack: callBack + }) + } + } + // if there is a yes/no button object + if (typeof options.btn_yes == 'object') { + options.yes_text = options.btn_yes.text || options.yes_text; + options.yes_class = options.btn_yes["class"] || options.yes_class; + options.yes_style = options.btn_yes.style || options.yes_style; + options.yes_callBack = options.btn_yes.callBack || options.yes_callBack; + } + if (typeof options.btn_no == 'object') { + options.no_text = options.btn_no.text || options.no_text; + options.no_class = options.btn_no["class"] || options.no_class; + options.no_style = options.btn_no.style || options.no_style; + options.no_callBack = options.btn_no.callBack || options.no_callBack; + } + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing' && w2popup.get()) { + if (options.width > w2popup.get().width) options.width = w2popup.get().width; + if (options.height > (w2popup.get().height - 50)) options.height = w2popup.get().height - 50; + w2popup.message({ + width : options.width, + height : options.height, + body : '
' + options.msg + '
', + buttons : (w2utils.settings.macButtonOrder + ? '' + + '' + : '' + + '' + ), + onOpen: function (event) { + $('#w2ui-popup .w2ui-message .w2ui-btn').on('click.w2confirm', function (event) { + w2popup._confirm_btn = event.target.id; + w2popup.message(); + }); + if (typeof options.onOpen == 'function') options.onOpen() + }, + onClose: function (event) { + // needed this because there might be other messages + $('#w2ui-popup .w2ui-message .w2ui-btn').off('click.w2confirm'); + // need to wait for message to slide up + setTimeout(function () { + if (typeof options.callBack == 'function') options.callBack(w2popup._confirm_btn); + if (w2popup._confirm_btn == 'Yes' && typeof options.yes_callBack == 'function') options.yes_callBack(); + if (w2popup._confirm_btn == 'No' && typeof options.no_callBack == 'function') options.no_callBack(); + }, 300); + if (typeof options.onClose == 'function') options.onClose() + } + // onKeydown will not work here + }); + + } else { + + if (!w2utils.isInt(options.height)) options.height = options.height + 50; + w2popup.open({ + width : options.width, + height : options.height, + title : options.title, + modal : true, + showClose : false, + body : '
' + options.msg + '
', + buttons : (w2utils.settings.macButtonOrder + ? '' + + '' + : '' + + '' + ), + onOpen: function (event) { + // do not use onComplete as it is slower + setTimeout(function () { + $('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { + w2popup.close(); + if (typeof options.callBack == 'function') options.callBack(event.target.id); + if (event.target.id == 'Yes' && typeof options.yes_callBack == 'function') options.yes_callBack(); + if (event.target.id == 'No' && typeof options.no_callBack == 'function') options.no_callBack(); + }); + if(options.focus_to_no){ + $('#w2ui-popup .w2ui-popup-btn#No').focus(); + }else{ + $('#w2ui-popup .w2ui-popup-btn#Yes').focus(); + } + if (typeof options.onOpen == 'function') options.onOpen() + }, 1); + }, + onClose: function (event) { + if (typeof options.onClose == 'function') options.onClose() + }, + onKeydown: function (event) { + // if there are no messages + if ($('#w2ui-popup .w2ui-message').length === 0) { + switch (event.originalEvent.keyCode) { + case 13: // enter + $('#w2ui-popup .w2ui-popup-btn#Yes').focus().addClass('clicked'); // no need fo click as enter will do click + w2popup.close(); + break; + case 27: // esc + $('#w2ui-popup .w2ui-popup-btn#No').focus().click(); + w2popup.close(); + break; + } + } + } + }); + } + + return { + yes: function (fun) { + options.yes_callBack = fun; + return this; + }, + no: function (fun) { + options.no_callBack = fun; + return this; + } + }; +}; + +var w2prompt = function (label, title, callBack) { + var $ = jQuery; + var options = {}; + var defaults = { + title : w2utils.lang('Notification'), + width : ($('#w2ui-popup').length > 0 ? 400 : 450), + height : ($('#w2ui-popup').length > 0 ? 170 : 220), + label : '', + value : '', + attrs : '', + textarea : false, + ok_text : w2utils.lang('Ok'), + ok_class : '', + cancel_text : w2utils.lang('Cancel'), + cancel_class: '', + callBack : null, + onOpen : null, + onClose : null + } + w2popup.tmp = w2popup.tmp || {} + + if (arguments.length == 1 && typeof label == 'object') { + $.extend(options, defaults, label); + } else { + if (typeof title == 'function') { + $.extend(options, defaults, { + label : label, + callBack: title + }) + } else { + $.extend(options, defaults, { + label : label, + title : title, + callBack: callBack + }) + } + } + + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing' && w2popup.get()) { + if (options.width > w2popup.get().width) options.width = w2popup.get().width; + if (options.height > (w2popup.get().height - 50)) options.height = w2popup.get().height - 50; + w2popup.message({ + width : options.width, + height : options.height, + body : (options.textarea + ? '
'+ + '
' + options.label + '
'+ + ' '+ + '
' + : '
'+ + ' '+ + ' '+ + '
' + ), + buttons : (w2utils.settings.macButtonOrder + ? '' + + '' + : '' + + '' + ), + onOpen: function () { + $('#w2prompt').val(options.value).off('.w2prompt').on('keydown.w2prompt', function(event) { + if (event.keyCode == 13) { + $('#w2ui-popup .w2ui-message .w2ui-btn#Ok').click() + } + }); + $('#w2ui-popup .w2ui-message .w2ui-btn#Ok').off('.w2prompt').on('click.w2prompt', function (event) { + w2popup.tmp.btn = 'ok'; + w2popup.tmp.value = $('#w2prompt').val(); + w2popup.message(); + }); + $('#w2ui-popup .w2ui-message .w2ui-btn#Cancel').off('.w2prompt').on('click.w2prompt', function (event) { + w2popup.tmp.btn = 'cancel'; + w2popup.tmp.value = null; + w2popup.message(); + }); + // set focus + setTimeout(function () { $('#w2prompt').focus(); }, 100); + // some event + if (typeof options.onOpen == 'function') options.onOpen() + }, + onClose: function () { + // needed this because there might be other messages + $('#w2ui-popup .w2ui-message .w2ui-btn').off('click.w2prompt'); + // need to wait for message to slide up + setTimeout(function () { + btnClick(w2popup.tmp.btn, w2popup.tmp.value); + }, 300); + // some event + if (typeof options.onClose == 'function') options.onClose() + } + // onKeydown will not work here + }); + + } else { + + if (!w2utils.isInt(options.height)) options.height = options.height + 50; + w2popup.open({ + width : options.width, + height : options.height, + title : options.title, + modal : true, + showClose : false, + body : (options.textarea + ? '
'+ + '
' + options.label + '
'+ + ' '+ + '
' + : '
'+ + ' '+ + ' '+ + '
' + ), + buttons : (w2utils.settings.macButtonOrder + ? '' + + '' + : ''+ + '' + ), + onOpen: function (event) { + // do not use onComplete as it is slower + setTimeout(function () { + $('#w2prompt').val(options.value); + $('#w2prompt').w2field('text'); + $('#w2ui-popup .w2ui-popup-btn#Ok').on('click', function (event) { + w2popup.tmp.btn = 'ok'; + w2popup.tmp.value = $('#w2prompt').val(); + w2popup.close(); + }); + $('#w2ui-popup .w2ui-popup-btn#Cancel').on('click', function (event) { + w2popup.tmp.btn = 'cancel'; + w2popup.tmp.value = null; + w2popup.close(); + }); + $('#w2ui-popup .w2ui-popup-btn#Ok'); + // set focus + setTimeout(function () { $('#w2prompt').focus(); }, 100); + // some event + if (typeof options.onOpen == 'function') options.onOpen() + }, 1); + }, + onClose: function (event) { + // some event + btnClick(w2popup.tmp.btn, w2popup.tmp.value); + if (typeof options.onClose == 'function') options.onClose() + }, + onKeydown: function (event) { + // if there are no messages + if ($('#w2ui-popup .w2ui-message').length === 0) { + switch (event.originalEvent.keyCode) { + case 13: // enter + $('#w2ui-popup .w2ui-popup-btn#Ok').focus().addClass('clicked'); // no need fo click as enter will do click + break; + case 27: // esc + w2popup.tmp.btn = 'cancel'; + w2popup.tmp.value = null; + break; + } + } + } + }); + } + function btnClick(btn, value) { + if (btn == 'ok' && typeof options.ok_callBack == 'function') { + options.ok_callBack(value) + } + if (btn == 'cancel' && typeof options.cancel_callBack == 'function') { + options.cancel_callBack(value) + } + if (typeof options.callBack == 'function') { + options.callBack(btn, value); + } + } + return { + change: function (fun) { + $('#w2prompt').on('keyup', fun).keyup(); + return this; + }, + ok: function (fun) { + options.ok_callBack = fun; + return this; + }, + cancel: function (fun) { + options.cancel_callBack = fun; + return this; + } + }; +}; + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2tabs - tabs widget +* - $().w2tabs - jQuery wrapper +* - Dependencies: jQuery, w2utils +* +* == NICE TO HAVE == +* - align = left, right, center ?? +* +* == 1.5 changes == +* - tab.caption - deprecated +* - getTabHTML() +* - refactored with display: flex +* - reorder +* - initReorder +* - dragMove +* - tmp +* +************************************************************************/ + +(function ($) { + var w2tabs = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.active = null; + this.reorder = false; + this.flow = 'down'; // can be down or up + this.tooltip = 'top|left'; // can be top, bottom, left, right + this.tabs = []; + this.routeData = {}; // data for dynamic routes + this.tmp = {}; // placeholder for internal variables + this.right = ''; + this.style = ''; + + $.extend(this, { handlers: [] }); + $.extend(true, this, w2obj.tabs, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2tabs = function(method) { + if ($.isPlainObject(method)) { + // check name parameter + if (!w2utils.checkName(method, 'w2tabs')) return; + // extend tabs + var tabs = method.tabs || []; + var object = new w2tabs(method); + for (var i = 0; i < tabs.length; i++) { + object.tabs[i] = $.extend({}, w2tabs.prototype.tab, tabs[i]); + } + // register new object + w2ui[object.name] = object; + // render + if ($(this).length !== 0) { + object.render($(this)[0]); + } + return object; + } else { + var obj = w2ui[$(this).attr('name')]; + if (!obj) return null; + if (arguments.length > 0) { + if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + return obj; + } + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2tabs.prototype = { + onClick : null, + onClose : null, + onRender : null, + onRefresh : null, + onResize : null, + onDestroy : null, + + tab : { + id : null, // command to be sent to all event handlers + text : null, + route : null, + hidden : false, + disabled : false, + closable : false, + tooltip : null, + style : '', + onClick : null, + onRefresh : null, + onClose : null + }, + + add: function (tab) { + return this.insert(null, tab); + }, + + insert: function (id, tab) { + if (!$.isArray(tab)) tab = [tab]; + // assume it is array + for (var i = 0; i < tab.length; i++) { + // checks + if (tab[i].id == null) { + console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); + return; + } + if (!w2utils.checkUniqueId(tab[i].id, this.tabs, 'tabs', this.name)) return; + // add tab + var newTab = $.extend({}, w2tabs.prototype.tab, tab[i]); + if (id == null) { + this.tabs.push(newTab); + } else { + var middle = this.get(id, true); + var before = this.tabs[middle].id + this.insertTabHTML(before, newTab) + } + } + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab) return false; + removed++; + // remove from array + this.tabs.splice(this.get(tab.id, true), 1); + // remove from screen + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).remove(); + } + this.resize(); + return removed; + }, + + select: function (id) { + if (this.active == id || this.get(id) == null) return false; + this.active = id; + this.refresh(); + return true; + }, + + set: function (id, tab) { + var index = this.get(id, true); + if (index == null) return false; + $.extend(this.tabs[index], tab); + this.refresh(id); + return true; + }, + + get: function (id, returnIndex) { + if (arguments.length === 0) { + var all = []; + for (var i1 = 0; i1 < this.tabs.length; i1++) { + if (this.tabs[i1].id != null) { + all.push(this.tabs[i1].id); + } + } + return all; + } else { + for (var i2 = 0; i2 < this.tabs.length; i2++) { + if (this.tabs[i2].id == id) { // need to be == since id can be numeric + return (returnIndex === true ? i2 : this.tabs[i2]); + } + } + } + return null; + }, + + show: function () { + var obj = this; + var shown = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.hidden === false) continue; + shown++; + tab.hidden = false; + tmp.push(tab.id); + } + setTimeout(function () { for (var t=0; t
' + ); + helper = $(obj.el).prev(); + helper + .css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'padding-top' : $(obj.el).css('padding-top'), + 'padding-bottom' : $(obj.el).css('padding-bottom'), + 'padding-left' : $(obj.el).css('padding-left'), + 'padding-right' : 0, + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 2) + 'px', + 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px', + 'margin-left' : $(obj.el).css('margin-left'), + 'margin-right' : 0 + }) + .on('click', function (event) { + if (obj.options.icon && typeof obj.onIconClick === 'function') { + // event before + var edata = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] }); + if (edata.isCancelled === true) return; + + // intentionally empty + + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + } else { + if (obj.type === 'list') { + $(obj.helpers.focus).find('input').focus(); + } else { + $(obj.el).focus(); + } + } + }); + $(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px'); + // remember helper + obj.helpers.prefix = helper; + } + }, 1); + }, + + addSuffix: function () { + var obj = this; + var helper, pr; + setTimeout(function () { + if (obj.type === 'clear') return; + var tmp = $(obj.el).data('tmp') || {}; + if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']); + tmp['old-padding-right'] = $(obj.el).css('padding-right'); + $(obj.el).data('tmp', tmp); + pr = parseInt($(obj.el).css('padding-right'), 10); + if (obj.options.arrows) { + // remove if already displayed + if (obj.helpers.arrows) $(obj.helpers.arrows).remove(); + // add fresh + $(obj.el).after( + '
 '+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'); + helper = $(obj.el).next(); + helper.css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px', + 'padding' : 0, + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : 0, + 'border-left' : '1px solid silver' + }) + .css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px') + .on('mousedown', function (event) { + var body = $('body'); + body.on('mouseup', tmp); + body.data('_field_update_timer', setTimeout(update, 700)); + update(false); + // timer function + function tmp() { + clearTimeout(body.data('_field_update_timer')); + body.off('mouseup', tmp); + } + // update function + function update(notimer) { + $(obj.el).focus(); + obj.keyDown($.Event("keydown"), { + keyCode : ($(event.target).attr('type') === 'up' ? 38 : 40) + }); + if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); + } + }); + pr += helper.width() + 12; + $(obj.el).css('padding-right', pr + 'px'); + // remember helper + obj.helpers.arrows = helper; + } + if (obj.options.suffix !== '') { + // remove if already displayed + if (obj.helpers.suffix) $(obj.helpers.suffix).remove(); + // add fresh + $(obj.el).after( + '
'+ + obj.options.suffix + + '
'); + helper = $(obj.el).next(); + helper + .css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'padding-top' : $(obj.el).css('padding-top'), + 'padding-bottom' : $(obj.el).css('padding-bottom'), + 'padding-left' : '3px', + 'padding-right' : $(obj.el).css('padding-right'), + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 2) + 'px', + 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px' + }) + .on('click', function (event) { + if (obj.type === 'list') { + $(obj.helpers.focus).find('input').focus(); + } else { + $(obj.el).focus(); + } + }); + + helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px'); + pr += helper.width() + 3; + $(obj.el).css('padding-right', pr + 'px'); + // remember helper + obj.helpers.suffix = helper; + } + }, 1); + }, + + addFocus: function () { + var obj = this; + var options = this.options; + var width = 0; // 11 - show search icon, 0 do not show + var pholder; + // clean up & init + $(obj.helpers.focus).remove(); + // remember original tabindex + var tabIndex = parseInt($(obj.el).attr('tabIndex')); + if (!isNaN(tabIndex) && tabIndex !== -1) obj.el._tabIndex = tabIndex; + if (obj.el._tabIndex) tabIndex = obj.el._tabIndex; + if (tabIndex == null) tabIndex = -1; + if (isNaN(tabIndex)) tabIndex = 0; + // if there is id, add to search with "_search" + var searchId = ''; + if ($(obj.el).attr('id') != null) { + searchId = 'id="' + $(obj.el).attr('id') + '_search"' + } + // build helper + var html = + '
'+ + ' '+ + ' '+ + '
'; + $(obj.el).attr('tabindex', -1).before(html); + var helper = $(obj.el).prev(); + obj.helpers.focus = helper; + helper.css({ + width : $(obj.el).width(), + "margin-top" : $(obj.el).css('margin-top'), + "margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px', + "margin-bottom" : $(obj.el).css('margin-bottom'), + "margin-right" : $(obj.el).css('margin-right') + }) + .find('input') + .css({ + cursor : 'default', + width : '100%', + outline : 'none', + opacity : 1, + margin : 0, + border : '1px solid transparent', + padding : $(obj.el).css('padding-top'), + "padding-left" : 0, + "margin-left" : (width > 0 ? width + 6 : 0), + "background-color" : 'transparent' + }); + // INPUT events + helper.find('input') + .on('click', function (event) { + if ($('#w2ui-overlay').length === 0) obj.focus(event); + event.stopPropagation(); + }) + .on('focus', function (event) { + pholder = $(obj.el).attr('placeholder'); + $(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '2px' }); + $(this).val(''); + $(obj.el).triggerHandler('focus'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('blur', function (event) { + $(obj.el).css('outline', 'none'); + $(this).val(''); + obj.refresh(); + $(obj.el).triggerHandler('blur'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (pholder != null) $(obj.el).attr('placeholder', pholder); + }) + .on('keydown', function (event) { + var el = this; + obj.keyDown(event); + setTimeout(function () { + if (el.value === '') $(obj.el).attr('placeholder', pholder); else $(obj.el).attr('placeholder', ''); + }, 10); + }) + .on('keyup', function (event) { obj.keyUp(event); }) + .on('keypress', function (event) { obj.keyPress(event); }); + // MAIN div + helper.on('click', function (event) { $(this).find('input').focus(); }); + obj.refresh(); + }, + + addMulti: function () { + var obj = this; + var options = this.options; + // clean up & init + $(obj.helpers.multi).remove(); + // build helper + var html = ''; + var margin = + 'margin-top : 0px; ' + + 'margin-bottom : 0px; ' + + 'margin-left : ' + $(obj.el).css('margin-left') + '; ' + + 'margin-right : ' + $(obj.el).css('margin-right') + '; '+ + 'width : ' + (w2utils.getSize(obj.el, 'width') + - parseInt($(obj.el).css('margin-left'), 10) + - parseInt($(obj.el).css('margin-right'), 10)) + + 'px;'; + // if there is id, add to search with "_search" + var searchId = ''; + if ($(obj.el).attr('id') != null) { + searchId = 'id="' + $(obj.el).attr('id') + '_search" ' + } + if (obj.type === 'enum') { + // remember original tabindex + var tabIndex = $(obj.el).attr('tabIndex'); + if (tabIndex && tabIndex !== -1) obj.el._tabIndex = tabIndex; + if (obj.el._tabIndex) tabIndex = obj.el._tabIndex; + if (tabIndex == null) tabIndex = 0; // default tabindex + + html = '
'+ + '
'+ + '
    '+ + '
  • '+ + ' '+ + '
  • '+ + '
'+ + '
'+ + '
'; + } + if (obj.type === 'file') { + html = '
'+ + '
'+ + ' '+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'; + } + // old bg and border + var tmp = $(obj.el).data('tmp') || {}; + tmp['old-background-color'] = $(obj.el).css('background-color'); + tmp['old-border-color'] = $(obj.el).css('border-color'); + $(obj.el).data('tmp', tmp); + + $(obj.el) + .before(html) + .css({ + 'background-color' : 'transparent', + 'border-color' : 'transparent' + }); + + var div = $(obj.el).prev(); + obj.helpers.multi = div; + if (obj.type === 'enum') { + $(obj.el).attr('tabindex', -1); + // INPUT events + div.find('input') + .on('click', function (event) { + if ($('#w2ui-overlay').length === 0) obj.focus(event); + $(obj.el).triggerHandler('click'); + }) + .on('focus', function (event) { + $(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '2px' }); + $(obj.el).triggerHandler('focus'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('blur', function (event) { + $(div).css('outline', 'none'); + $(obj.el).triggerHandler('blur'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('keyup', function (event) { obj.keyUp(event); }) + .on('keydown', function (event) { obj.keyDown(event); }) + .on('keypress', function (event) { obj.keyPress(event); }); + // MAIN div + div.on('click', function (event) { $(this).find('input').focus(); }); + } + if (obj.type === 'file') { + $(obj.el).css('outline', 'none'); + div.find('input') + .off('.drag') + .on('click.drag', function (event) { + event.stopPropagation(); + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + $(obj.el).focus(); + }) + .on('dragenter.drag', function (event) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + $(div).addClass('w2ui-file-dragover'); + }) + .on('dragleave.drag', function (event) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + $(div).removeClass('w2ui-file-dragover'); + }) + .on('drop.drag', function (event) { + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; + $(div).removeClass('w2ui-file-dragover'); + var files = event.originalEvent.dataTransfer.files; + for (var i = 0, l = files.length; i < l; i++) obj.addFile.call(obj, files[i]); + $(obj.el).focus(); + // cancel to stop browser behaviour + event.preventDefault(); + event.stopPropagation(); + }) + .on('dragover.drag', function (event) { + // cancel to stop browser behaviour + event.preventDefault(); + event.stopPropagation(); + }) + .on('change.drag', function () { + $(obj.el).focus(); + if (typeof this.files !== "undefined") { + for (var i = 0, l = this.files.length; i < l; i++) { + obj.addFile.call(obj, this.files[i]); + } + } + }); + } + obj.refresh(); + }, + + addFile: function (file) { + var obj = this; + var options = this.options; + var selected = $(obj.el).data('selected'); + var newItem = { + name : file.name, + type : file.type, + modified : file.lastModifiedDate, + size : file.size, + content : null, + file : file + }; + var size = 0; + var cnt = 0; + var err; + if (selected) { + for (var s = 0; s < selected.length; s++) { + // check for dups + if (selected[s].name == file.name && selected[s].size == file.size) return; + size += selected[s].size; + cnt++; + } + } + // trigger event + var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, file: newItem, total: cnt, totalSize: size }); + if (edata.isCancelled === true) return; + // check params + if (options.maxFileSize !== 0 && newItem.size > options.maxFileSize) { + err = 'Maximum file size is '+ w2utils.formatSize(options.maxFileSize); + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { + err = w2utils.lang('Maximum total size is') + ' ' + w2utils.formatSize(options.maxSize); + if (options.silent === false) { + $(obj.el).w2tag(err); + } else { + console.log('ERROR: '+ err); + } + return; + } + if (options.max !== 0 && cnt >= options.max) { + err = w2utils.lang('Maximum number of files is') + ' '+ options.max; + if (options.silent === false) { + $(obj.el).w2tag(err); + } else { + console.log('ERROR: '+ err); + } + return; + } + selected.push(newItem); + // read file as base64 + if (typeof FileReader !== "undefined" && options.readContent === true) { + var reader = new FileReader(); + // need a closure + reader.onload = (function () { + return function (event) { + var fl = event.target.result; + var ind = fl.indexOf(','); + newItem.content = fl.substr(ind+1); + obj.refresh(); + $(obj.el).trigger('input').trigger('change'); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + }; + })(); + reader.readAsDataURL(file); + } else { + obj.refresh(); + $(obj.el).trigger('input').trigger('change'); + obj.trigger($.extend(edata, { phase: 'after' })); + } + }, + + normMenu: function (menu, el) { + if ($.isArray(menu)) { + for (var m = 0; m < menu.length; m++) { + if (typeof menu[m] === 'string') { + menu[m] = { id: menu[m], text: menu[m] }; + } else if (menu[m] != null) { + if (menu[m].text != null && menu[m].id == null) menu[m].id = menu[m].text; + if (menu[m].text == null && menu[m].id != null) menu[m].text = menu[m].id; + if (menu[m].caption != null) menu[m].text = menu[m].caption; + } else { + menu[m] = { id: null, text: 'null' } + } + } + return menu; + } else if (typeof menu === 'function') { + return w2obj.field.prototype.normMenu.call(this, menu.call(this, el)); + } else if (typeof menu === 'object') { + var tmp = []; + for (var m in menu) tmp.push({ id: m, text: menu[m] }); + return tmp; + } + }, + + getMonthHTML: function (month, year, selected) { + var td = new Date(); + var months = w2utils.settings.fullmonths; + var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31']; + var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate(); + var days = w2utils.settings.fulldays.slice(); // creates copy of the array + var sdays = w2utils.settings.shortdays.slice(); // creates copy of the array + if (w2utils.settings.weekStarts !== 'M') { + days.unshift(days.pop()); + sdays.unshift(sdays.pop()); + } + var options = this.options; + if (options == null) options = {}; + // normalize date + year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear(); + month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1; + if (month > 12) { month -= 12; year++; } + if (month < 1 || month === 0) { month += 12; year--; } + if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } + options.current = month + '/' + year; + + // start with the required date + td = new Date(year, month-1, 1); + var weekDay = td.getDay(); + var dayTitle = ''; + for (var i = 0; i < sdays.length; i++) dayTitle += '' + sdays[i] + ''; + + var html = + '
'+ + ' '+ + ' '+ + months[month-1] +', '+ year + + '
'+ + ''+ + ' ' + dayTitle + ''+ + ' '; + + var day = 1; + if (w2utils.settings.weekStarts !== 'M') weekDay++; + if(this.type === 'datetime') { + var dt_sel = w2utils.isDateTime(selected, options.format, true); + selected = w2utils.formatDate(dt_sel, w2utils.settings.dateFormat); + } + for (var ci = 1; ci < 43; ci++) { + if (weekDay === 0 && ci == 1) { + for (var ti = 0; ti < 6; ti++) html += ''; + ci += 6; + } else { + if (ci < weekDay || day > daysCount[month-1]) { + html += ''; + if ((ci) % 7 === 0) html += ''; + continue; + } + } + var dt = year + '/' + month + '/' + day; + var DT = new Date(dt); + var className = ''; + if (DT.getDay() === 6) className = ' w2ui-saturday'; + if (DT.getDay() === 0) className = ' w2ui-sunday'; + if (dt == today) className += ' w2ui-today'; + + var dspDay = day; + var col = ''; + var bgcol = ''; + var tmp_dt, tmp_dt_fmt; + if(this.type === 'datetime') { + // var fm = options.format.split('|')[0].trim(); + // tmp_dt = w2utils.formatDate(dt, fm); + tmp_dt = w2utils.formatDateTime(dt, options.format); + tmp_dt_fmt = w2utils.formatDate(dt, w2utils.settings.dateFormat); + } else { + tmp_dt = w2utils.formatDate(dt, options.format); + tmp_dt_fmt = tmp_dt; + } + if (options.colored && options.colored[tmp_dt_fmt] !== undefined) { // if there is predefined colors for dates + var tmp = options.colored[tmp_dt_fmt].split(':'); + bgcol = 'background-color: ' + tmp[0] + ';'; + col = 'color: ' + tmp[1] + ';'; + } + html += ''; + if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += ''; + day++; + } + html += '
  
'+ + dspDay + + '
'; + return html; + }, + + getYearHTML: function () { + var months = w2utils.settings.shortmonths; + var start_year = w2utils.settings.dateStartYear; + var end_year = w2utils.settings.dateEndYear; + var mhtml = ''; + var yhtml = ''; + for (var m = 0; m < months.length; m++) { + mhtml += '
'+ months[m] + '
'; + } + for (var y = start_year; y <= end_year; y++) { + yhtml += '
'+ y + '
'; + } + return '
'+ mhtml +'
'+ yhtml +'
'; + }, + + getHourHTML: function () { + var tmp = []; + var options = this.options; + if (options == null) options = { format: w2utils.settings.timeFormat }; + var h24 = (options.format.indexOf('h24') > -1); + for (var a = 0; a < 24; a++) { + var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : ''); + if (a == 12 && !h24) time = '12:00 pm'; + if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = ''; + var tm1 = this.fromMin(this.toMin(time)); + var tm2 = this.fromMin(this.toMin(time) + 59); + if (this.type === 'datetime') { + var dt = w2utils.isDateTime(this.el.value, options.format, true); + var fm = options.format.split('|')[0].trim(); + tm1 = w2utils.formatDate(dt, fm) + ' ' + tm1; + tm2 = w2utils.formatDate(dt, fm) + ' ' + tm2; + } + tmp[Math.floor(a/8)] += '
'+ time +'
'; + } + var html = + '
'+ + '
'+ w2utils.lang('Select Hour') +'
'+ + '
'+ + ' ' + + ' ' + + ' ' + + '
'+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
'+ + '
'; + return html; + }, + + getMinHTML: function (hour) { + if (hour == null) hour = 0; + var options = this.options; + if (options == null) options = { format: w2utils.settings.timeFormat }; + var h24 = (options.format.indexOf('h24') > -1); + var tmp = []; + for (var a = 0; a < 60; a += 5) { + var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : ''); + var tm = time; + var ind = a < 20 ? 0 : (a < 40 ? 1 : 2); + if (!tmp[ind]) tmp[ind] = ''; + if (this.type === 'datetime') { + var dt = w2utils.isDateTime(this.el.value, options.format, true); + var fm = options.format.split('|')[0].trim(); + tm = w2utils.formatDate(dt, fm) + ' ' + tm; + } + tmp[ind] += '
'+ time +'
'; + } + var html = + '
'+ + '
'+ w2utils.lang('Select Minute') +'
'+ + '
'+ + ' ' + + ' ' + + ' ' + + '
'+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
'+ + '
'; + return html; + }, + + toMin: function (str) { + if (typeof str !== 'string') return null; + var tmp = str.split(':'); + if (tmp.length === 2) { + tmp[0] = parseInt(tmp[0]); + tmp[1] = parseInt(tmp[1]); + if (str.indexOf('pm') !== -1 && tmp[0] !== 12) tmp[0] += 12; + } else { + return null; + } + return tmp[0] * 60 + tmp[1]; + }, + + fromMin: function (time) { + var ret = ''; + if (time >= 24 * 60) time = time % (24 * 60); + if (time < 0) time = 24 * 60 + time; + var hour = Math.floor(time/60); + var min = ((time % 60) < 10 ? '0' : '') + (time % 60); + var options = this.options; + if (options == null) options = { format: w2utils.settings.timeFormat }; + if (options.format.indexOf('h24') !== -1) { + ret = hour + ':' + min; + } else { + ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am'); + } + return ret; + } + }; + + $.extend(w2field.prototype, w2utils.event); + w2obj.field = w2field; + +}) (jQuery); + +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2form - form widget +* - $().w2form - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2fields, w2tabs, w2toolbar +* +* == NICE TO HAVE == +* - include delta on save +* - form should read '; + switch (field.type) { + case 'pass': + case 'password': + input = ''; + break; + case 'check': + case 'checks': + if (field.options.items == null && field.html.items != null) field.options.items = field.html.items; + var items = field.options.items; + input = ''; + // normalized options + if (!$.isArray(items)) items = []; + if (items.length > 0) { + items = w2obj.field.prototype.normMenu.call(this, items, field); + } + // generate + for (var i = 0; i < items.length; i++) { + input += '
'; + } + break; + + case 'checkbox': + input = ''; + break; + case 'radio': + input = ''; + // normalized options + if (field.options.items == null && field.html.items != null) field.options.items = field.html.items; + var items = field.options.items; + if (!$.isArray(items)) items = []; + if (items.length > 0) { + items = w2obj.field.prototype.normMenu.call(this, items, field); + } + // generate + for (var i = 0; i < items.length; i++) { + input += '
'; + } + break; + case 'select': + input = ''; + break; + case 'textarea': + input = ''; + break; + case 'toggle': + input = '
'; + break; + case 'map': + case 'array': + field.html.key = field.html.key || {}; + field.html.value = field.html.value || {}; + field.html.tabindex_str = tabindex_str + input = '' + (field.html.text || '') + '' + + ''+ + '
'; + break; + case 'html': + case 'div': + case 'custom': + input = '
'+ + (field && field.html && field.html.html ? field.html.html : '') + + '
'; + break; + case 'empty': + input = (field && field.html ? (field.html.html || '') + (field.html.text || '') : ''); + break; + + } + if (group !== '') { + if(page != field.html.page || column != field.html.column || (field.html.group && (group != field.html.group))){ + pages[page][column] += '\n \n '; + group = ''; + } + } + if (field.html.group && (group != field.html.group)) { + var collapsable = ''; + if (field.html.groupCollapsable) { + collapsable = '' + } + html += '\n
' + + '\n
' + + collapsable + field.html.group + '
\n' + + '
'; + group = field.html.group; + } + if (field.html.anchor == null) { + var span = (field.html.span != null ? 'w2ui-span'+ field.html.span : '') + if (field.html.span == -1) span = 'w2ui-span-none'; + var label = '' + w2utils.lang(field.type != 'checkbox' ? field.html.label : field.html.text) +'' + if (!field.html.label) label = '' + html += '\n
'+ + '\n '+ label + + ((field.type === 'empty') ? input : '\n
'+ input + (field.type != 'array' && field.type != 'map' ? w2utils.lang(field.type != 'checkbox' ? field.html.text : '') : '') + '
') + + '\n
'; + } else { + pages[field.html.page].anchors = pages[field.html.page].anchors || {}; + pages[field.html.page].anchors[field.html.anchor] = '
'+ + ((field.type === 'empty') ? input : '
'+ w2utils.lang(field.type != 'checkbox' ? field.html.label : field.html.text) + input + w2utils.lang(field.type != 'checkbox' ? field.html.text : '') + '
') + + '
'; + } + if (pages[field.html.page] == null) pages[field.html.page] = {}; + if (pages[field.html.page][field.html.column] == null) pages[field.html.page][field.html.column] = ''; + pages[field.html.page][field.html.column] += html; + page = field.html.page; + column = field.html.column; + } + if (group !== '') pages[page][column] += '\n
\n
'; + if (this.tabs.tabs) { + for (var i = 0; i < this.tabs.tabs.length; i++) if (pages[i] == null) pages[i] = []; + } + // buttons if any + var buttons = ''; + if (!$.isEmptyObject(this.actions)) { + var addClass = ''; + buttons += '\n
'; + tabindex = this.tabindexBase + this.fields.length + 1; + + for (var a in this.actions) { // it is an object + var act = this.actions[a]; + var info = { text: '', style: '', "class": '' }; + if ($.isPlainObject(act)) { + if (act.text == null && act.caption != null) { + console.log('NOTICE: form action.caption property is deprecated, please use action.text. Action ->', act); + act.text = act.caption; + } + if (act.text) info.text = act.text; + if (act.style) info.style = act.style; + if (act["class"]) info['class'] = act['class']; + } else { + info.text = a; + if (['save', 'update', 'create'].indexOf(a.toLowerCase()) !== -1) info['class'] = 'w2ui-btn-blue'; else info['class'] = ''; + } + buttons += '\n '; + tabindex++; + } + buttons += '\n
'; + } + html = ''; + for (var p = 0; p < pages.length; p++){ + html += '
'; + if (pages[p].before) { + html += pages[p].before; + } + html += '
'; + Object.keys(pages[p]).sort().forEach(function (c, ind) { + if (c == parseInt(c)) { + html += '
' + (pages[p][c] || '') + '\n
'; + } + }) + html += '\n
'; + if (pages[p].after) { + html += pages[p].after; + } + html += '\n
'; + // process page anchors + if (pages[p].anchors) { + Object.keys(pages[p].anchors).forEach(function (key, ind) { + html = html.replace(key, pages[p].anchors[key]); + }); + } + } + html += buttons; + return html; + }, + + toggleGroup: function (groupName, show) { + var el = $(this.box).find('.w2ui-group-title[data-group="' + w2utils.base64encode(groupName) + '"]') + if (el.next().css('display') == 'none' && show !== true) { + el.next().slideDown(300); + el.next().next().remove() + el.find('span').addClass('w2ui-icon-collapse').removeClass('w2ui-icon-expand'); + } else { + el.next().slideUp(300); + var css = 'width: ' + el.next().css('width') + ';' + + 'padding-left: ' + el.next().css('padding-left') + ';' + + 'padding-right: ' + el.next().css('padding-right') + ';' + + 'margin-left: ' + el.next().css('margin-left') + ';' + + 'margin-right: ' + el.next().css('margin-right') + ';' + setTimeout(function () { el.next().after('
') }, 100) + el.find('span').addClass('w2ui-icon-expand').removeClass('w2ui-icon-collapse'); + } + }, + + action: function (action, event) { + var act = this.actions[action]; + var click = act; + if ($.isPlainObject(act) && act.onClick) click = act.onClick; + // event before + var edata = this.trigger({ phase: 'before', target: action, type: 'action', action: act, originalEvent: event }); + if (edata.isCancelled === true) return; + // default actions + if (typeof click === 'function') click.call(this, event); + // event after + this.trigger($.extend(edata, { phase: 'after' })); + }, + + resize: function () { + var obj = this; + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'resize' }); + if (edata.isCancelled === true) return; + // default behaviour + var main = $(this.box).find('> div.w2ui-form-box'); + var header = $(this.box).find('> div .w2ui-form-header'); + var toolbar = $(this.box).find('> div .w2ui-form-toolbar'); + var tabs = $(this.box).find('> div .w2ui-form-tabs'); + var page = $(this.box).find('> div .w2ui-page'); + var cpage = $(this.box).find('> div .w2ui-page.page-'+ this.page); + var dpage = $(this.box).find('> div .w2ui-page.page-'+ this.page + ' > div'); + var buttons = $(this.box).find('> div .w2ui-buttons'); + // if no height, calculate it + resizeElements(); + if (this.autosize) { //we don't need auto-size every time + if (parseInt($(this.box).height()) === 0 || $(this.box).data('auto-size') === true) { + $(this.box).height( + (header.length > 0 ? w2utils.getSize(header, 'height') : 0) + + ((typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') : 0) + + ((typeof this.toolbar === 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0) + + (page.length > 0 ? w2utils.getSize(dpage, 'height') + w2utils.getSize(cpage, '+height') + 12 : 0) + // why 12 ??? + (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) + ); + $(this.box).data('auto-size', true); + } + resizeElements(); + } + if (this.toolbar && this.toolbar.resize) this.toolbar.resize(); + if (this.tabs && this.tabs.resize) this.tabs.resize(); + // event after + obj.trigger($.extend(edata, { phase: 'after' })); + + function resizeElements() { + // resize elements + main.width($(obj.box).width()).height($(obj.box).height()); + toolbar.css('top', (obj.header !== '' ? w2utils.getSize(header, 'height') : 0)); + tabs.css('top', (obj.header !== '' ? w2utils.getSize(header, 'height') : 0) + + ((typeof obj.toolbar === 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0)); + page.css('top', (obj.header !== '' ? w2utils.getSize(header, 'height') : 0) + + ((typeof obj.toolbar === 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') + 5 : 0) + + ((typeof obj.tabs === 'object' && $.isArray(obj.tabs.tabs) && obj.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') + 5 : 0)); + page.css('bottom', (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0)); + } + }, + + refresh: function () { + var time = (new Date()).getTime(); + var obj = this; + if (!this.box) return; + if (!this.isGenerated || $(this.box).html() == null) return; + // event before + var edata = this.trigger({ phase: 'before', target: this.name, type: 'refresh', page: this.page, field: field, fields: arguments }); + if (edata.isCancelled === true) return; + var fields = Array.from(this.fields.keys()); + if (arguments.length > 0) { + fields = Array.from(arguments) + .map(function (fld, ind) { + if (typeof fld != 'string') console.log('ERROR: Arguments in refresh functions should be field names') + return this.get(fld, true); // get index of field + }.bind(this)) + .filter(function (fld, ind) { + if (fld != null) return true; else return false; + }); + } else { + // update what page field belongs + $(this.box).find('input, textarea, select').each(function (index, el) { + var name = ($(el).attr('name') != null ? $(el).attr('name') : $(el).attr('id')); + var field = obj.get(name); + if (field) { + // find page + var div = $(el).closest('.w2ui-page'); + if (div.length > 0) { + for (var i = 0; i < 100; i++) { + if (div.hasClass('page-'+i)) { field.page = i; break; } + } + } + } + }); + // default action + $(this.box).find('.w2ui-page').hide(); + $(this.box).find('.w2ui-page.page-' + this.page).show(); + $(this.box).find('.w2ui-form-header').html(this.header); + // refresh tabs if needed + if (typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) { + $('#form_'+ this.name +'_tabs').show(); + this.tabs.active = this.tabs.tabs[this.page].id; + this.tabs.refresh(); + } else { + $('#form_'+ this.name +'_tabs').hide(); + } + // refresh tabs if needed + if (typeof this.toolbar === 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) { + $('#form_'+ this.name +'_toolbar').show(); + this.toolbar.refresh(); + } else { + $('#form_'+ this.name +'_toolbar').hide(); + } + } + // refresh values of fields + for (var f = 0; f < fields.length; f++) { + var field = this.fields[fields[f]]; + if (field.name == null && field.field != null) field.name = field.field; + if (field.field == null && field.name != null) field.field = field.name; + field.$el = $(this.box).find('[name="'+ String(field.name).replace(/\\/g, '\\\\') +'"]'); + field.el = field.$el[0]; + if (field.el) field.el.id = field.name; + var tmp = $(field).data('w2field'); + if (tmp) tmp.clear(); + $(field.$el) + .off('.w2form') + .on('change.w2form', function (event) { + var that = this; + var field = obj.get(this.name); + if (field == null) return; + if ($(this).data('skip_change') == true) { + $(this).data('skip_change', false) + return + } + + var value_new = this.value; + var value_previous = obj.getValue(this.name); + if (value_previous == null) value_previous = '' + + if (['list', 'enum', 'file'].indexOf(field.type) !== -1 && $(this).data('selected')) { + var nv = $(this).data('selected'); + var cv = obj.getValue(this.name); + if ($.isArray(nv)) { + value_new = []; + for (var i = 0; i < nv.length; i++) value_new[i] = $.extend(true, {}, nv[i]); // clone array + } + if ($.isPlainObject(nv)) { + value_new = $.extend(true, {}, nv); // clone object + } + if ($.isArray(cv)) { + value_previous = []; + for (var i = 0; i < cv.length; i++) value_previous[i] = $.extend(true, {}, cv[i]); // clone array + } + if ($.isPlainObject(cv)) { + value_previous = $.extend(true, {}, cv); // clone object + } + } + if (['toggle', 'checkbox'].indexOf(field.type) !== -1) { + value_new = ($(this).prop('checked') ? ($(this).prop('value') === 'on' ? true : $(this).prop('value')) : false); + } + if (['check', 'checks'].indexOf(field.type) !== -1) { + if (!Array.isArray(value_previous)) value_previous = []; + value_new = value_previous.slice(); + var tmp = field.options.items[$(this).attr('data-index')]; + if ($(this).prop('checked')) { + value_new.push(tmp.id) + } else { + value_new.splice(value_new.indexOf(tmp.id), 1) + } + } + // clean extra chars + if (['int', 'float', 'percent', 'money', 'currency'].indexOf(field.type) !== -1) { + value_new = $(this).data('w2field').clean(value_new); + } + if (value_new === value_previous) return; + // event before + var edata2 = obj.trigger({ phase: 'before', target: this.name, type: 'change', value_new: value_new, value_previous: value_previous, originalEvent: event }); + if (edata2.isCancelled === true) { + edata2.value_new = obj.getValue(this.name) + if ($(this).val() !== edata2.value_new) { + $(this).data('skip_change', true) + // if not immediate, then ignore it + setTimeout(function () { $(that).data('skip_change', false) }, 10) + } + $(this).val(edata2.value_new); // return previous value + } + // default action + var val = edata2.value_new; + if (['enum', 'file'].indexOf(field.type) !== -1) { + if (val.length > 0) { + var fld = $(field.el).data('w2field').helpers.multi; + $(fld).removeClass('w2ui-error'); + } + } + if (val === '' || val == null + || ($.isArray(val) && val.length === 0) || ($.isPlainObject(val) && $.isEmptyObject(val))) { + val = null; + } + obj.setValue(this.name, val); + // event after + obj.trigger($.extend(edata2, { phase: 'after' })); + }) + .on('input.w2form', function (event) { + var val = this.value; + if (event.target.type == 'checkbox') { + val = event.target.checked; + } + // remember original + if (obj.original == null) { + if (!$.isEmptyObject(obj.record)) { + obj.original = $.extend(true, {}, obj.record); + } else { + obj.original = {}; + } + } + // event before + var edata2 = obj.trigger({ phase: 'before', target: this.name, type: 'input', value_new: val, originalEvent: event }); + if (edata2.isCancelled === true) return; + + // event after + obj.trigger($.extend(edata2, { phase: 'after' })); + }); + // required + if (field.required) { + $(field.el).parent().parent().addClass('w2ui-required'); + } else { + $(field.el).parent().parent().removeClass('w2ui-required'); + } + // disabled + if (field.disabled != null) { + var $fld = $(field.el); + if (field.disabled) { + if ($fld.data('w2ui-tabIndex') == null) { + $fld.data('w2ui-tabIndex', $fld.prop('tabIndex')); + } + $(field.el) + .prop('readonly', true) + .prop('tabindex', -1) + .closest('.w2ui-field') + .addClass('w2ui-disabled'); + } else { + $(field.el) + .prop('readonly', false) + .prop('tabIndex', $fld.data('w2ui-tabIndex')) + .closest('.w2ui-field') + .removeClass('w2ui-disabled'); + } + } + // hidden + var tmp = field.el; + if (!tmp) tmp = $(this.box).find('#' + field.field) + if (field.hidden) { + $(tmp).closest('.w2ui-field').hide(); + } else { + $(tmp).closest('.w2ui-field').show(); + } + } + // attach actions on buttons + $(this.box).find('button, input[type=button]').each(function (index, el) { + $(el).off('click').on('click', function (event) { + var action = this.value; + if (this.id) action = this.id; + if (this.name) action = this.name; + obj.action(action, event); + }); + }); + // init controls with record + for (var f = 0; f < fields.length; f++) { + var field = this.fields[fields[f]]; + var value = (this.getValue(field.name) != null ? this.getValue(field.name) : ''); + if (!field.el) continue; + if (!$(field.el).hasClass('w2ui-input')) $(field.el).addClass('w2ui-input'); + field.type = String(field.type).toLowerCase(); + if (!field.options) field.options = {}; + switch (field.type) { + case 'text': + case 'textarea': + case 'email': + case 'pass': + case 'password': + field.el.value = value; + break; + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + // issue #761 + field.el.value = value; + $(field.el).w2field($.extend({}, field.options, { type: field.type })); + break; + case 'hex': + case 'alphanumeric': + case 'color': + case 'date': + case 'time': + field.el.value = value; + $(field.el).w2field($.extend({}, field.options, { type: field.type })); + break; + case 'toggle': + if (w2utils.isFloat(value)) value = parseFloat(value); + $(field.el).prop('checked', (value ? true : false)); + this.setValue(field.name, (value ? value : false)); + break; + case 'radio': + $(field.$el).prop('checked', false).each(function (index, el) { + if ($(el).val() == value) $(el).prop('checked', true); + }); + break; + case 'checkbox': + $(field.el).prop('checked', value ? true : false); + if (field.disabled === true || field.disabled === false) { + $(field.el).prop('disabled', field.disabled ? true : false) + } + break; + case 'check': + case 'checks': + if (Array.isArray(value)) { + value.forEach(function (val) { + $(field.el).closest('div').find('[data-value="' + val + '"]').prop('checked', true) + }) + } + if (field.disabled) { + $(field.el).closest('div').find('input[type=checkbox]').prop('disabled', true) + } else { + $(field.el).closest('div').find('input[type=checkbox]').removeProp('disabled') + } + break; + // enums + case 'list': + case 'combo': + if (field.type === 'list') { + var tmp_value = ($.isPlainObject(value) ? value.id : ($.isPlainObject(field.options.selected) ? field.options.selected.id : value)); + // normalized options + if (!field.options.items) field.options.items = []; + var items = field.options.items; + if (typeof items == 'function') items = items(); + // find value from items + var isFound = false; + if (Array.isArray(items)) { + for (var i = 0; i < items.length; i++) { + var item = items[i]; + if (item.id == tmp_value) { + value = $.extend(true, {}, item); + obj.setValue(field.name, value); + isFound = true; + break; + } + } + } + if (!isFound && value != null && value !== '') { + field.$el.data('find_selected', value); + } + } else if (field.type === 'combo' && !$.isPlainObject(value)) { + field.el.value = value; + } else if ($.isPlainObject(value) && value.text != null) { + field.el.value = value.text; + } else { + field.el.value = ''; + } + if (!$.isPlainObject(value)) value = {}; + $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); + break; + case 'enum': + case 'file': + var sel = []; + var isFound = false; + if (!$.isArray(value)) value = []; + if (typeof field.options.items != 'function') { + if (!$.isArray(field.options.items)) { + field.options.items = []; + } + // find value from items + value.forEach(function (val) { + field.options.items.forEach(function (it) { + if (it && (it.id == val || ($.isPlainObject(val) && it.id == val.id))) { + sel.push($.isPlainObject(it) ? $.extend(true, {}, it) : it); + isFound = true + } + }) + }) + } + if (!isFound && value != null && value.length !== 0) { + field.$el.data('find_selected', value); + sel = value + } + var opt = $.extend({}, field.options, { type: field.type, selected: sel }) + Object.keys(field.options).forEach(function(key) { + if (typeof field.options[key] == 'function') { + opt[key] = field.options[key] + } + }) + $(field.el).w2field(opt); + break; + + // standard HTML + case 'select': + // generate options + var items = field.options.items; + if (items != null && items.length > 0) { + items = w2obj.field.prototype.normMenu.call(this, items, field); + $(field.el).html(''); + for (var it = 0; it < items.length; it++) { + $(field.el).append('";a.addClass("w2ui-editable").html('"+s.outTag),setTimeout(function(){a.find("select").on("change",function(e){delete u.last.move}).on("blur",function(e){1!=$(this).data("keep-open")&&u.editChange.call(u,this,c,d,e)})},10);break;case"div":var y="font-family: "+(x=o.find("[col="+d+"] > div")).css("font-family")+"; font-size: "+x.css("font-size")+";";a.addClass("w2ui-editable").html('
"+s.outTag),null==e&&a.find("div.w2ui-input").text("object"!=typeof f?f:"");var b=a.find("div.w2ui-input").get(0);setTimeout(function(){var t=b;$(t).on("blur",function(e){1!=$(this).data("keep-open")&&u.editChange.call(u,t,c,d,e)})},10),null!=e&&$(b).text("object"!=typeof f?f:"");break;default:var x,y="font-family: "+(x=o.find("[col="+d+"] > div")).css("font-family")+"; font-size: "+x.css("font-size");a.addClass("w2ui-editable").html('"+s.outTag),"number"==s.type&&(f=w2utils.formatNumber(f)),"date"==s.type&&(f=w2utils.formatDate(w2utils.isDate(f,s.format,!0)||new Date,s.format)),null==e&&a.find("input").val("object"!=typeof f?f:"");b=a.find("input").get(0);$(b).w2field(s.type,$.extend(s,{selected:f})),setTimeout(function(){var e=b;"list"==s.type&&(e=$($(b).data("w2field").helpers.focus).find("input"),"object"!=typeof f&&""!=f&&e.val(f).css({opacity:1}).prev().css({opacity:1}),a.find("input").on("change",function(e){u.editChange.call(u,b,c,d,e)})),$(e).on("blur",function(e){1!=$(this).data("keep-open")&&u.editChange.call(u,b,c,d,e)})},10),null!=e&&$(b).val("object"!=typeof f?f:"")}setTimeout(function(){u.last.inEditMode&&(a.find("input, select, div.w2ui-input").data("old_value",g).on("mousedown",function(e){e.stopPropagation()}).on("click",function(e){"div"==s.type?_.call(a.find("div.w2ui-input")[0],null):_.call(a.find("input, select")[0],null)}).on("paste",function(e){var t=e.originalEvent;e.preventDefault();t=t.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,t)}).on("keydown",function(o){var a=this,e="DIV"==a.tagName.toUpperCase()?$(a).text():$(a).val();switch(o.keyCode){case 8:"list"!=s.type||$(b).data("w2field")||o.preventDefault();break;case 9:case 13:o.preventDefault();break;case 37:0===w2utils.getCursorPosition(a)&&o.preventDefault();break;case 39:w2utils.getCursorPosition(a)==e.length&&(w2utils.setCursorPosition(a,e.length),o.preventDefault())}setTimeout(function(){switch(o.keyCode){case 9:var e=r,t=o.shiftKey?u.prevCell(c,d,!0):u.nextCell(c,d,!0);if(null==t){var i=o.shiftKey?u.prevRow(c,d):u.nextRow(c,d);if(null!=i&&i!=c)for(var e=u.records[i].recid,s=0;si.width()&&i.width(s+20)}catch(e){}}},editChange:function(e,t,i,s){var n=this;setTimeout(function(){var e=$(n.box).find("#grid_"+n.name+"_focus");e.is(":focus")||e.focus()},10);var l=t<0;t=t<0?-t-1:t;var o=(l?this.summary:this.records)[t],a=this.columns[i],r=$("#grid_"+this.name+(!0===a.frozen?"_frec_":"_rec_")+w2utils.escapeId(o.recid)),d=e.tagName&&"DIV"==e.tagName.toUpperCase()?$(e).text():e.value,u=this.parseField(o,a.field),c=$(e).data("w2field");c&&("list"==c.type&&(d=$(e).data("selected")),!$.isEmptyObject(d)&&null!=d||(d=""),$.isPlainObject(d)||(d=c.clean(d))),"checkbox"==e.type&&(o.w2ui&&!1===o.w2ui.editable&&(e.checked=!e.checked),d=e.checked);var h={phase:"before",type:"change",target:this.name,input_id:e.id,recid:o.recid,index:t,column:i,originalEvent:s.originalEvent||s,value_new:d,value_previous:o.w2ui&&o.w2ui.changes&&o.w2ui.changes.hasOwnProperty(a.field)?o.w2ui.changes[a.field]:u,value_original:u};for(null!=$(s.target).data("old_value")&&(h.value_previous=$(s.target).data("old_value"));;){if("object"!=typeof(d=h.value_new)&&String(u)!=String(d)||"object"==typeof d&&d&&d.id!=u&&("object"!=typeof u||null==u||d.id!=u.id)){if(!0!==(h=this.trigger($.extend(h,{type:"change",phase:"before"}))).isCancelled){if(d!==h.value_new)continue;o.w2ui=o.w2ui||{},o.w2ui.changes=o.w2ui.changes||{},o.w2ui.changes[a.field]=h.value_new,this.trigger($.extend(h,{phase:"after"}))}}else if(!0!==(h=this.trigger($.extend(h,{type:"restore",phase:"before"}))).isCancelled){if(d!==h.value_new)continue;o.w2ui&&o.w2ui.changes&&delete o.w2ui.changes[a.field],o.w2ui&&$.isEmptyObject(o.w2ui.changes)&&delete o.w2ui.changes,this.trigger($.extend(h,{phase:"after"}))}break}r=$(r).find("[col="+i+"]");l||(o.w2ui&&o.w2ui.changes&&null!=o.w2ui.changes[a.field]?r.addClass("w2ui-changed"):r.removeClass("w2ui-changed"),r.replaceWith(this.getCellHTML(t,i,l))),$(this.box).find("div.w2ui-edit-box").remove(),this.show.toolbarSave&&(0'+w2utils.lang(i.msgDelete).replace("NN",s.length).replace("records",1==s.length?"record":"records")+"",buttons:w2utils.settings.macButtonOrder?'":'",onOpen:function(e){var t=$(this.box).find("input, textarea, select, button");t.off(".message").on("blur.message",function(e){t.index(e.target)+1===t.length&&(t.get(0).focus(),e.preventDefault())}).on("keydown.message",function(e){27==e.keyCode&&i.message()}),setTimeout(function(){$(this.box).find(".w2ui-btn.btn-default").focus(),clearTimeout(i.last.kbd_timer)}.bind(this),50)}})}},click:function(e,t){var i=(new Date).getTime(),s=null;if(!(1==this.last.cancelClick||t&&t.altKey))if("object"==typeof e&&null!==e&&(s=e.column,e=e.recid),null==t&&(t={}),i-parseInt(this.last.click_time)<350&&this.last.click_recid==e&&"click"==t.type)this.dblClick(e,t);else{this.last.bubbleEl&&($(this.last.bubbleEl).w2tag(),this.last.bubbleEl=null),this.last.click_time=i;var n=this.last.click_recid;this.last.click_recid=e,null==s&&t.target&&("TD"!=(v=t.target).tagName.toUpperCase()&&(v=$(v).parents("td")[0]),null!=$(v).attr("col")&&(s=parseInt($(v).attr("col"))));var l=this.trigger({phase:"before",target:this.name,type:"click",recid:e,column:s,originalEvent:t});if(!0!==l.isCancelled){var o=this,a=this.getSelection();$("#grid_"+this.name+"_check_all").prop("checked",!1);var i=this.get(e,!0),r=(this.records[i],[]);if(o.last.sel_ind=i,o.last.sel_col=s,o.last.sel_recid=e,o.last.sel_type="click",t.shiftKey&&0a[0].column?(d=a[0].column,s):(d=s,a[0].column);for(var p=d;p<=u;p++)r.push(p)}else c=this.get(n,!0),h=this.get(e,!0);var f=[];h=this.records.length?this.selectNone():this.selectAll());else if(t.altKey&&(s=this.getColumn(e))&&s.sortable&&this.sort(e,null,!(!t||!t.ctrlKey&&!t.metaKey)),"line-number"==i.field)this.getSelection().length>=this.records.length?this.selectNone():this.selectAll();else{t.shiftKey||t.metaKey||t.ctrlKey||this.selectNone();var i,e=this.getSelection(),s=this.getColumn(i.field,!0),n=[],l=[];if(0!=e.length&&t.shiftKey){var t=s,o=e[0].column;o.w2ui-message").length)27==i.keyCode&&this.message();else{var n=!1,l=$("#grid_"+s.name+"_records"),o=s.getSelection();0===o.length&&(n=!0);var a=o[0]||null,r=[],d=o[o.length-1];if("object"==typeof a&&null!=a){for(var a=o[0].recid,r=[],u=0;o[u]&&o[u].recid==a;)r.push(o[u].column),u++;d=o[o.length-1].recid}var c=s.get(a,!0),h=s.get(d,!0),p=(s.get(a),$("#grid_"+s.name+"_rec_"+(null!=c?w2utils.escapeId(s.records[c].recid):"none"))),f=!1,g=i.keyCode,m=i.shiftKey;switch(g){case 8:case 46:s.delete(),f=!0,i.stopPropagation();break;case 27:s.selectNone(),f=!0;break;case 65:if(!i.metaKey&&!i.ctrlKey)break;s.selectAll(),f=!0;break;case 13:if("row"==this.selectType&&!0===s.show.expandColumn){if(p.length<=0)break;s.toggle(a,i),f=!0}else{for(var w=0;wv&&s.last.sel_ind!=h?s.unselect(s.records[h].recid):s.select(s.records[v].recid);else if(s.last.sel_ind>v&&s.last.sel_ind!=h){v=h;for(y=[],w=0;w
'),$("#grid_"+this.name+"_frec_"+n).after(''+(this.show.lineNumbers?'':"")+'
'),!0===(s=this.trigger({phase:"before",type:"expand",target:this.name,recid:e,box_id:"grid_"+this.name+"_rec_"+e+"_expanded",fbox_id:"grid_"+this.name+"_frec_"+n+"_expanded"})).isCancelled)return $("#grid_"+this.name+"_rec_"+n+"_expanded_row").remove(),$("#grid_"+this.name+"_frec_"+n+"_expanded_row").remove(),!1;var o=$(this.box).find("#grid_"+this.name+"_rec_"+e+"_expanded"),t=$(this.box).find("#grid_"+this.name+"_frec_"+e+"_expanded"),l=o.find("> div:first-child").height();o.height()o&&(o=i[r].column),-1==a.indexOf(i[r].index)&&a.push(i[r].index);a.sort(function(e,t){return e-t});for(var d=0;d div.w2ui-grid-box").css("width",$(this.box).width()).css("height",$(this.box).height());var i=this.trigger({phase:"before",type:"resize",target:this.name});if(!0!==i.isCancelled)return e.resizeBoxes(),e.resizeRecords(),e.toolbar&&e.toolbar.resize&&e.toolbar.resize(),this.trigger($.extend(i,{phase:"after"})),(new Date).getTime()-t}},update:function(e){var t=(new Date).getTime();if(null==this.box)return 0;if(null==e){for(var i=this.last.range_start-1;i<=this.last.range_end-1;i++)if(!(i<0)){(o=this.records[i]||{}).w2ui||(o.w2ui={});for(var s=0;s'+i[0]+'
"+i[1]+'
'+s[0]+'
'+s[1]+"
",l=$("#grid_"+this.name+"_body",n.box).html(s),o=$("#grid_"+this.name+"_records",n.box),s=$("#grid_"+this.name+"_frecords",n.box),a=this;"row"==this.selectType&&(o.on("mouseover mouseout","tr",function(e){$("#grid_"+a.name+"_frec_"+w2utils.escapeId($(this).attr("recid"))).toggleClass("w2ui-record-hover","mouseover"==e.type)}),s.on("mouseover mouseout","tr",function(e){$("#grid_"+a.name+"_rec_"+w2utils.escapeId($(this).attr("recid"))).toggleClass("w2ui-record-hover","mouseover"==e.type)})),w2utils.isIOS?o.add(s).on("click","tr",function(e){a.dblClick($(this).attr("recid"),e)}):o.add(s).on("click","tr",function(e){a.click($(this).attr("recid"),e)}).on("contextmenu","tr",function(e){a.contextMenu($(this).attr("recid"),null,e)}),l.data("scrolldata",{lastTime:0,lastDelta:0,time:0}).find(".w2ui-grid-frecords").on("mousewheel DOMMouseScroll ",function(e){e.preventDefault();var t=e.originalEvent,i=l.data("scrolldata"),s=$(this).siblings(".w2ui-grid-records").addBack().filter(".w2ui-grid-records"),e=null!=typeof t.wheelDelta?-1*t.wheelDelta/120:(t.detail||t.deltaY)/3,t=s.scrollTop();i.time=+new Date,i.lastTime
'+this.msgEmpty+"
"):0<$("#grid_"+this.name+"_empty_msg").length&&$("#grid_"+this.name+"_empty_msg").remove(),0=this.searches.length?(this.last.field="",this.last.label=""):(this.last.field=this.searches[n].field,this.last.label=this.searches[n].label)}$(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-grid w2ui-inactive").html('
"),"row"!=this.selectType&&$(this.box).addClass("w2ui-ss"),0<$(this.box).length&&($(this.box)[0].style.cssText+=this.style),this.initToolbar(),null!=this.toolbar&&this.toolbar.render($("#grid_"+this.name+"_toolbar")[0]),this.last.field&&"all"!=this.last.field&&(i=this.searchData,setTimeout(function(){x.initAllField(x.last.field,1==i.length?i[0].value:null)},1)),$("#grid_"+this.name+"_footer").html(this.getFooterHTML()),this.last.state||(this.last.state=this.stateSave(!0)),this.stateRestore(),s&&(this.clear(),this.refresh());for(var _,l=!1,o=0;o
'),(u=$(x.box).find(".w2ui-grid-records")).append('
'),u.append('
'),$("#grid_"+x.name+"_ghost").append(t).append(r.ghost)),d=$("#grid_"+x.name+"_ghost"),u=$(x.box).find(".w2ui-grid-records"),d.css({top:r.pos.top+u.scrollTop(),left:r.pos.left,"border-top":"1px solid #aaa","border-bottom":"1px solid #aaa"})):x.last.move.reorder=!1)}$(document).on("mousemove.w2ui-"+x.name,c).on("mouseup.w2ui-"+x.name,h),e.stopPropagation()}),this.updateToolbar(),this.trigger($.extend(e,{phase:"after"})),0===$(".w2ui-layout").length&&$(window).off("resize.w2ui-"+x.name).on("resize.w2ui-"+x.name,function(e){null==w2ui[x.name]?$(window).off("resize.w2ui-"+x.name):w2ui[x.name].resize()}),(new Date).getTime()-t}}function c(e){var t=x.last.move;if(t&&-1!=["select","select-column"].indexOf(t.type)&&(t.divX=e.screenX-t.x,t.divY=e.screenY-t.y,!(Math.abs(t.divX)<=1&&Math.abs(t.divY)<=1))){if(x.last.cancelClick=!0,1==x.reorderRows&&x.last.move.reorder){var i,s,n=$(x.box).find(".w2ui-grid-records");return(l="-none-"==(l=(d=$(e.target).parents("tr")).attr("recid"))?"bottom":l)!=t.from&&($("#grid_"+x.name+"_rec_"+t.recid),s=$("#grid_"+x.name+"_rec_"+l),$(x.box).find(".insert-before"),s.addClass("insert-before"),t.lastY=e.screenY,t.to=l,i=s.position(),s=$("#grid_"+x.name+"_ghost_line"),i?s.css({top:i.top+n.scrollTop(),left:t.pos.left,"border-top":"2px solid #769EFC"}):s.css({"border-top":"2px solid transparent"})),void $("#grid_"+x.name+"_ghost").css({top:t.pos.top+t.divY+n.scrollTop(),left:t.pos.left})}t.start&&t.recid&&(x.selectNone(),t.start=!1);var l,o=[];if(null==(l=("TR"==e.target.tagName.toUpperCase()?$(e.target):$(e.target).parents("tr")).attr("recid"))){if("row"!=x.selectType&&(!x.last.move||"select"!=x.last.move.type)){n=parseInt($(e.target).parents("td").attr("col"));if(isNaN(n))x.removeRange("column-selection"),$(x.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected"),$(x.box).find(".w2ui-col-number").removeClass("w2ui-row-selected"),delete t.colRange;else{var a=n+"-"+n;t.columnn?n+"-"+t.column:a).split("-"),u=parseInt(d[0]);u<=parseInt(d[1]);u++)r.push(u);if(t.colRange!=a&&!0!==(_=x.trigger({phase:"before",type:"columnSelect",target:x.name,columns:r,isCancelled:!1})).isCancelled){null==t.colRange&&x.selectNone();d=a.split("-");$(x.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected");for(var c=parseInt(d[0]);c<=parseInt(d[1]);c++)$(x.box).find("#grid_"+x.name+"_column_"+c+" .w2ui-col-header").addClass("w2ui-col-selected");$(x.box).find(".w2ui-col-number").not(".w2ui-head").addClass("w2ui-row-selected"),t.colRange=a,x.removeRange("column-selection"),x.addRange({name:"column-selection",range:[{recid:x.records[0].recid,column:d[0]},{recid:x.records[x.records.length-1].recid,column:d[1]}],style:"background-color: rgba(90, 145, 234, 0.1)"})}}}}else{a=x.get(t.recid,!0);if(!(null==a||x.records[a]&&x.records[a].recid!=t.recid))if(null!=(h=x.get(l,!0))){var h,p=parseInt(t.column),f=parseInt(("TD"==e.target.tagName.toUpperCase()?$(e.target):$(e.target).parents("td")).attr("col"));isNaN(p)&&isNaN(f)&&(p=0,f=x.columns.length-1),h",i=0;i ")}var l="object"!=typeof this.url?this.url:this.url.get;(l&&e.show.skipRecords||e.show.saveRestoreState)&&(t+=''),l&&e.show.skipRecords&&(t+='"),e.show.saveRestoreState&&(t+='"),t+="
'+w2utils.lang("Skip")+' "+w2utils.lang("Records")+"
"+w2utils.lang("Save Grid State")+'
"+w2utils.lang("Restore Default State")+"
",this.toolbar.get("w2ui-column-on-off").html=t}},initColumnDrag:function(e){if(this.columnGroups&&this.columnGroups.length)throw"Draggable columns are not currently supported with column groups.";var r=this,d={};function t(){d.pressed=!1,clearTimeout(d.timeout)}function i(o){d.timeout&&clearTimeout(d.timeout);var a=this;d.pressed=!0,d.timeout=setTimeout(function(){if(d.pressed&&0!==d.numberPreColumnsPresent){var e,t,i,s=["w2ui-col-number","w2ui-col-expand","w2ui-col-select"].concat(["w2ui-head-last"]);if($(o.originalEvent.target).parents().hasClass("w2ui-head")){for(var n=0,l=s.length;n=t[t.length-1]+i)return t.length;for(var s=0,n=t.length;s
'),d.markerLeft=$('
'));d.lastInt&&d.lastInt===e||(d.lastInt=e,d.marker.remove(),d.markerLeft.remove(),$(".w2ui-head").removeClass("w2ui-col-intersection"),e>=d.columns.length?($(d.columns[d.columns.length-1]).children("div:last").append(d.marker.addClass("right").removeClass("left")),$(d.columns[d.columns.length-1]).addClass("w2ui-col-intersection")):e<=d.numberPreColumnsPresent?($(d.columns[d.numberPreColumnsPresent]).prepend(d.marker.addClass("left").removeClass("right")).css({position:"relative"}),$(d.columns[d.numberPreColumnsPresent]).prev().addClass("w2ui-col-intersection")):($(d.columns[e]).children("div:last").prepend(d.marker.addClass("left").removeClass("right")),$(d.columns[e]).prev().children("div:last").append(d.markerLeft.addClass("right").removeClass("left")).css({position:"relative"}),$(d.columns[e-1]).addClass("w2ui-col-intersection")))}(d.targetInt),i=i,s=s,$(d.ghost).css({left:i-10,top:s-10}))}function c(e){d.pressed=!1;var t,i,s,n=$(".w2ui-grid-ghost"),l=r.trigger({type:"columnDragEnd",phase:"before",originalEvent:e,target:d.columnHead[0]});if(!0===l.isCancelled)return!1;t=r.columns[d.originalPos],i=r.columns,s=$(d.columns[Math.min(d.lastInt,d.columns.length-1)]),(e=d.lastInt
'+this.buttons.search.html+'
',this.toolbar.items.push({type:"html",id:"w2ui-search",html:e})),this.show.toolbarSearch&&this.multiSearch&&0 div',n.box).each(function(){var e=this.offsetWidth-this.scrollWidth;e div.w2ui-grid-box"),i=$("#grid_"+this.name+"_header"),s=$("#grid_"+this.name+"_toolbar"),n=$("#grid_"+this.name+"_summary"),o=$("#grid_"+this.name+"_fsummary"),a=$("#grid_"+this.name+"_footer"),r=$("#grid_"+this.name+"_body"),d=$("#grid_"+this.name+"_columns"),u=$("#grid_"+this.name+"_fcolumns"),c=$("#grid_"+this.name+"_records"),h=$("#grid_"+this.name+"_frecords"),p=$("#grid_"+this.name+"_scroll1"),f=8*String(this.total).length+10;f<34&&(f=34),null!=this.lineNumberWidth&&(f=this.lineNumberWidth);for(var g,m=!1,w=!1,v=0,y=0;ytable").height()+(m?w2utils.scrollBarSize():0)&&(w=!0),this.fixedBody?(g=t.height()-(this.show.header?w2utils.getSize(i,"height"):0)-(this.show.toolbar?w2utils.getSize(s,"height"):0)-("none"!=n.css("display")?w2utils.getSize(n,"height"):0)-(this.show.footer?w2utils.getSize(a,"height"):0),r.css("height",g)):(g=w2utils.getSize(d,"height")+w2utils.getSize($("#grid_"+l.name+"_records table"),"height")+(m?w2utils.scrollBarSize():0),l.height=g+w2utils.getSize(t,"+height")+(l.show.header?w2utils.getSize(i,"height"):0)+(l.show.toolbar?w2utils.getSize(s,"height"):0)+("none"!=n.css("display")?w2utils.getSize(n,"height"):0)+(l.show.footer?w2utils.getSize(a,"height"):0),t.css("height",l.height),r.css("height",g),e.css("height",w2utils.getSize(t,"height")+w2utils.getSize(e,"+height")));t=this.records.length,e="object"!=typeof this.url?this.url:this.url.get;if(0==this.searchData.length||e||(t=this.last.searchIds.length),this.fixedBody||(w=!1),m||w?(d.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show(),c.css({top:(0 table > tbody > tr:nth-child(1) td.w2ui-head-last").hide(),c.css({top:(0=this.recordHeight&&(m-=this.recordHeight,b++),this.fixedBody){for(var x=t;x',l+='',i.show.lineNumbers&&(n+=''),i.show.selectColumn&&(n+=''),i.show.expandColumn&&(n+=''),l+='',i.show.orderColumn&&(l+='');for(var o=0;oi.last.colEnd)&&!a.frozen||(s='',a.frozen?n+=s:l+=s)}n+=' ',l+=' ',$("#grid_"+i.name+"_frecords > table").append(n),$("#grid_"+i.name+"_records > table").append(l)}if(0C&&!0!==D.hidden&&(S=D.hidden=!0),D.gridMinWidthparseInt(D.max)&&(D.sizeCalculated=D.max+"px"),O+=parseInt(D.sizeCalculated));var z=parseInt(C)-parseInt(O);if(0 table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show();var I=1;this.show.lineNumbers&&(I+=f),this.show.selectColumn&&(I+=26),this.show.expandColumn&&(I+=26);for(y=0;y table > tbody > tr:nth-child(1) td").add(u.find("> table > tbody > tr:nth-child(1) td")).each(function(e,t){$(t).hasClass("w2ui-col-number")&&$(t).css("width",f);var i=$(t).attr("col");if(null!=i){if("start"==i){for(var s=0,n=0;n table > tbody > tr").length&&d.find("> table > tbody > tr:nth-child(1) td").add(u.find("> table > tbody > tr:nth-child(1) td")).html("").css({height:"0px",border:"0px",padding:"0px",margin:"0px"}),c.find("> table > tbody > tr:nth-child(1) td").add(h.find("> table > tbody > tr:nth-child(1) td")).each(function(e,t){$(t).hasClass("w2ui-col-number")&&$(t).css("width",f);var i=$(t).attr("col");if(null!=i){if("start"==i){for(var s=0,n=0;n table > tbody > tr:nth-child(1) td").add(o.find("> table > tbody > tr:nth-child(1) td")).each(function(e,t){$(t).hasClass("w2ui-col-number")&&$(t).css("width",f);var i=$(t).attr("col");if(null!=i){if("start"==i){for(var s=0,n=0;n',t=!1,i=0;iX",t=!0),null==s.inTag&&(s.inTag=""),null==s.outTag&&(s.outTag=""),null==s.style&&(s.style=""),null==s.type&&(s.type="text"),null==s.label&&null!=s.caption&&(console.log("NOTICE: grid search.caption property is deprecated, please use search.label. Search ->",s),s.label=s.caption);var l='";switch(e+=' '+n+' '+(s.label||"")+' '+l+' ',s.type){case"text":case"alphanumeric":case"hex":case"color":case"list":case"combo":case"enum":var o="width: 250px;";-1!=["hex","color"].indexOf(s.type)&&(o="width: 90px;"),e+='";break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":case"datetime":o="width: 90px;";e+='";break;case"select":e+='"}e+=s.outTag+" "}}return e+='
"},initOperator:function(e,t){var i=this.searches[t],s=$("#grid_"+this.name+"_range_"+t),n=$("#grid_"+this.name+"_field_"+t),l=n.parent().find("span input");switch(n.show(),s.hide(),$(e).val()){case"between":s.show(),l.w2field(i.type,i.options);break;case"not null":case"null":n.hide(),n.val("1"),n.change()}},initSearches:function(){for(var t=this,e=0;e--',o=0;o'+(u=null==u&&null!=c.text?c.text:u)+""):r+='"}$("#grid_"+this.name+"_field_"+e).html(r)}null!=s?("int"==s.type&&-1!=["in","not in"].indexOf(s.operator)&&$("#grid_"+this.name+"_field_"+e).w2field("clear").val(s.value),$("#grid_"+this.name+"_operator_"+e).val(s.operator).trigger("change"),$.isArray(s.value)?-1!=["in","not in"].indexOf(s.operator)?$("#grid_"+this.name+"_field_"+e).val(s.value).trigger("change"):($("#grid_"+this.name+"_field_"+e).val(s.value[0]).trigger("change"),$("#grid_"+this.name+"_field2_"+e).val(s.value[1]).trigger("change")):null!=s.value&&$("#grid_"+this.name+"_field_"+e).val(s.value).trigger("change")):$("#grid_"+this.name+"_operator_"+e).val(l).trigger("change")}$("#w2ui-overlay-"+this.name+"-searchOverlay .w2ui-grid-searches *[rel=search]").on("keypress",function(e){13==e.keyCode&&(t.search(),$().w2overlay({name:t.name+"-searchOverlay"}))})},getColumnsHTML:function(){var e,t,i,f=this,s="",n="";return this.show.columnHeaders&&(n=0 ",f.columnGroups[s]),f.columnGroups[s].text=f.columnGroups[s].caption);""!=f.columnGroups[f.columnGroups.length-1].text&&f.columnGroups.push({text:""});f.show.lineNumbers&&(e+='
 
');f.show.selectColumn&&(e+='
 
');f.show.expandColumn&&(e+='
 
');var n=0;t+='',f.show.orderColumn&&(t+='
 
');for(var l=0;l",a),a.text=a.caption);for(var r=0,d=n;d');var p="function"==typeof a.text?a.text(a):a.text;i='"+h+'
'+(p||" ")+"
",a&&a.frozen?e+=i:t+=i}else{p="function"==typeof o.text?o.text(o):o.text;i='
'+(p||" ")+"
",a&&a.frozen?e+=i:t+=i}n+=o.span}return e+="",t+='',[e,t]}(),i=l(!1),s=e[0]+t[0]+i[0],e[1]+t[1]+i[1]):(s=(i=l(!0))[0],i[1])),[s,n];function l(e){var t="",i="";f.show.lineNumbers&&(t+='
#
"),f.show.selectColumn&&(t+='
"),f.show.expandColumn&&(t+='
 
');var s,n=0,l=0;i+='',f.show.orderColumn&&(i+='
 
');for(var o=0;o ",r),r.text=r.caption),null==r.size&&(r.size="100%"),o==l&&(l+=(s=f.columnGroups[n++]||{}).span),(of.last.colEnd)&&!r.frozen||r.hidden||!0===s.master&&!e||(a=f.getColumnCellHTML(o),r&&r.frozen?t+=a:i+=a)}return t+='
 
',i+='
 
',[t+="",i+=""]}},getColumnCellHTML:function(e){var t=this.columns[e];if(null==t)return"";for(var i=!this.reorderColumns||this.columnGroups&&this.columnGroups.length?"":" w2ui-reorder-cols-head ",s="",n=0;n"+(!1!==t.resizable?'
':"")+'
'+(r||" ")+"
"},columnTooltipShow:function(e){var t,i,s;"normal"!=this.columnTooltip&&(t=$(this.box).find("#grid_"+this.name+"_column_"+e),i=this.columns[e],s=this.columnTooltip,t.prop("_mouse_over",!0),setTimeout(function(){!0===t.prop("_mouse_over")&&!0!==t.prop("_mouse_tooltip")&&(t.prop("_mouse_tooltip",!0),t.w2tag(i.tooltip,{position:s,top:5}))},1))},columnTooltipHide:function(e){var t;"normal"!=this.columnTooltip&&(t=$(this.box).find("#grid_"+this.name+"_column_"+e),this.columns[e],t.removeProp("_mouse_over"),setTimeout(function(){!0!==t.prop("_mouse_over")&&!0===t.prop("_mouse_tooltip")&&(t.removeProp("_mouse_tooltip"),t.w2tag())},1))},getRecordsHTML:function(){var e=this.records.length,t="object"!=typeof this.url?this.url:this.url.get;(e=0!=this.searchData.length&&!t?this.last.searchIds.length:e)>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start;var t=$("#grid_"+this.name+"_records"),i=Math.floor((t.height()||0)/this.recordHeight)+this.last.show_extra+1;(!this.fixedBody||e"+s[0],l=""+s[1];n+='',l+='';for(var o=0;o
',l+=' ',this.last.range_start=0,this.last.range_end=i,[n,l]},getSummaryHTML:function(){if(0!==this.summary.length){for(var e=this.getRecordHTML(-1,0),t=""+e[0],i="
"+e[1],s=0;s
",i+=""]}},scroll:function(e){(new Date).getTime();var n=this,t="object"!=typeof this.url?this.url:this.url.get,i=$("#grid_"+this.name+"_records"),s=$("#grid_"+this.name+"_frecords");e&&(p=e.target.scrollTop,h=e.target.scrollLeft,n.last.scrollTop=p,n.last.scrollLeft=h,$("#grid_"+n.name+"_columns")[0].scrollLeft=h,$("#grid_"+n.name+"_summary")[0].scrollLeft=h,s[0].scrollTop=p),this.last.bubbleEl&&($(this.last.bubbleEl).w2tag(),this.last.bubbleEl=null);var l=null,o=null;if(n.disableCVS||0n.last.scrollLeft&&null==l&&(l=u),d+a-30>n.last.scrollLeft+r&&null==o&&(o=u),d+=a);null==o&&(o=n.columns.length-1)}if(null!=l&&((l=l<0?0:l)==(o=o<0?0:o)&&(0n.last.colStart)for(u=n.last.colStart;u';null!=i&&(s=n.getCellHTML(parseInt(i),u,!1)),$(t).after(s)}),v.each(function(e,t){var i=$(t).parent().attr("index"),s='';null!=i&&(s=n.getCellHTML(parseInt(i),u,!0)),$(t).after(s)}));if(o>n.last.colEnd)for(u=n.last.colEnd+1;u<=o;u++)n.columns[u]&&(n.columns[u].frozen||n.columns[u].hidden)||(g.before(n.getColumnCellHTML(u)),w.each(function(e,t){var i=$(t).parent().attr("index"),s='';null!=i&&(s=n.getCellHTML(parseInt(i),u,!1)),$(t).before(s)}),y.each(function(e,t){var i=$(t).parent().attr("index")||-1,i=n.getCellHTML(parseInt(i),u,!0);$(t).before(i)}));n.last.colStart=l,n.last.colEnd=o,n.resizeRecords()}else{n.last.colStart=l,n.last.colEnd=o;var h=this.getColumnsHTML(),b=this.getRecordsHTML(),x=this.getSummaryHTML(),p=c.find("#grid_"+this.name+"_columns"),_=c.find("#grid_"+this.name+"_records"),k=c.find("#grid_"+this.name+"_frecords"),C=c.find("#grid_"+this.name+"_summary");p.find("tbody").html(h[1]),k.html(b[0]),_.prepend(b[1]),null!=x&&C.html(x[1]),setTimeout(function(){_.find("> table").not("table:first-child").remove(),C[0]&&(C[0].scrollLeft=n.last.scrollLeft)},1),n.resizeRecords()}}k=this.records.length;if(k>this.total&&-1!==this.total&&(k=this.total),0!==(k=0!=this.searchData.length&&!t?this.last.searchIds.length:k)&&0!==i.length&&0!==i.height()){k>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start;b=Math.round(i[0].scrollTop/this.recordHeight+1),x=b+(Math.round(i.height()/this.recordHeight)-1);if(kthis.total&&-1!=this.total&&(S=this.total);var O=i.find("#grid_"+this.name+"_rec_top"),z=i.find("#grid_"+this.name+"_rec_bottom"),D=s.find("#grid_"+this.name+"_frec_top"),I=s.find("#grid_"+this.name+"_frec_bottom");-1!=String(O.next().prop("id")).indexOf("_expanded_row")&&(O.next().remove(),D.next().remove()),this.total>S&&-1!=String(z.prev().prop("id")).indexOf("_expanded_row")&&(z.prev().remove(),I.prev().remove());x=parseInt(O.next().attr("line")),t=parseInt(z.prev().attr("line"));if(x=x-this.last.show_extra+2&&1S))break;E.remove(),R.remove()}"bottom"==(j=i.find("#grid_"+this.name+"_rec_top").next().attr("line"))&&(j=S);for(var R,F,u=parseInt(j)-1;T<=u;u--)this.records[u-1]&&((R=this.records[u-1].w2ui)&&!Array.isArray(R.children)&&(R.expanded=!1),F=this.getRecordHTML(u-1,u),O.after(F[1]),D.after(F[0]));A(),setTimeout(function(){n.refreshRanges()},0)}var x=(T-1)*n.recordHeight,j=(k-S)*this.recordHeight;j<0&&(j=0),O.css("height",x+"px"),D.css("height",x+"px"),z.css("height",j+"px"),I.css("height",j+"px"),n.last.range_start=T,n.last.range_end=S,k
'),n.last.pull_more=!0,n.last.xhr_offset+=n.limit,n.request("get")}).find("td").html(n.autoLoad?'
':'
'+w2utils.lang("Load")+" "+n.limit+" "+w2utils.lang("More")+"...
"))}}function A(){n.markSearch&&(clearTimeout(n.last.marker_timer),n.last.marker_timer=setTimeout(function(){for(var e=[],t=0;t',l+='',this.show.lineNumbers&&(n+=''),this.show.selectColumn&&(n+=''),this.show.expandColumn&&(n+=''),l+='',this.show.orderColumn&&(l+='');for(var a=0;a';(p=this.columns[a]).frozen&&!p.hidden?n+=r:p.hidden||athis.last.colEnd||(l+=r)}return n+='',l+='',[n+="",l+=""]}var d="object"!=typeof this.url?this.url:this.url.get;if(!0!==i)if(0=this.last.searchIds.length)return"";e=this.last.searchIds[e],s=this.records[e]}else{if(e>=this.records.length)return"";s=this.records[e]}else{if(e>=this.summary.length)return"";s=this.summary[e]}if(!s)return"";null!=s.recid||null==this.recid||null!=(u=this.parseField(s,this.recid))&&(s.recid=u);w2utils.escapeId(s.recid);d=!1;-1!=o.indexes.indexOf(e)&&(d=!0);var u=s.w2ui?s.w2ui.style:"";null!=u&&"string"==typeof u||(u="");o=s.w2ui?s.w2ui.class:"";null!=o&&"string"==typeof o||(o=""),n+='",l+='",this.show.lineNumbers&&(n+='"+(!0!==i?this.getLineHTML(t,s):"")+""),this.show.selectColumn&&(s&&s.w2ui&&s.w2ui.hideCheckBox,n+=''+(!0===i||s.w2ui&&!0===s.w2ui.hideCheckBox?"":'
')+""),this.show.expandColumn&&(d="",d=s.w2ui&&!0===s.w2ui.expanded?"-":"+",s.w2ui&&"none"==s.w2ui.expanded&&(d=""),s.w2ui&&"spinner"==s.w2ui.expanded&&(d='
'),n+=''+(!0!==i?'
"+d+"
":"")+""),l+='',this.show.orderColumn&&(l+=''+(!0!==i?'
 
':"")+"");for(var c=0,h=0;;){var p,f,g,m=1;if(null==(p=this.columns[c]))break;if(p.hidden)c++,0this.last.colEnd)||p.frozen){if(s.w2ui&&"object"==typeof s.w2ui.colspan){var w=parseInt(s.w2ui.colspan[p.field])||null;if(1=this.columns.length);a++)this.columns[a].hidden&&v++;m=w-v,h=w-1}}m=this.getCellHTML(e,c,i,m);p.frozen?n+=m:l+=m,c++}else c++}return n+='',l+='',[n+="",l+=""]},getLineHTML:function(e){return"
"+e+"
"},getCellHTML:function(i,s,e,t){var n=this,l=this.columns[s];if(null==l)return"";var o,a,r,d=(!0!==e?this.records:this.summary)[i],u=-1!==i?this.getCellValue(i,s,e):"",c=-1!==i?this.getCellEditable(i,s):"",h="max-height: "+parseInt(this.recordHeight)+"px;"+(l.clipboardCopy?"margin-right: 20px":""),p=!e&&d&&d.w2ui&&d.w2ui.changes&&null!=d.w2ui.changes[l.field],f="",g="",m=this.last.selection,w=!1,v="";if(-1!=m.indexes.indexOf(i)&&(w=!0),null==t&&(t=d&&d.w2ui&&d.w2ui.colspan&&d.w2ui.colspan[l.field]?d.w2ui.colspan[l.field]:1),0===s&&d&&d.w2ui&&Array.isArray(d.w2ui.children)){for(var y,b=0,x=this.get(d.w2ui.parent_recid,!0);null!=x;){if(b++,null==(y=this.records[x].w2ui)||null==y.parent_recid)break;x=this.get(y.parent_recid,!0)}if(d.w2ui.parent_recid)for(var _=0;_';v+='"}!0===l.info&&(l.info={}),null!=l.info&&(o="w2ui-icon-info","function"==typeof l.info.icon?o=l.info.icon(d):"object"==typeof l.info.icon?o=l.info.icon[this.parseField(d,l.field)]||"":"string"==typeof l.info.icon&&(o=l.info.icon),a=l.info.style||"","function"==typeof l.info.style?a=l.info.style(d):"object"==typeof l.info.style?a=l.info.style[this.parseField(d,l.field)]||"":"string"==typeof l.info.style&&(a=l.info.style),v+='"),null!=l.render&&-1!==i?("function"==typeof l.render&&(null!=(a=l.render.call(this,d,i,s,u))&&"object"==typeof a?(u=$.trim(a.html||""),g=a.class||"",f=a.style||""):u=$.trim(a),(u.length<4||"'+v+String(u)+"")),"object"==typeof l.render&&(u='
'+v+String(r)+"
"),"string"==typeof l.render&&(y=[],-1==(r=l.render.toLowerCase().indexOf(":"))?(y[0]=l.render.toLowerCase(),y[1]=""):(y[0]=l.render.toLowerCase().substr(0,r),y[1]=l.render.toLowerCase().substr(r+1)),r=w2utils.formatters[y[0]],u='
'+v+String(u)+"
")):(c&&-1!=["checkbox","check"].indexOf(c.type)&&(c=e?-(i+1):i,h+="text-align: center;",u='',v=""),u='
'+v+String(u)+"
"),null==u&&(u=""),"string"==typeof l.render&&(y=l.render.toLowerCase().split(":"),-1!=["number","int","float","money","currency","percent","size"].indexOf(y[0])&&(f+="text-align: right;")),d&&d.w2ui&&("object"==typeof d.w2ui.style&&("string"==typeof d.w2ui.style[s]&&(f+=d.w2ui.style[s]+";"),"string"==typeof d.w2ui.style[l.field]&&(f+=d.w2ui.style[l.field]+";")),"object"==typeof d.w2ui.class&&("string"==typeof d.w2ui.class[s]&&(g+=d.w2ui.class[s]+" "),"string"==typeof d.w2ui.class[l.field]&&(g+=d.w2ui.class[l.field]+" ")));h=!1;w&&-1!=$.inArray(s,m.columns[i])&&(h=!0);w="string"==typeof l.clipboardCopy?l.clipboardCopy:"Copy to clipboard",m="';return u='"+u+(""!=w2utils.stripTags(u)&&l.clipboardCopy&&w?m:"")+"",u=-1===i&&!0===e?'":u;function k(e){var t="";return n.show.recordTitles&&(null!=l.title?("function"==typeof l.title&&(t=l.title.call(n,d,i,s)),"string"==typeof l.title&&(t=l.title)):t=w2utils.stripTags(String(e).replace(/"/g,"''"))),null!=t?String(t):""}},clipboardCopy:function(e,t){var i=this.records[e],e=this.columns[t],t=e?this.parseField(i,e.field):"";"function"==typeof e.clipboardCopy&&(t=e.clipboardCopy(i)),$("#grid_"+this.name+"_focus").text(t).select(),document.execCommand("copy")},showBubble:function(e,t){var i="",s=this.columns[t].info,n=this.records[e],l=$(this.box).find("#grid_"+this.name+"_data_"+e+"_"+t+" .w2ui-info");if(this.last.bubbleEl&&$(this.last.bubbleEl).w2tag(),this.last.bubbleEl=l,null==s.fields){s.fields=[];for(var o=0;os.maxLength&&(c=c.substr(0,s.maxLength)+"..."),i+=""+a.text+""+((0===c?"0":c)||"")+"")):i+='
';i+=""}else if($.isPlainObject(r)){for(var d in i='',r){var u,c,h=r[d];""!=h&&"-"!=h&&"--"!=h&&"---"!=h?(u=String(h).split(":"),c=(a=null==(a=this.getColumn(u[0]))?{field:u[0],caption:u[0]}:a)?this.parseField(n,a.field):"",1")):i+=''}i+="
"+d+""+((c=null!=s.maxLength&&"string"==typeof c&&c.length>s.maxLength?c.substr(0,s.maxLength)+"...":c)||"")+"
"}$(l).w2tag($.extend({html:i,left:-4,position:"bottom|top",className:"w2ui-info-bubble",style:"",hideOnClick:!0},s.options||{}))},getCellEditable:function(e,t){var i=this.columns[t],s=this.records[e];if(!s||!i)return null;var n=s.w2ui?s.w2ui.editable:null;return!1===n?null:(null!=n&&!0!==n||"function"==typeof(n=i?i.editable:null)&&(i=this.getCellValue(e,t,!1),n=n.call(this,s,e,t,i)),n)},getCellValue:function(e,t,i){var t=this.columns[t],e=(!0!==i?this.records:this.summary)[e],s=this.parseField(e,t.field);return e&&e.w2ui&&e.w2ui.changes&&null!=e.w2ui.changes[t.field]&&(s=e.w2ui.changes[t.field]),$.isPlainObject(s)&&(t.options&&t.options.items?(val=t.options.items.find(function(e){return e.id==s.id}),s=val?val.text:s.id):null!=(s=null!=s.text?s.text:s).id&&(s=s.id)),s=null==s?"":s},getFooterHTML:function(){return'
'},status:function(e){var t,i;null!=e?$("#grid_"+this.name+"_footer").find(".w2ui-footer-left").html(e):(t="",0<(i=this.getSelection()).length&&(this.show.statusSelection&&1=this.columns.length)return null;var n=this.records[e].w2ui,l=(this.columns[t],this.columns[s]),n=n&&n.colspan&&!isNaN(n.colspan[l.field])?parseInt(n.colspan[l.field]):1;if(null==l)return null;if(l&&l.hidden||0===n)return this.nextCell(e,s,i);if(i){t=this.getCellEditable(e,t);if(null==t||-1!=["checkbox","check"].indexOf(t.type))return this.nextCell(e,s,i)}return s},prevCell:function(e,t,i){var s=t-1;if(s<0)return null;var n=this.records[e].w2ui,l=this.columns[s],n=n&&n.colspan&&!isNaN(n.colspan[l.field])?parseInt(n.colspan[l.field]):1;if(null==l)return null;if(l&&l.hidden||0===n)return this.prevCell(e,s,i);if(i){t=this.getCellEditable(e,t);if(null==t||-1!=["checkbox","check"].indexOf(t.type))return this.prevCell(e,s,i)}return s},nextRow:function(e,t){var i=this.last.searchIds,s=null;if(e+1this.records.length);)e++;var n=this.records[e].w2ui,l=this.columns[t],s=0===(n&&n.colspan&&null!=l&&!isNaN(n.colspan[l.field])?parseInt(n.colspan[l.field]):1)?this.nextRow(e,t):e}return s},prevRow:function(e,t){var i=this.last.searchIds,s=null;if(0i[0]){if(e--,0'+e+"",buttons:'",onOpen:function(e){setTimeout(function(){$(this.box).find(".w2ui-btn").focus()},25)},onClose:function(e){"function"==typeof t&&t()}}),w2utils.message.call(this,{box:this.box,path:"w2ui."+this.name,title:".w2ui-grid-header:visible",body:".w2ui-grid-box"},e)}},$.extend(w2grid.prototype,w2utils.event),w2obj.grid=w2grid}(jQuery),function(O){function a(e){this.box=null,this.name=null,this.panels=[],this.tmp={},this.padding=1,this.resizer=4,this.style="",O.extend(!0,this,w2obj.layout,e)}var z=["top","left","main","preview","right","bottom"];O.fn.w2layout=function(e){if(!O.isPlainObject(e)){var t=w2ui[O(this).attr("name")];return t?0"+t+""),l.status=!0,l;if(null==n)return console.log("ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css"),l.error=!0,l;if(null==t)return l;var o=this.trigger({phase:"before",type:"content",target:e,object:n,content:t,transition:i});if(!0===o.isCancelled)return l.cancelled=!0,l;if(t instanceof jQuery)return console.log("ERROR: You can not pass jQuery object to w2layout.content() method"),l;var a,r,d="#layout_"+this.name+"_panel_"+n.type,u=O(d+"> .w2ui-panel-content"),c=0;return 0 .w2ui-panel-content")).after('
'),r=O(d+"> .w2ui-panel-content.new-panel"),a.css("top",c),r.css("top",c),"object"==typeof t?(t.box=r[0],t.render()):r.html(t),w2utils.transition(a[0],r[0],i,function(){a.remove(),r.removeClass("new-panel"),r.css("overflow",n.overflow),O(d+"> .w2ui-panel-content").slice(1).remove(),s.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){s.resize()},100)}))),this.refresh(e),s.trigger(O.extend(o,{phase:"after"})),s.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){s.resize()},100),l},message:function(e,t){var i=this;"string"==typeof t&&(t={width:t.length<300?350:550,height:t.length<300?170:250,body:'
'+t+"
",buttons:'",onOpen:function(e){setTimeout(function(){O(this.box).find(".w2ui-btn").focus()},25)}});var s,n=this.get(e),l=O("#layout_"+this.name+"_panel_"+n.type).css("overflow");t&&(t.onClose&&(s=t.onClose),t.onClose=function(e){"function"==typeof s&&s(e),e.done(function(){O("#layout_"+i.name+"_panel_"+n.type).css("overflow",l)})}),O("#layout_"+this.name+"_panel_"+n.type).css("overflow","hidden"),w2utils.message.call(this,{box:O("#layout_"+this.name+"_panel_"+n.type),param:e,path:"w2ui."+this.name,title:".w2ui-panel-title:visible",body:".w2ui-panel-content"},t)},load:function(s,e,n,l){var o=this;return"css"==s?(O.get(e,function(e,t,i){o.html(s,i.responseText),l&&l()}),!0):null!=this.get(s)&&(O.get(e,function(e,t,i){o.html(s,i.responseText,n),l&&l(),o.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){o.resize()},100)}),!0)},sizeTo:function(e,t,i){var s=this;return null!=s.get(e)&&(O(s.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition",!0!==i?".2s":"0s")),setTimeout(function(){s.set(e,{size:t})},1),setTimeout(function(){O(s.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition","0s")),s.resize()},500),!0)},show:function(e,t){var i=this,s=this.trigger({phase:"before",type:"show",target:e,object:this.get(e),immediate:t});if(!0!==s.isCancelled){var n=i.get(e);return null==n?!1:(!(n.hidden=!1)===t?(O("#layout_"+i.name+"_panel_"+e).css({opacity:"1"}),i.trigger(O.extend(s,{phase:"after"})),i.resize()):(O("#layout_"+i.name+"_panel_"+e).css({opacity:"0"}),O(i.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition",".2s")),setTimeout(function(){i.resize()},1),setTimeout(function(){O("#layout_"+i.name+"_panel_"+e).css({opacity:"1"})},250),setTimeout(function(){O(i.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition","0s")),i.trigger(O.extend(s,{phase:"after"})),i.resize()},500)),!0)}},hide:function(e,t){var i=this,s=this.trigger({phase:"before",type:"hide",target:e,object:this.get(e),immediate:t});if(!0!==s.isCancelled){var n=i.get(e);return null==n?!1:((n.hidden=!0)===t?(O("#layout_"+i.name+"_panel_"+e).css({opacity:"0"}),i.trigger(O.extend(s,{phase:"after"})),i.resize()):(O(i.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition",".2s")),O("#layout_"+i.name+"_panel_"+e).css({opacity:"0"}),setTimeout(function(){i.resize()},1),setTimeout(function(){O(i.box).find(" > div > .w2ui-panel").css(w2utils.cssPrefix("transition","0s")),i.trigger(O.extend(s,{phase:"after"})),i.resize()},500)),!0)}},toggle:function(e,t){var i=this.get(e);return null!=i&&(i.hidden?this.show(e,t):this.hide(e,t))},set:function(e,t){var i=this.get(e,!0);return null!=i&&(O.extend(this.panels[i],t),null==t.content&&null==t.resizable||this.refresh(e),this.resize(),!0)},get:function(e,t){for(var i=0;i .w2ui-panel-content");return 1!=e.length?null:e[0]},hideToolbar:function(e){var t=this.get(e);t&&(t.show.toolbar=!1,O("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-toolbar").hide(),this.resize())},showToolbar:function(e){var t=this.get(e);t&&(t.show.toolbar=!0,O("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-toolbar").show(),this.resize())},toggleToolbar:function(e){var t=this.get(e);t&&(t.show.toolbar?this.hideToolbar(e):this.showToolbar(e))},assignToolbar:function(e,t){"string"==typeof t&&null!=w2ui[t]&&(t=w2ui[t]);var i=this.get(e);i.toolbar=t;var s=O(this.box).find(e+"> .w2ui-panel-toolbar");null!=i.toolbar?(0===s.find("[name="+i.toolbar.name+"]").length?s.w2render(i.toolbar):null!=i.toolbar&&i.toolbar.refresh(),(t.owner=this).showToolbar(e),this.refresh(e)):(s.html(""),this.hideToolbar(e))},hideTabs:function(e){var t=this.get(e);t&&(t.show.tabs=!1,O("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-tabs").hide(),this.resize())},showTabs:function(e){var t=this.get(e);t&&(t.show.tabs=!0,O("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-tabs").show(),this.resize())},toggleTabs:function(e){var t=this.get(e);t&&(t.show.tabs?this.hideTabs(e):this.showTabs(e))},render:function(e){var u=this,t=(new Date).getTime(),i=u.trigger({phase:"before",type:"render",target:u.name,box:e});if(!0!==i.isCancelled){if(null!=e&&(0"),0
';O(u.box).find(" > div").append(n)}return O(u.box).find(" > div").append('
'),u.refresh(),u.trigger(O.extend(i,{phase:"after"})),setTimeout(function(){u.tmp.events={resize:function(e){null==w2ui[u.name]?O(window).off("resize.w2ui-"+u.name):w2ui[u.name].resize()},resizeStart:l,mouseMove:a,mouseUp:o},O(window).on("resize.w2ui-"+u.name,u.tmp.events.resize),u.resize()},0),(new Date).getTime()-t}function l(e,t){if(u.box){t=t||window.event,O(document).off("mousemove",u.tmp.events.mouseMove).on("mousemove",u.tmp.events.mouseMove),O(document).off("mouseup",u.tmp.events.mouseUp).on("mouseup",u.tmp.events.mouseUp),u.tmp.resize={type:e,x:t.screenX,y:t.screenY,diff_x:0,diff_y:0,value:0};for(var i=0;it.width&&(l=t.minSize-t.width),t.maxSize&&t.width+l>t.maxSize&&(l=t.maxSize-t.width),a.minSize+l>a.width&&(l=a.width-a.minSize);break;case"right":t.minSize+l>t.width&&(l=t.width-t.minSize),t.maxSize&&t.width-l>t.maxSize&&(l=t.width-t.maxSize),a.minSize-l>a.width&&(l=a.minSize-a.width);break;case"top":t.minSize-o>t.height&&(o=t.minSize-t.height),t.maxSize&&t.height+o>t.maxSize&&(o=t.maxSize-t.height),a.minSize+o>a.height&&(o=a.height-a.minSize);break;case"preview":case"bottom":t.minSize+o>t.height&&(o=t.height-t.minSize),t.maxSize&&t.height-o>t.maxSize&&(o=t.height-t.maxSize),a.minSize-o>a.height&&(o=a.minSize-a.height)}switch(i.diff_x=l,i.diff_y=o,i.type){case"top":case"preview":case"bottom":(i.diff_x=0) .w2ui-panel-content")[0],setTimeout(function(){0 .w2ui-panel-content").length&&(O(l+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").css("overflow",n.overflow)[0].style.cssText+=";"+n.style),n.content&&"function"==typeof n.content.render&&n.content.render()},1)):0 .w2ui-panel-content").length&&(O(l+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").html(n.content).css("overflow",n.overflow)[0].style.cssText+=";"+n.style);e=O(t.box).find(l+"> .w2ui-panel-tabs");n.show.tabs?0===e.find("[name="+n.tabs.name+"]").length&&null!=n.tabs?e.w2render(n.tabs):n.tabs.refresh():e.html("").removeClass("w2ui-tabs").hide(),e=O(t.box).find(l+"> .w2ui-panel-toolbar"),n.show.toolbar?0===e.find("[name="+n.toolbar.name+"]").length&&null!=n.toolbar?e.w2render(n.toolbar):n.toolbar.refresh():e.html("").removeClass("w2ui-toolbar").hide(),e=O(t.box).find(l+"> .w2ui-panel-title"),n.title?e.html(n.title).show():e.html("").hide()}else{if(0===O("#layout_"+t.name+"_panel_main").length)return void t.render();t.resize();for(var o=0;o div").css({width:s+"px",height:n+"px"});for(var l,o,a,r,d,u,c=this,h=this.get("main"),p=this.get("preview"),f=this.get("left"),g=this.get("right"),m=this.get("top"),w=this.get("bottom"),v=null!=p&&!0!==p.hidden,y=null!=f&&!0!==f.hidden,b=null!=g&&!0!==g.hidden,x=null!=m&&!0!==m.hidden,_=null!=w&&!0!==w.hidden,k=0;kthis.padding?this.resizer:this.padding,O("#layout_"+this.name+"_resizer_top").show().css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){var t=c.trigger({phase:"before",type:"resizerClick",target:"top",originalEvent:e});if(!0!==t.isCancelled)return w2ui[c.name].tmp.events.resizeStart("top",e),c.trigger(O.extend(t,{phase:"after"})),!1}))):(O("#layout_"+this.name+"_panel_top").hide(),O("#layout_"+this.name+"_resizer_top").hide()),null!=f&&!0!==f.hidden?(o=(l=0)+(x?m.sizeCalculated+this.padding:0),a=f.sizeCalculated,r=n-(x?m.sizeCalculated+this.padding:0)-(_?w.sizeCalculated+this.padding:0),d=O("#layout_"+this.name+"_panel_left"),-1!=window.navigator.userAgent.indexOf("MSIE")&&0this.padding?this.resizer:this.padding,O("#layout_"+this.name+"_resizer_left").show().css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(e){var t=c.trigger({phase:"before",type:"resizerClick",target:"left",originalEvent:e});if(!0!==t.isCancelled)return w2ui[c.name].tmp.events.resizeStart("left",e),c.trigger(O.extend(t,{phase:"after"})),!1}))):(O("#layout_"+this.name+"_panel_left").hide(),O("#layout_"+this.name+"_resizer_left").hide()),null!=g&&!0!==g.hidden?(l=s-g.sizeCalculated,o=0+(x?m.sizeCalculated+this.padding:0),a=g.sizeCalculated,r=n-(x?m.sizeCalculated+this.padding:0)-(_?w.sizeCalculated+this.padding:0),O("#layout_"+this.name+"_panel_right").css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px"}).show(),g.width=a,g.height=r,g.resizable&&(l-=this.padding,a=this.resizer>this.padding?this.resizer:this.padding,O("#layout_"+this.name+"_resizer_right").show().css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(e){var t=c.trigger({phase:"before",type:"resizerClick",target:"right",originalEvent:e});if(!0!==t.isCancelled)return w2ui[c.name].tmp.events.resizeStart("right",e),c.trigger(O.extend(t,{phase:"after"})),!1}))):(O("#layout_"+this.name+"_panel_right").hide(),O("#layout_"+this.name+"_resizer_right").hide()),null!=w&&!0!==w.hidden?(l=0,o=n-w.sizeCalculated,a=s,r=w.sizeCalculated,O("#layout_"+this.name+"_panel_bottom").css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px"}).show(),w.width=a,w.height=r,w.resizable&&(o-=0===this.padding?0:this.padding,r=this.resizer>this.padding?this.resizer:this.padding,O("#layout_"+this.name+"_resizer_bottom").show().css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){var t=c.trigger({phase:"before",type:"resizerClick",target:"bottom",originalEvent:e});if(!0!==t.isCancelled)return w2ui[c.name].tmp.events.resizeStart("bottom",e),c.trigger(O.extend(t,{phase:"after"})),!1}))):(O("#layout_"+this.name+"_panel_bottom").hide(),O("#layout_"+this.name+"_resizer_bottom").hide()),l=0+(y?f.sizeCalculated+this.padding:0),o=0+(x?m.sizeCalculated+this.padding:0),a=s-(y?f.sizeCalculated+this.padding:0)-(b?g.sizeCalculated+this.padding:0),r=n-(x?m.sizeCalculated+this.padding:0)-(_?w.sizeCalculated+this.padding:0)-(v?p.sizeCalculated+this.padding:0),d=O("#layout_"+this.name+"_panel_main"),-1!=window.navigator.userAgent.indexOf("MSIE")&&0this.padding?this.resizer:this.padding,O("#layout_"+this.name+"_resizer_preview").show().css({display:"block",left:l+"px",top:o+"px",width:a+"px",height:r+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){var t=c.trigger({phase:"before",type:"resizerClick",target:"preview",originalEvent:e});if(!0!==t.isCancelled)return w2ui[c.name].tmp.events.resizeStart("preview",e),c.trigger(O.extend(t,{phase:"after"})),!1}))):(O("#layout_"+this.name+"_panel_preview").hide(),O("#layout_"+this.name+"_resizer_preview").hide());for(var C=0;C .w2ui-panel-",$=0;T&&(T.title&&($+=w2utils.getSize(O(S+"title").css({top:$+"px",display:"block"}),"height")),T.show.tabs&&(null!=T.tabs&&w2ui[this.name+"_"+z[C]+"_tabs"]&&w2ui[this.name+"_"+z[C]+"_tabs"].resize(),$+=w2utils.getSize(O(S+"tabs").css({top:$+"px",display:"block"}),"height")),T.show.toolbar&&(null!=T.toolbar&&w2ui[this.name+"_"+z[C]+"_toolbar"]&&w2ui[this.name+"_"+z[C]+"_toolbar"].resize(),$+=w2utils.getSize(O(S+"toolbar").css({top:$+"px",display:"block"}),"height"))),O(S+"content").css({display:"block"}).css({top:$+"px"})}return clearTimeout(this._resize_timer),this._resize_timer=setTimeout(function(){for(var e in w2ui){var t;"function"==typeof w2ui[e].resize&&(null==w2ui[e].panels&&w2ui[e].resize(),0<(t=O(w2ui[e].box).parents(".w2ui-layout")).length&&t.attr("name")==c.name&&w2ui[e].resize())}},100),this.trigger(O.extend(i,{phase:"after"})),(new Date).getTime()-e}},destroy:function(){var e=this.trigger({phase:"before",type:"destroy",target:this.name});if(!0!==e.isCancelled)return null!=w2ui[this.name]&&(0"+e+""),"object"==typeof t&&(i.buttons+='"),"string"==typeof t&&(i.buttons+=t)})),0===c("#w2ui-popup").length){if(!0===(n=this.trigger({phase:"before",type:"open",target:"popup",options:i,present:!1})).isCancelled)return;w2popup.status="opening",w2popup.lockScreen(i);var a="";i.showClose&&(a+='
Close
'),i.showMax&&(a+='
Max
');o='
';c("body").append(o);l=c("#w2ui-popup");0'+a+'
';c("#w2ui-popup").html(o),i.title&&c("#w2ui-popup .w2ui-popup-title").append(i.title),i.buttons&&c("#w2ui-popup .w2ui-popup-buttons").append(i.buttons),i.body&&c("#w2ui-popup .w2ui-popup-body").append(i.body),setTimeout(function(){c("#w2ui-popup").css(w2utils.cssPrefix({transition:i.speed+"s opacity, "+i.speed+"s -webkit-transform"})).removeClass("w2ui-popup-opening"),t.focus()},1),setTimeout(function(){c("#w2ui-popup").css(w2utils.cssPrefix("transform",""))},1e3*i.speed),w2popup.status="open",t.trigger(c.extend(n,{phase:"after"}))}else if(!0===i.multiple)w2popup.message(e);else{if(null==w2popup._prev&&null!=w2popup._template&&t.restoreTemplate(),!0===(n=this.trigger({phase:"before",type:"open",target:"popup",options:i,present:!0})).isCancelled)return;w2popup.status="opening",null!=s&&(s.maximized||s.width==i.width&&s.height==i.height||w2popup.resize(i.width,i.height),i.prevSize=i.width+"px:"+i.height+"px",i.maximized=s.maximized);s=c("#w2ui-popup .w2ui-box").clone();s.removeClass("w2ui-box").addClass("w2ui-box-temp").find(".w2ui-popup-body").empty().append(i.body),"string"==typeof i.body&&0Close':"")+(i.showMax?'
Max
':"")).append(i.title),c("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-title"),c("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","")):(c("#w2ui-popup .w2ui-popup-title").hide().html(""),c("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-title"),c("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","0px"));var r=c("#w2ui-popup .w2ui-box")[0],d=c("#w2ui-popup .w2ui-box-temp")[0];w2utils.transition(r,d,i.transition,function(){t.restoreTemplate(),c(r).remove(),c(d).removeClass("w2ui-box-temp").addClass("w2ui-box");var e=c(d).find(".w2ui-popup-body");1==e.length&&(e[0].style.cssText=i.style),c("#w2ui-popup").data("prev-size",null),t.focus()}),w2popup.status="open",t.trigger(c.extend(n,{phase:"after"}))}i._last_focus=c(":focus"),i.keyboard&&c(document).on("keydown",this.keydown);var u={resizing:!1,mvMove:function(e){if(1!=u.resizing)return;e=e||window.event;u.div_x=e.screenX-u.x,u.div_y=e.screenY-u.y;e=w2popup.trigger({phase:"before",type:"move",target:"popup",div_x:u.div_x,div_y:u.div_y});if(!0===e.isCancelled)return;c("#w2ui-popup").css(w2utils.cssPrefix({transition:"none",transform:"translate3d("+u.div_x+"px, "+u.div_y+"px, 0px)"})),w2popup.trigger(c.extend(e,{phase:"after"}))},mvStop:function(e){if(1!=u.resizing)return;e=e||window.event;w2popup.status="open",u.div_x=e.screenX-u.x,u.div_y=e.screenY-u.y,c("#w2ui-popup").css({left:u.pos_x+u.div_x+"px",top:u.pos_y+u.div_y+"px"}).css(w2utils.cssPrefix({transition:"none",transform:"translate3d(0px, 0px, 0px)"})),u.resizing=!1,c(document).off("mousemove",u.mvMove),c(document).off("mouseup",u.mvStop),u.isLocked||w2popup.unlock()}};return c("#w2ui-popup .w2ui-popup-title").on("mousedown",function(e){w2popup.get().maximized||function(e){e=e||window.event;w2popup.status="moving",u.resizing=!0,u.isLocked=1==c("#w2ui-popup > .w2ui-lock").length,u.x=e.screenX,u.y=e.screenY,u.pos_x=c("#w2ui-popup").position().left,u.pos_y=c("#w2ui-popup").position().top,u.isLocked||w2popup.lock({opacity:0});c(document).on("mousemove",u.mvMove),c(document).on("mouseup",u.mvStop),e.stopPropagation?e.stopPropagation():e.cancelBubble=!0;{if(!e.preventDefault)return;e.preventDefault()}}(e)}),this}setTimeout(function(){t.open.call(t,i)},100)},action:function(e,t){var i=this,s=c("#w2ui-popup").data("options");null!=t&&(i={parent:this,options:s=c("#w2ui-message"+t).data("options"),close:function(){w2popup.message({msgId:t})}});var n=s.actions[e],s=n;c.isPlainObject(n)&&n.onClick&&(s=n.onClick);n=this.trigger({phase:"before",target:e,msgId:t,type:"action",action:n,originalEvent:event});!0!==n.isCancelled&&("function"==typeof s&&s.call(i,event),this.trigger(c.extend(n,{phase:"after"})))},keydown:function(e){var t=c("#w2ui-popup").data("options");t&&!t.keyboard||!0!==(t=w2popup.trigger({phase:"before",type:"keydown",target:"popup",options:t,originalEvent:e})).isCancelled&&(27===e.keyCode&&(e.preventDefault(),0